tradeblocks-mcp 4.2.0 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -1
- package/dist/{chunk-YRD62LDE.js → chunk-35RVWZGT.js} +4 -1
- package/dist/{chunk-4UU7IT2A.js.map → chunk-35RVWZGT.js.map} +1 -1
- package/dist/{chunk-4UU7IT2A.js → chunk-ENXBPJ7Y.js} +148 -6
- package/dist/chunk-ENXBPJ7Y.js.map +1 -0
- package/dist/{chunk-62GCLMQA.js → chunk-TLX7IBCM.js} +3 -6
- package/dist/chunk-TLX7IBCM.js.map +1 -0
- package/dist/{daily-logs-store-PXB53WEK.js → daily-logs-store-FZRIGYUX.js} +2 -2
- package/dist/{daily-logs-store-65YHFJ5F.js → daily-logs-store-MEZ5S3BR.js} +2 -2
- package/dist/market/provenance/index.js +1 -4
- package/dist/market/provenance/index.js.map +1 -1
- package/dist/{sync-JL7OPLCT.js → sync-EW33QZPD.js} +3 -3
- package/dist/test-exports.js +320 -279
- package/dist/test-exports.js.map +1 -1
- package/dist/{trades-store-UGZ62A7N.js → trades-store-3TOLBL2W.js} +2 -2
- package/dist/{trades-store-MOFJHRC2.js → trades-store-PNLPRYRJ.js} +2 -2
- package/package.json +1 -1
- package/server/{chunk-7N6HBOAY.js → chunk-PDSUY2X2.js} +148 -6
- package/server/chunk-PDSUY2X2.js.map +1 -0
- package/server/{chunk-J4GWE6JR.js → chunk-YIWLVX7Z.js} +3 -6
- package/server/chunk-YIWLVX7Z.js.map +1 -0
- package/server/{daily-logs-store-YAXASQN4.js → daily-logs-store-LRVO7COL.js} +2 -2
- package/server/index.js +993 -801
- package/server/index.js.map +1 -1
- package/server/{sync-ZV3QEGMO.js → sync-2POG6KA6.js} +3 -3
- package/server/{trades-store-MF7YYLCH.js → trades-store-MXUZLSF5.js} +2 -2
- package/src/db/dataset-schemas.ts +97 -23
- package/src/tools/market-data.ts +327 -245
- package/src/tools/profile-analysis.ts +18 -4
- package/src/tools/reports/fields.ts +16 -11
- package/src/tools/reports/helpers.ts +6 -2
- package/src/tools/reports/predictive.ts +15 -4
- package/src/tools/shared/field-analysis.ts +57 -14
- package/src/tools/shared/filter-objective.ts +73 -0
- package/src/utils/trade-analysis-fields.ts +19 -4
- package/dist/chunk-62GCLMQA.js.map +0 -1
- package/dist/chunk-YRD62LDE.js.map +0 -1
- package/server/chunk-7N6HBOAY.js.map +0 -1
- package/server/chunk-J4GWE6JR.js.map +0 -1
- /package/dist/{daily-logs-store-65YHFJ5F.js.map → daily-logs-store-FZRIGYUX.js.map} +0 -0
- /package/dist/{daily-logs-store-PXB53WEK.js.map → daily-logs-store-MEZ5S3BR.js.map} +0 -0
- /package/dist/{sync-JL7OPLCT.js.map → sync-EW33QZPD.js.map} +0 -0
- /package/dist/{trades-store-MOFJHRC2.js.map → trades-store-3TOLBL2W.js.map} +0 -0
- /package/dist/{trades-store-UGZ62A7N.js.map → trades-store-PNLPRYRJ.js.map} +0 -0
- /package/server/{daily-logs-store-YAXASQN4.js.map → daily-logs-store-LRVO7COL.js.map} +0 -0
- /package/server/{sync-ZV3QEGMO.js.map → sync-2POG6KA6.js.map} +0 -0
- /package/server/{trades-store-MF7YYLCH.js.map → trades-store-MXUZLSF5.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/market/provenance/canonical-json.ts","../../../src/market/provenance/content-object-store.ts","../../../src/market/provenance/durable-directory.ts","../../../src/market/provenance/partition-commit-store.ts","../../../src/market/provenance/dataset-registry.ts","../../../src/market/provenance/partition-commit-attempt.ts","../../../src/market/provenance/xnys-calendar-data.ts","../../../src/market/provenance/xnys-session-calendar.ts","../../../src/market/stores/enriched-legacy-migration.ts","../../../src/db/market-datasets.ts","../../../src/db/data-root.ts","../../../src/db/parquet-writer.ts","../../../src/market/tickers/schemas.ts","../../../src/market/provenance/canonical-market-resolver.ts","../../../src/market/provenance/content-manifest.ts","../../../src/market/provenance/refresh-completion.ts","../../../src/utils/providers/thetadata/bulk-roots.ts","../../../src/db/json-adapters.ts","../../../../lib/calculations/walk-forward-analyzer.ts","../../../../lib/calculations/xnys-session-calendar.ts","../../../src/market/provenance/rate-slices.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\n\n/**\n * Canonical JSON version used by the market-data provenance object store.\n *\n * The version defines normalization and numeric semantics. Addresses remain\n * ordinary SHA-256 addresses of the exact encoded bytes.\n */\nexport const CANONICAL_JSON_VERSION = 1 as const;\n\nexport type Sha256Address = `sha256:${string}`;\nexport type CanonicalJsonAddress = Sha256Address;\n\nconst SHA256_ADDRESS_RE = /^sha256:([0-9a-f]{64})$/;\n\nfunction compareCodePoints(left: string, right: string): number {\n const leftPoints = Array.from(left, (char) => char.codePointAt(0) as number);\n const rightPoints = Array.from(right, (char) => char.codePointAt(0) as number);\n const length = Math.min(leftPoints.length, rightPoints.length);\n for (let i = 0; i < length; i++) {\n if (leftPoints[i] !== rightPoints[i]) return leftPoints[i] - rightPoints[i];\n }\n return leftPoints.length - rightPoints.length;\n}\n\nfunction encode(value: unknown, seen: WeakSet<object>): string {\n if (value === null) return \"null\";\n\n switch (typeof value) {\n case \"string\":\n return JSON.stringify(value.normalize(\"NFC\"));\n case \"boolean\":\n return value ? \"true\" : \"false\";\n case \"number\":\n if (!Number.isSafeInteger(value)) {\n throw new TypeError(\"Canonical JSON v1 supports only safe integers\");\n }\n // JSON.stringify already emits ECMAScript's shortest round-trippable\n // representation and normalizes negative zero to zero.\n return JSON.stringify(value);\n case \"undefined\":\n case \"function\":\n case \"symbol\":\n case \"bigint\":\n throw new TypeError(`Canonical JSON does not support ${typeof value}`);\n case \"object\":\n break;\n }\n\n const object = value as object;\n if (seen.has(object)) throw new TypeError(\"Canonical JSON does not support cyclic values\");\n seen.add(object);\n try {\n if (Array.isArray(value)) {\n const elements: string[] = [];\n for (let i = 0; i < value.length; i++) {\n if (!(i in value)) throw new TypeError(\"Canonical JSON does not support sparse arrays\");\n elements.push(encode(value[i], seen));\n }\n return `[${elements.join(\",\")}]`;\n }\n\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) {\n throw new TypeError(\"Canonical JSON accepts only plain objects and arrays\");\n }\n\n const normalizedKeys = new Map<string, string>();\n for (const sourceKey of Object.keys(value as Record<string, unknown>)) {\n const normalizedKey = sourceKey.normalize(\"NFC\");\n const collision = normalizedKeys.get(normalizedKey);\n if (collision !== undefined && collision !== sourceKey) {\n throw new TypeError(\n `Canonical JSON key collision after NFC normalization: ${JSON.stringify(collision)} and ${JSON.stringify(sourceKey)}`,\n );\n }\n normalizedKeys.set(normalizedKey, sourceKey);\n }\n const entries = [...normalizedKeys.entries()]\n .sort(([left], [right]) => compareCodePoints(left, right))\n .map(\n ([normalizedKey, sourceKey]) =>\n `${JSON.stringify(normalizedKey)}:${encode((value as Record<string, unknown>)[sourceKey], seen)}`,\n );\n return `{${entries.join(\",\")}}`;\n } finally {\n seen.delete(object);\n }\n}\n\n/** Encode a JSON value with stable recursive object-key ordering. */\nexport function canonicalJson(value: unknown): string {\n return encode(value, new WeakSet<object>());\n}\n\nexport function canonicalJsonBytes(value: unknown): Buffer {\n return Buffer.from(canonicalJson(value), \"utf8\");\n}\n\n/** Address the exact canonical JSON bytes. */\nexport function addressCanonicalJson(value: unknown): CanonicalJsonAddress {\n return addressBytes(canonicalJsonBytes(value));\n}\n\n/** Address exact binary bytes, such as a completed Parquet file. */\nexport function addressBytes(bytes: Uint8Array): Sha256Address {\n const digest = createHash(\"sha256\").update(bytes).digest(\"hex\");\n return `sha256:${digest}`;\n}\n\nexport function parseCanonicalJsonAddress(address: string): string {\n return parseSha256Address(address);\n}\n\nexport function parseSha256Address(address: string): string {\n const match = SHA256_ADDRESS_RE.exec(address);\n if (!match) throw new TypeError(`Invalid SHA-256 address: ${JSON.stringify(address)}`);\n return match[1];\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport {\n addressBytes,\n canonicalJsonBytes,\n parseCanonicalJsonAddress,\n type CanonicalJsonAddress,\n} from \"./canonical-json.ts\";\nimport { DurableDirectories, syncDirectory } from \"./durable-directory.ts\";\n\nexport interface PutContentObjectResult<T> {\n address: CanonicalJsonAddress;\n value: T;\n path: string;\n bytes: number;\n created: boolean;\n}\n\nexport class ContentObjectCollisionError extends Error {\n readonly address: CanonicalJsonAddress;\n readonly objectPath: string;\n\n constructor(address: CanonicalJsonAddress, objectPath: string) {\n super(`Content object collision or corruption at ${address} (${objectPath})`);\n this.name = \"ContentObjectCollisionError\";\n this.address = address;\n this.objectPath = objectPath;\n }\n}\n\nfunction deepFreeze<T>(value: T): T {\n if (value && typeof value === \"object\" && !Object.isFrozen(value)) {\n for (const child of Object.values(value as Record<string, unknown>)) deepFreeze(child);\n Object.freeze(value);\n }\n return value;\n}\n\n/**\n * Immutable canonical-JSON object store.\n *\n * Temp objects are created with `wx` and installed by a no-replace hard link;\n * an existing address is never replaced. Repeating an identical put is\n * idempotent, while different bytes at the same address are treated as\n * collision/corruption and fail closed.\n */\nexport class ContentObjectStore {\n readonly rootDir: string;\n private readonly directories = new DurableDirectories();\n\n constructor(rootDir: string) {\n this.rootDir = rootDir;\n }\n\n objectPath(address: CanonicalJsonAddress): string {\n const digest = parseCanonicalJsonAddress(address);\n return path.join(this.rootDir, \"objects\", \"sha256\", digest.slice(0, 2), `${digest}.json`);\n }\n\n private async syncExistingObject(objectPath: string): Promise<void> {\n const handle = await fs.open(objectPath, \"r\");\n try {\n await handle.sync();\n } finally {\n await handle.close();\n }\n await syncDirectory(path.dirname(objectPath));\n }\n\n async put<T>(value: T): Promise<PutContentObjectResult<T>> {\n // Encode once. Accessors and mutable input objects must not be able to make\n // an address computed by a second traversal disagree with published bytes.\n const bytes = canonicalJsonBytes(value);\n const address = addressBytes(bytes);\n const materialized = deepFreeze(JSON.parse(bytes.toString(\"utf8\")) as T);\n const objectPath = this.objectPath(address);\n const objectDir = path.dirname(objectPath);\n await this.directories.ensure(objectDir);\n const tempPath = path.join(objectDir, `.${path.basename(objectPath)}.tmp-${randomUUID()}`);\n\n let handle: fs.FileHandle | undefined;\n try {\n // Publish only after the full object is durable. link(2) is an atomic\n // no-replace operation: unlike rename(), it fails with EEXIST and can\n // never overwrite an immutable object installed by another writer.\n handle = await fs.open(tempPath, \"wx\", 0o444);\n await handle.writeFile(bytes);\n await handle.sync();\n await handle.close();\n handle = undefined;\n await fs.link(tempPath, objectPath);\n await syncDirectory(objectDir);\n await fs.unlink(tempPath);\n await syncDirectory(objectDir);\n return {\n address,\n value: materialized,\n path: objectPath,\n bytes: bytes.byteLength,\n created: true,\n };\n } catch (error) {\n await handle?.close();\n handle = undefined;\n await fs.unlink(tempPath).catch(() => undefined);\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n const existing = await fs.readFile(objectPath);\n if (!existing.equals(bytes)) throw new ContentObjectCollisionError(address, objectPath);\n // The EEXIST winner may have linked the inode but not yet completed its\n // durability barrier. An idempotent caller supplies that barrier before\n // reporting success.\n await this.syncExistingObject(objectPath);\n return {\n address,\n value: materialized,\n path: objectPath,\n bytes: bytes.byteLength,\n created: false,\n };\n } finally {\n await handle?.close();\n }\n }\n\n async get<T>(address: CanonicalJsonAddress): Promise<T> {\n const objectPath = this.objectPath(address);\n const bytes = await fs.readFile(objectPath);\n // Identity is established from the exact stored bytes before parsing. A\n // parse/reserialize cycle must never be allowed to bless changed bytes.\n const digestAddress = addressBytes(bytes);\n if (digestAddress !== address) throw new ContentObjectCollisionError(address, objectPath);\n const value = JSON.parse(bytes.toString(\"utf8\")) as T;\n if (!canonicalJsonBytes(value).equals(bytes)) {\n throw new ContentObjectCollisionError(address, objectPath);\n }\n return deepFreeze(value);\n }\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\n\n/** fsync a directory so entries created, linked, renamed or removed in it are durable. */\nexport async function syncDirectory(directory: string): Promise<void> {\n const handle = await fs.open(directory, \"r\");\n try {\n await handle.sync();\n } finally {\n await handle.close();\n }\n}\n\ntype DirectoryIdentity = string;\n\n/**\n * Device, inode and birth time name one directory generation. Without a birth\n * time a reused inode would look like the directory already synced, so a\n * filesystem that reports none yields no identity and the directory is never\n * treated as known.\n */\nfunction identityOf(stat: {\n dev: bigint;\n ino: bigint;\n birthtimeNs: bigint;\n}): DirectoryIdentity | undefined {\n if (stat.birthtimeNs === 0n) return undefined;\n return `${stat.dev}:${stat.ino}:${stat.birthtimeNs}`;\n}\n\nasync function syncDirectoryIdentity(directory: string): Promise<DirectoryIdentity | undefined> {\n const handle = await fs.open(directory, \"r\");\n try {\n const identity = identityOf(await handle.stat({ bigint: true }));\n await handle.sync();\n return identity;\n } finally {\n await handle.close();\n }\n}\n\nasync function currentIdentity(directory: string): Promise<DirectoryIdentity | undefined> {\n try {\n return identityOf(await fs.stat(directory, { bigint: true }));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return undefined;\n throw error;\n }\n}\n\n/**\n * Directories one store instance has made durable, keyed by path and pinned to\n * the directory inode that was synced.\n *\n * Invariant: when `ensure(directory)` resolves, `directory` exists, and it and\n * every ancestor up to `/` were each fsynced, with its entry fsynced in its\n * parent, after that ancestor's current inode was created. This instance\n * performs those syncs the first time it meets each directory: on creation, or\n * on first sight of a directory someone else created. A later call skips a\n * directory whose path still resolves to the same device, inode and birth time,\n * because a durable entry stays durable until it is removed or renamed.\n * Removing or recreating a directory gives the path a new identity, so it is\n * synced again, together with its parent entry. Where the filesystem reports\n * no birth time, no identity is recorded and every call syncs the directory\n * and its parent, as before this memo. The store never renames directories it\n * ensures; an external rename of an ancestor is outside this invariant.\n */\nexport class DurableDirectories {\n private readonly known = new Map<string, DirectoryIdentity>();\n\n async ensure(directory: string): Promise<void> {\n const known = this.known.get(directory);\n if (known !== undefined) {\n if ((await currentIdentity(directory)) === known) return;\n this.known.delete(directory);\n }\n\n const parent = path.dirname(directory);\n if (parent !== directory) await this.ensure(parent);\n try {\n await fs.mkdir(directory);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n }\n // Sync the directory before anything is published into it, and its parent\n // so its own entry is durable. A directory another writer just created may\n // not have finished either sync, so an existing directory gets both too.\n const identity = await syncDirectoryIdentity(directory);\n if (parent !== directory) await syncDirectory(parent);\n if (identity !== undefined) this.known.set(directory, identity);\n }\n}\n","import { createHash, randomUUID } from \"node:crypto\";\nimport type { DuckDBConnection } from \"@duckdb/node-api\";\nimport { constants, readFileSync } from \"node:fs\";\nimport * as fs from \"node:fs/promises\";\nimport { hostname } from \"node:os\";\nimport * as path from \"node:path\";\nimport {\n addressBytes,\n addressCanonicalJson,\n canonicalJsonBytes,\n parseCanonicalJsonAddress,\n parseSha256Address,\n type CanonicalJsonAddress,\n type Sha256Address,\n} from \"./canonical-json.ts\";\nimport { ContentObjectCollisionError, ContentObjectStore } from \"./content-object-store.ts\";\nimport { DurableDirectories, syncDirectory } from \"./durable-directory.ts\";\nimport {\n canonicalPartitionDataset,\n canonicalPartitionRelativePath,\n isRealMarketSessionDate,\n validatePartitionIdentity,\n} from \"./dataset-registry.ts\";\n\nexport const PARTITION_COMMIT_RECEIPT_KIND = \"tradeblocks.market-data.partition-commit\" as const;\nexport const PARTITION_COMMIT_RECEIPT_VERSION = 1 as const;\nexport const PARTITION_COMMIT_EVENT_KIND =\n \"tradeblocks.market-data.partition-commit-event\" as const;\nexport const PARTITION_COMMIT_EVENT_VERSION = 1 as const;\nexport const PARTITION_HEAD_KIND = \"tradeblocks.market-data.partition-head\" as const;\nexport const PARTITION_HEAD_VERSION = 1 as const;\n\nexport type PartitionCommitClassification = \"append\" | \"repair\";\n\nexport type LogicalCoverage =\n { kind: \"date-range\"; from: string; through: string } | { kind: \"empty\" };\n\nexport interface PartitionQualityCounts {\n inputRows: number;\n writtenRows: number;\n droppedRows: number;\n}\n\nexport interface ExactFileFingerprint {\n address: Sha256Address;\n bytes: number;\n rows: number;\n}\n\nexport interface PartitionIdentity {\n dataset: string;\n partition: Record<string, string>;\n}\n\nexport interface PartitionCommitReceiptV1 extends PartitionIdentity {\n kind: typeof PARTITION_COMMIT_RECEIPT_KIND;\n version: typeof PARTITION_COMMIT_RECEIPT_VERSION;\n schemaRevision: number;\n relativePath: string;\n coverage: LogicalCoverage;\n quality: PartitionQualityCounts;\n file: ExactFileFingerprint;\n classification: PartitionCommitClassification;\n parent?: CanonicalJsonAddress;\n}\n\nexport interface PartitionCommitEventV1 extends PartitionIdentity {\n kind: typeof PARTITION_COMMIT_EVENT_KIND;\n version: typeof PARTITION_COMMIT_EVENT_VERSION;\n receipt: CanonicalJsonAddress;\n previous?: CanonicalJsonAddress;\n}\n\nexport interface StoredPartitionCommit {\n address: CanonicalJsonAddress;\n receipt: PartitionCommitReceiptV1;\n created: boolean;\n}\n\nexport interface RecordPartitionCommitInput extends PartitionIdentity {\n schemaRevision: number;\n relativePath: string;\n coverage: LogicalCoverage;\n quality: PartitionQualityCounts;\n file: ExactFileFingerprint;\n}\n\nexport interface PublishPartitionFileInput extends RecordPartitionCommitInput {\n /** Completed sibling file that has not yet been installed. */\n preparedPath: string;\n /** Caller expectation; the store derives and verifies this from relativePath. */\n expectedTargetPath: string;\n}\n\n/**\n * Package-internal capability used only to bring validated historical\n * canonical-layout bytes under authority. It is deliberately a symbol so the\n * exported store does not expose a general string-named \"bless this file\"\n * operation. The migration caller must first validate its legacy source and\n * XNYS session; the store independently revalidates canonical schema,\n * partition identity, coverage, inode, and exact bytes.\n */\nexport const INTERNAL_HISTORICAL_PARTITION_ADOPTION = Symbol(\n \"tradeblocks.internal.historical-partition-adoption\",\n);\n\nexport interface PartitionCommitRecorder {\n publishFileCommit(input: PublishPartitionFileInput): Promise<StoredPartitionCommit>;\n readCommit(address: CanonicalJsonAddress): Promise<StoredPartitionCommit>;\n}\n\nexport interface FilePartitionCommitStoreOptions {\n /** A provably dead local claim is recoverable after this age. Defaults to 30 seconds. */\n staleLockMs?: number;\n /** Maximum time to wait for an earlier or ambiguous claim. Defaults to 5 seconds. */\n lockWaitMs?: number;\n}\n\ninterface PartitionLockOwner {\n kind: \"tradeblocks.market-data.partition-lock-owner\";\n version: 1;\n token: string;\n pid: number;\n hostname: string;\n bootId: string;\n createdAtMs: number;\n}\n\ninterface PartitionLockTicket {\n kind: \"tradeblocks.market-data.partition-lock-ticket\";\n version: 1;\n token: string;\n number: number;\n}\n\ninterface PartitionHeadV1 extends PartitionIdentity {\n kind: typeof PARTITION_HEAD_KIND;\n version: typeof PARTITION_HEAD_VERSION;\n receipt: CanonicalJsonAddress;\n event: CanonicalJsonAddress;\n}\n\ninterface AuthorityTip {\n eventAddress: CanonicalJsonAddress;\n commit: StoredPartitionCommit;\n}\n\ntype PartitionCommitTestFaultPoint =\n | \"after-claim-open\"\n | \"after-event-before-head\"\n | \"historical-after-snapshot\"\n | \"before-release-claim\";\nconst partitionCommitTestFaults = new WeakMap<\n FilePartitionCommitStore,\n (point: PartitionCommitTestFaultPoint) => void | Promise<void>\n>();\n\n/** @internal Test-only deterministic crash-boundary injection; not in the public barrel. */\nexport function setPartitionCommitTestFault(\n store: FilePartitionCommitStore,\n fault?: (point: PartitionCommitTestFaultPoint) => void | Promise<void>,\n): void {\n if (fault) partitionCommitTestFaults.set(store, fault);\n else partitionCommitTestFaults.delete(store);\n}\n\nfunction attachPartitionLockCleanupError(primary: unknown, cleanup: unknown): unknown {\n if (primary instanceof Error) {\n try {\n Object.defineProperty(primary, \"cleanupError\", {\n value: cleanup,\n enumerable: false,\n configurable: true,\n });\n return primary;\n } catch {\n // A frozen/custom Error cannot carry the attachment; preserve both\n // failures without discarding the operation error.\n }\n }\n return new AggregateError(\n [primary, cleanup],\n \"Partition operation failed and its lock claim could not be released\",\n { cause: primary },\n );\n}\n\nexport type PartitionInspection =\n | { status: \"absent\" }\n | { status: \"orphan\"; observed: Omit<ExactFileFingerprint, \"rows\"> }\n | { status: \"missing\"; receipt: StoredPartitionCommit }\n | {\n status: \"mismatch\";\n receipt: StoredPartitionCommit;\n observed: Omit<ExactFileFingerprint, \"rows\">;\n }\n | { status: \"match\"; receipt: StoredPartitionCommit };\n\n/** A canonical partition path does not name the regular file inode being verified. */\nexport class PartitionFileIntegrityError extends Error {\n readonly filePath: string;\n\n constructor(filePath: string, reason: string, cause?: unknown) {\n super(`Invalid partition file (${reason}): ${filePath}`, {\n ...(cause === undefined ? {} : { cause }),\n });\n this.name = \"PartitionFileIntegrityError\";\n this.filePath = filePath;\n }\n}\n\nconst TOKEN_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;\nconst CURRENT_HOSTNAME = hostname();\nconst CURRENT_BOOT_ID = (() => {\n try {\n const value = readFileSync(\"/proc/sys/kernel/random/boot_id\", \"utf8\").trim();\n return value.length > 0 ? value : \"unavailable\";\n } catch {\n return \"unavailable\";\n }\n})();\n\nfunction validateIdentity(identity: PartitionIdentity): void {\n validatePartitionIdentity(identity);\n}\n\nfunction canonicalRelativePath(identity: PartitionIdentity): string {\n return canonicalPartitionRelativePath(identity);\n}\n\nfunction validateRelativePath(relativePath: string): void {\n if (\n relativePath.length === 0 ||\n relativePath.includes(\"\\\\\") ||\n path.posix.isAbsolute(relativePath) ||\n relativePath.split(\"/\").some((part) => part === \"..\" || part === \".\" || part === \"\")\n ) {\n throw new TypeError(`Invalid provenance relative path: ${JSON.stringify(relativePath)}`);\n }\n}\n\nfunction validateRegistryPath(identity: PartitionIdentity, relativePath: string): void {\n validateRelativePath(relativePath);\n const expected = canonicalRelativePath(identity);\n if (relativePath !== expected) {\n throw new TypeError(\n `Provenance path does not match the registered partition: ${JSON.stringify({ expected, observed: relativePath })}`,\n );\n }\n}\n\nfunction validateFingerprint(file: ExactFileFingerprint): void {\n parseSha256Address(file.address);\n if (!Number.isSafeInteger(file.bytes) || file.bytes < 0) {\n throw new TypeError(`Invalid provenance byte count: ${file.bytes}`);\n }\n if (!Number.isSafeInteger(file.rows) || file.rows < 0) {\n throw new TypeError(`Invalid provenance row count: ${file.rows}`);\n }\n}\n\nfunction validateCoverage(coverage: LogicalCoverage, rows: number): void {\n if (coverage.kind === \"empty\") {\n if (rows !== 0) throw new TypeError(\"Non-empty partition cannot have empty logical coverage\");\n return;\n }\n if (!isRealMarketSessionDate(coverage.from) || !isRealMarketSessionDate(coverage.through)) {\n throw new TypeError(`Invalid logical date coverage: ${JSON.stringify(coverage)}`);\n }\n if (coverage.from > coverage.through) {\n throw new TypeError(`Logical coverage starts after it ends: ${JSON.stringify(coverage)}`);\n }\n if (rows === 0) throw new TypeError(\"Empty partition cannot have non-empty logical coverage\");\n}\n\nfunction validateQuality(quality: PartitionQualityCounts, file: ExactFileFingerprint): void {\n for (const [name, count] of Object.entries(quality)) {\n if (!Number.isSafeInteger(count) || count < 0) {\n throw new TypeError(`Invalid provenance ${name}: ${count}`);\n }\n }\n if (quality.writtenRows !== file.rows) {\n throw new TypeError(\n `Provenance writtenRows ${quality.writtenRows} does not match file rows ${file.rows}`,\n );\n }\n if (quality.inputRows !== quality.writtenRows + quality.droppedRows) {\n throw new TypeError(\"Provenance inputRows must equal writtenRows + droppedRows\");\n }\n}\n\nfunction validateInput(input: RecordPartitionCommitInput): void {\n validateIdentity(input);\n if (!Number.isSafeInteger(input.schemaRevision) || input.schemaRevision < 1) {\n throw new TypeError(`Invalid schema revision: ${input.schemaRevision}`);\n }\n validateRegistryPath(input, input.relativePath);\n validateFingerprint(input.file);\n validateCoverage(input.coverage, input.file.rows);\n validateQuality(input.quality, input.file);\n const date = input.partition[canonicalPartitionDataset(input.dataset)!.provenance.sessionKey];\n if (\n input.coverage.kind === \"date-range\" &&\n (input.coverage.from !== date || input.coverage.through !== date)\n ) {\n throw new TypeError(\n `Partition logical coverage must equal its registered date: ${JSON.stringify({ date, coverage: input.coverage })}`,\n );\n }\n}\n\nconst CANONICAL_PARQUET_SCHEMAS: Readonly<\n Record<string, readonly (readonly [name: string, type: string])[]>\n> = Object.freeze({\n spot: [\n [\"ticker\", \"VARCHAR\"],\n [\"date\", \"VARCHAR\"],\n [\"time\", \"VARCHAR\"],\n [\"open\", \"DOUBLE\"],\n [\"high\", \"DOUBLE\"],\n [\"low\", \"DOUBLE\"],\n [\"close\", \"DOUBLE\"],\n [\"bid\", \"DOUBLE\"],\n [\"ask\", \"DOUBLE\"],\n ],\n enriched: [\n [\"ticker\", \"VARCHAR\"],\n [\"date\", \"VARCHAR\"],\n [\"Prior_Close\", \"DOUBLE\"],\n [\"Gap_Pct\", \"DOUBLE\"],\n [\"ATR_Pct\", \"DOUBLE\"],\n [\"RSI_14\", \"DOUBLE\"],\n [\"Price_vs_EMA21_Pct\", \"DOUBLE\"],\n [\"Price_vs_SMA50_Pct\", \"DOUBLE\"],\n [\"Realized_Vol_5D\", \"DOUBLE\"],\n [\"Realized_Vol_20D\", \"DOUBLE\"],\n [\"Return_5D\", \"DOUBLE\"],\n [\"Return_20D\", \"DOUBLE\"],\n [\"Intraday_Range_Pct\", \"DOUBLE\"],\n [\"Intraday_Return_Pct\", \"DOUBLE\"],\n [\"Close_Position_In_Range\", \"DOUBLE\"],\n [\"Gap_Filled\", \"INTEGER\"],\n [\"Consecutive_Days\", \"INTEGER\"],\n [\"Prev_Return_Pct\", \"DOUBLE\"],\n [\"Prior_Range_vs_ATR\", \"DOUBLE\"],\n [\"High_Time\", \"DOUBLE\"],\n [\"Low_Time\", \"DOUBLE\"],\n [\"High_Before_Low\", \"INTEGER\"],\n [\"Reversal_Type\", \"INTEGER\"],\n [\"Opening_Drive_Strength\", \"DOUBLE\"],\n [\"Intraday_Realized_Vol\", \"DOUBLE\"],\n [\"Day_of_Week\", \"INTEGER\"],\n [\"Month\", \"INTEGER\"],\n [\"Is_Opex\", \"INTEGER\"],\n [\"ivr\", \"DOUBLE\"],\n [\"ivp\", \"DOUBLE\"],\n ],\n enriched_context: [\n [\"date\", \"VARCHAR\"],\n [\"Vol_Regime\", \"INTEGER\"],\n [\"Term_Structure_State\", \"INTEGER\"],\n [\"Trend_Direction\", \"VARCHAR\"],\n [\"VIX_Spike_Pct\", \"DOUBLE\"],\n [\"VIX_Gap_Pct\", \"DOUBLE\"],\n ],\n option_chain: [\n [\"underlying\", \"VARCHAR\"],\n [\"date\", \"VARCHAR\"],\n [\"ticker\", \"VARCHAR\"],\n [\"contract_type\", \"VARCHAR\"],\n [\"strike\", \"DOUBLE\"],\n [\"expiration\", \"VARCHAR\"],\n [\"dte\", \"INTEGER\"],\n [\"exercise_style\", \"VARCHAR\"],\n ],\n option_quote_minutes: [\n [\"underlying\", \"VARCHAR\"],\n [\"date\", \"VARCHAR\"],\n [\"ticker\", \"VARCHAR\"],\n [\"time\", \"VARCHAR\"],\n [\"bid\", \"DOUBLE\"],\n [\"ask\", \"DOUBLE\"],\n [\"mid\", \"DOUBLE\"],\n [\"last_updated_ns\", \"BIGINT\"],\n [\"source\", \"VARCHAR\"],\n [\"delta\", \"FLOAT\"],\n [\"gamma\", \"FLOAT\"],\n [\"theta\", \"FLOAT\"],\n [\"vega\", \"FLOAT\"],\n [\"iv\", \"FLOAT\"],\n [\"greeks_source\", \"VARCHAR\"],\n [\"greeks_revision\", \"INTEGER\"],\n [\"rate_type\", \"VARCHAR\"],\n [\"rate_value\", \"DOUBLE\"],\n [\"gamma_source\", \"VARCHAR\"],\n ],\n option_oi_daily: [\n [\"underlying\", \"VARCHAR\"],\n [\"date\", \"VARCHAR\"],\n [\"ticker\", \"VARCHAR\"],\n [\"expiration\", \"VARCHAR\"],\n [\"strike\", \"DOUBLE\"],\n [\"right\", \"VARCHAR\"],\n [\"open_interest\", \"BIGINT\"],\n [\"source\", \"VARCHAR\"],\n ],\n});\n\nfunction escapeSqlLiteral(value: string): string {\n return value.replaceAll(\"'\", \"''\");\n}\n\nfunction canonicalDuckDbType(value: unknown): string {\n const normalized = String(value).toUpperCase();\n return normalized === \"REAL\" ? \"FLOAT\" : normalized;\n}\n\n/**\n * @internal Single canonical Parquet schema declaration check. Every consumer\n * (adoption inspection, prepared-file gate inside a commit attempt) verifies\n * through this assertion so the expected schema exists in exactly one place.\n */\nexport async function assertCanonicalParquetSchema(\n conn: DuckDBConnection,\n filePath: string,\n dataset: string,\n): Promise<void> {\n const expectedSchema = CANONICAL_PARQUET_SCHEMAS[dataset];\n if (!expectedSchema) throw new TypeError(`No canonical Parquet schema for ${dataset}`);\n const source = `read_parquet('${escapeSqlLiteral(filePath)}', hive_partitioning=false)`;\n const described = await conn.runAndReadAll(`DESCRIBE SELECT * FROM ${source}`);\n const schema = described\n .getRows()\n .map((row) => [String(row[0]), canonicalDuckDbType(row[1])] as const);\n if (canonicalJsonBytes(schema).compare(canonicalJsonBytes(expectedSchema)) !== 0) {\n throw new Error(\n `Canonical Parquet schema does not match revision 1: ${JSON.stringify({ dataset, observed: schema, expected: expectedSchema })}`,\n );\n }\n}\n\nasync function inspectCanonicalParquet(\n conn: DuckDBConnection,\n filePath: string,\n identity: PartitionIdentity,\n): Promise<{ rows: number; coverage: LogicalCoverage }> {\n await assertCanonicalParquetSchema(conn, filePath, identity.dataset);\n const source = `read_parquet('${escapeSqlLiteral(filePath)}', hive_partitioning=false)`;\n const definition = canonicalPartitionDataset(identity.dataset) as NonNullable<\n ReturnType<typeof canonicalPartitionDataset>\n >;\n const sessionColumn = definition.provenance.sessionKey;\n const predicates = Object.entries(identity.partition)\n .map(\n ([key, value]) =>\n `COUNT(*) FILTER (WHERE \"${key}\" IS NULL OR CAST(\"${key}\" AS VARCHAR) <> '${escapeSqlLiteral(value)}')::BIGINT`,\n )\n .join(\", \");\n const inspected = await conn.runAndReadAll(\n `SELECT COUNT(*)::BIGINT,\n COUNT(\"${sessionColumn}\")::BIGINT,\n MIN(CAST(\"${sessionColumn}\" AS VARCHAR)),\n MAX(CAST(\"${sessionColumn}\" AS VARCHAR)),\n ${predicates}\n FROM ${source}`,\n );\n const row = inspected.getRows()[0];\n const rows = Number(row[0]);\n const coveredRows = Number(row[1]);\n if (!Number.isSafeInteger(rows) || rows <= 0 || coveredRows !== rows) {\n throw new Error(\"Existing canonical Parquet must contain non-null rows for its session\");\n }\n for (const mismatches of row.slice(4)) {\n if (Number(mismatches) !== 0) {\n throw new Error(\"Existing canonical Parquet rows disagree with the registered partition\");\n }\n }\n const from = String(row[2]);\n const through = String(row[3]);\n const expectedSession = identity.partition[sessionColumn];\n if (from !== expectedSession || through !== expectedSession) {\n throw new Error(\"Existing canonical Parquet coverage disagrees with its partition session\");\n }\n return { rows, coverage: { kind: \"date-range\", from, through } };\n}\n\nfunction validateReceipt(receipt: PartitionCommitReceiptV1, identity: PartitionIdentity): void {\n if (\n receipt.kind !== PARTITION_COMMIT_RECEIPT_KIND ||\n receipt.version !== PARTITION_COMMIT_RECEIPT_VERSION ||\n receipt.dataset !== identity.dataset ||\n addressCanonicalJson(receipt.partition) !== addressCanonicalJson(identity.partition)\n ) {\n throw new Error(\"Partition receipt does not match its identity\");\n }\n validateInput(receipt);\n if (receipt.classification !== \"append\" && receipt.classification !== \"repair\") {\n throw new Error(`Invalid partition receipt classification: ${String(receipt.classification)}`);\n }\n if (receipt.classification === \"append\" && receipt.parent !== undefined) {\n throw new Error(\"Append receipt must not have a parent\");\n }\n if (receipt.classification === \"repair\" && receipt.parent === undefined) {\n throw new Error(\"Repair receipt must have a parent\");\n }\n if (receipt.parent !== undefined) parseCanonicalJsonAddress(receipt.parent);\n}\n\nfunction identityAddress(identity: PartitionIdentity): CanonicalJsonAddress {\n return addressCanonicalJson({\n kind: \"tradeblocks.market-data.partition-identity\",\n version: 1,\n dataset: identity.dataset,\n partition: identity.partition,\n });\n}\n\ninterface OpenRegularFile {\n handle: fs.FileHandle;\n stat: Awaited<ReturnType<fs.FileHandle[\"stat\"]>>;\n}\n\nfunction sameInode(\n left: Awaited<ReturnType<fs.FileHandle[\"stat\"]>>,\n right: Awaited<ReturnType<fs.FileHandle[\"stat\"]>>,\n): boolean {\n return left.dev === right.dev && left.ino === right.ino;\n}\n\nasync function openRegularFileNoFollow(filePath: string): Promise<OpenRegularFile> {\n let handle: fs.FileHandle;\n try {\n handle = await fs.open(\n filePath,\n constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK,\n );\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ELOOP\") {\n throw new PartitionFileIntegrityError(filePath, \"symbolic links are not allowed\", error);\n }\n throw error;\n }\n try {\n const stat = await handle.stat();\n if (!stat.isFile()) {\n throw new PartitionFileIntegrityError(filePath, \"expected a regular file\");\n }\n if (stat.nlink !== 1) {\n throw new PartitionFileIntegrityError(filePath, \"expected an unshared regular file inode\");\n }\n return { handle, stat };\n } catch (error) {\n await handle.close();\n throw error;\n }\n}\n\nasync function exactOpenFileAddress(\n handle: fs.FileHandle,\n): Promise<Omit<ExactFileFingerprint, \"rows\">> {\n const hash = createHash(\"sha256\");\n let bytes = 0;\n const buffer = Buffer.allocUnsafe(1024 * 1024);\n while (true) {\n const read = await handle.read(buffer, 0, buffer.byteLength, bytes);\n if (read.bytesRead === 0) break;\n hash.update(buffer.subarray(0, read.bytesRead));\n bytes += read.bytesRead;\n }\n return { address: `sha256:${hash.digest(\"hex\")}`, bytes };\n}\n\nasync function requireNamedRegularInode(\n filePath: string,\n expected: Awaited<ReturnType<fs.FileHandle[\"stat\"]>>,\n): Promise<void> {\n let named: Awaited<ReturnType<typeof fs.lstat>>;\n try {\n named = await fs.lstat(filePath);\n } catch (error) {\n throw new PartitionFileIntegrityError(\n filePath,\n \"verified inode is no longer named here\",\n error,\n );\n }\n if (!named.isFile()) {\n throw new PartitionFileIntegrityError(filePath, \"canonical entry is not a regular file\");\n }\n if (named.nlink !== 1 || expected.nlink !== 1) {\n throw new PartitionFileIntegrityError(filePath, \"canonical inode has multiple hard links\");\n }\n if (!sameInode(expected, named)) {\n throw new PartitionFileIntegrityError(filePath, \"canonical entry changed during verification\");\n }\n}\n\nasync function exactFileAddress(filePath: string): Promise<Omit<ExactFileFingerprint, \"rows\">> {\n const opened = await openRegularFileNoFollow(filePath);\n try {\n const fingerprint = await exactOpenFileAddress(opened.handle);\n const after = await opened.handle.stat();\n if (!after.isFile() || after.nlink !== 1 || !sameInode(opened.stat, after)) {\n throw new PartitionFileIntegrityError(filePath, \"open inode changed during verification\");\n }\n await requireNamedRegularInode(filePath, opened.stat);\n return fingerprint;\n } finally {\n await opened.handle.close();\n }\n}\n\nasync function snapshotOpenFile(\n source: fs.FileHandle,\n snapshotPath: string,\n): Promise<Omit<ExactFileFingerprint, \"rows\">> {\n const snapshot = await fs.open(snapshotPath, \"wx\", 0o400);\n const hash = createHash(\"sha256\");\n let bytes = 0;\n const buffer = Buffer.allocUnsafe(1024 * 1024);\n try {\n while (true) {\n const read = await source.read(buffer, 0, buffer.byteLength, bytes);\n if (read.bytesRead === 0) break;\n hash.update(buffer.subarray(0, read.bytesRead));\n let written = 0;\n while (written < read.bytesRead) {\n const result = await snapshot.write(\n buffer,\n written,\n read.bytesRead - written,\n bytes + written,\n );\n if (result.bytesWritten === 0) throw new Error(\"Unable to write inspection snapshot\");\n written += result.bytesWritten;\n }\n bytes += read.bytesRead;\n }\n await snapshot.sync();\n } finally {\n await snapshot.close();\n }\n return { address: `sha256:${hash.digest(\"hex\")}`, bytes };\n}\n\nfunction sameCommitContent(\n previous: PartitionCommitReceiptV1,\n input: RecordPartitionCommitInput,\n): boolean {\n return (\n previous.schemaRevision === input.schemaRevision &&\n previous.relativePath === input.relativePath &&\n addressCanonicalJson(previous.coverage) === addressCanonicalJson(input.coverage) &&\n addressCanonicalJson(previous.quality) === addressCanonicalJson(input.quality) &&\n previous.file.address === input.file.address &&\n previous.file.bytes === input.file.bytes &&\n previous.file.rows === input.file.rows\n );\n}\n\nfunction captureIdentity(identity: PartitionIdentity): PartitionIdentity {\n const captured = JSON.parse(\n canonicalJsonBytes({ dataset: identity.dataset, partition: identity.partition }).toString(\n \"utf8\",\n ),\n ) as PartitionIdentity;\n validateIdentity(captured);\n return Object.freeze({ ...captured, partition: Object.freeze(captured.partition) });\n}\n\nfunction captureInput(input: RecordPartitionCommitInput): RecordPartitionCommitInput {\n const captured = JSON.parse(\n canonicalJsonBytes({\n dataset: input.dataset,\n partition: input.partition,\n schemaRevision: input.schemaRevision,\n relativePath: input.relativePath,\n coverage: input.coverage,\n quality: input.quality,\n file: input.file,\n }).toString(\"utf8\"),\n ) as RecordPartitionCommitInput;\n validateInput(captured);\n Object.freeze(captured.partition);\n Object.freeze(captured.coverage);\n Object.freeze(captured.quality);\n Object.freeze(captured.file);\n return Object.freeze(captured);\n}\n\n/**\n * Durable partition receipt store rooted at the canonical market directory.\n * Data targets are derived from the registered identity and receipt path;\n * callers cannot redirect inspection or publication to arbitrary files.\n */\nexport class FilePartitionCommitStore implements PartitionCommitRecorder {\n readonly marketRootDir: string;\n readonly objects: ContentObjectStore;\n readonly provenanceRootDir: string;\n private readonly staleLockMs: number;\n private readonly lockWaitMs: number;\n private readonly directories = new DurableDirectories();\n\n constructor(marketRootDir: string, options: FilePartitionCommitStoreOptions = {}) {\n this.marketRootDir = marketRootDir;\n this.provenanceRootDir = path.join(marketRootDir, \".provenance\");\n this.objects = new ContentObjectStore(this.provenanceRootDir);\n this.staleLockMs = options.staleLockMs ?? 30_000;\n this.lockWaitMs = options.lockWaitMs ?? 5_000;\n }\n\n private identityDigest(identity: PartitionIdentity): string {\n return parseCanonicalJsonAddress(identityAddress(identity));\n }\n\n private headPath(identity: PartitionIdentity): string {\n const digest = this.identityDigest(identity);\n return path.join(this.provenanceRootDir, \"heads\", digest.slice(0, 2), `${digest}.json`);\n }\n\n private eventIndexDir(identity: PartitionIdentity): string {\n const digest = this.identityDigest(identity);\n return path.join(this.provenanceRootDir, \"events\", digest.slice(0, 2), digest);\n }\n\n private lockRoot(identity: PartitionIdentity): string {\n const digest = this.identityDigest(identity);\n return path.join(this.provenanceRootDir, \"locks\", digest.slice(0, 2), digest);\n }\n\n private targetPath(relativePath: string): string {\n validateRelativePath(relativePath);\n return path.join(this.marketRootDir, ...relativePath.split(\"/\"));\n }\n\n private async validateMarketRoot(): Promise<string> {\n const root = path.resolve(this.marketRootDir);\n const rootStat = await fs.lstat(root);\n if (!rootStat.isDirectory() || rootStat.isSymbolicLink()) {\n throw new PartitionFileIntegrityError(root, \"market root must be a real directory\");\n }\n return fs.realpath(root);\n }\n\n private async validatedTargetPath(\n relativePath: string,\n expectedRealRoot: string,\n ): Promise<string> {\n validateRelativePath(relativePath);\n const root = path.resolve(this.marketRootDir);\n const realRoot = await this.validateMarketRoot();\n if (realRoot !== expectedRealRoot) {\n throw new PartitionFileIntegrityError(root, \"market root changed during publication\");\n }\n const components = relativePath.split(\"/\");\n let current = root;\n for (const component of components.slice(0, -1)) {\n current = path.join(current, component);\n const stat = await fs.lstat(current);\n if (!stat.isDirectory() || stat.isSymbolicLink()) {\n throw new PartitionFileIntegrityError(\n current,\n \"target path components must be real directories\",\n );\n }\n }\n const realParent = await fs.realpath(current);\n const containment = path.relative(realRoot, realParent);\n if (\n containment === \"..\" ||\n containment.startsWith(`..${path.sep}`) ||\n path.isAbsolute(containment)\n ) {\n throw new PartitionFileIntegrityError(\n current,\n \"target parent escapes the configured market root\",\n );\n }\n return path.join(current, components.at(-1) as string);\n }\n\n private async quarantineClaim(claimedPath: string): Promise<void> {\n try {\n await fs.lstat(claimedPath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return;\n throw error;\n }\n const quarantineDir = path.join(this.provenanceRootDir, \"rejected-prepared\");\n await this.directories.ensure(quarantineDir);\n const quarantinePath = path.join(quarantineDir, randomUUID());\n await fs.rename(claimedPath, quarantinePath);\n await syncDirectory(path.dirname(claimedPath));\n await syncDirectory(quarantineDir);\n }\n\n private async restoreOrQuarantineClaim(claimedPath: string, preparedPath: string): Promise<void> {\n let restored = false;\n let claimedRemoved = false;\n try {\n // link(2) is no-replace at the destination and preserves a symlink as a\n // symlink. It safely restores regular files, hard links, and symlinks;\n // directories fall through to quarantine without recursive deletion.\n await fs.link(claimedPath, preparedPath);\n restored = true;\n await fs.unlink(claimedPath);\n claimedRemoved = true;\n await syncDirectory(path.dirname(preparedPath));\n return;\n } catch (error) {\n if (claimedRemoved) throw error;\n if (restored) await fs.unlink(preparedPath).catch(() => undefined);\n await this.quarantineClaim(claimedPath);\n }\n }\n\n private isProcessAlive(pid: number): boolean {\n if (!Number.isSafeInteger(pid) || pid <= 0) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return (error as NodeJS.ErrnoException).code === \"EPERM\";\n }\n }\n\n private async readCanonicalFile<T>(filePath: string): Promise<T | null> {\n try {\n const bytes = await fs.readFile(filePath);\n const value = JSON.parse(bytes.toString(\"utf8\")) as T;\n if (!canonicalJsonBytes(value).equals(bytes)) return null;\n return value;\n } catch {\n return null;\n }\n }\n\n private validOwner(owner: PartitionLockOwner | null, token: string): owner is PartitionLockOwner {\n return Boolean(\n owner &&\n owner.kind === \"tradeblocks.market-data.partition-lock-owner\" &&\n owner.version === 1 &&\n owner.token === token &&\n TOKEN_RE.test(owner.token) &&\n Number.isSafeInteger(owner.pid) &&\n owner.pid > 0 &&\n typeof owner.hostname === \"string\" &&\n owner.hostname.length > 0 &&\n typeof owner.bootId === \"string\" &&\n owner.bootId.length > 0 &&\n Number.isSafeInteger(owner.createdAtMs) &&\n owner.createdAtMs >= 0,\n );\n }\n\n private validTicket(\n ticket: PartitionLockTicket | null,\n token: string,\n ): ticket is PartitionLockTicket {\n return Boolean(\n ticket &&\n ticket.kind === \"tradeblocks.market-data.partition-lock-ticket\" &&\n ticket.version === 1 &&\n ticket.token === token &&\n Number.isSafeInteger(ticket.number) &&\n ticket.number >= 1,\n );\n }\n\n private ownerProvablyDead(owner: PartitionLockOwner): boolean {\n // A different host is intrinsically ambiguous; never steal it. A different\n // boot generation on this host is conclusive evidence that the process is\n // gone. Otherwise use the local PID liveness probe.\n if (owner.hostname !== CURRENT_HOSTNAME) return false;\n if (\n owner.bootId !== \"unavailable\" &&\n CURRENT_BOOT_ID !== \"unavailable\" &&\n owner.bootId !== CURRENT_BOOT_ID\n ) {\n return true;\n }\n return !this.isProcessAlive(owner.pid);\n }\n\n private async recoverClaim(claimsDir: string, token: string): Promise<boolean> {\n if (!TOKEN_RE.test(token)) return false;\n const claimPath = path.join(claimsDir, token);\n let claimStat: Awaited<ReturnType<typeof fs.stat>>;\n try {\n claimStat = await fs.stat(claimPath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return true;\n throw error;\n }\n const owner = await this.readCanonicalFile<PartitionLockOwner>(\n path.join(claimPath, \"owner.json\"),\n );\n const validOwner = this.validOwner(owner, token);\n // A malformed owner is ambiguous, even when old. Only a complete claim\n // with conclusive same-host generation/process evidence is recoverable.\n if (!validOwner) return false;\n const createdAtMs = owner.createdAtMs;\n if (Date.now() - createdAtMs < this.staleLockMs) return false;\n if (!this.ownerProvablyDead(owner)) return false;\n\n // Claim paths are unique generations and never reused. Recovery therefore\n // moves only the exact observed token path, never a constant path that a\n // replacement owner could have acquired (the usual stale-lock ABA race).\n const quarantineDir = path.join(path.dirname(claimsDir), \"quarantine\");\n await this.directories.ensure(quarantineDir);\n const quarantinePath = path.join(\n quarantineDir,\n `${token}-${claimStat.ino}-${Math.floor(claimStat.birthtimeMs)}`,\n );\n try {\n await fs.rename(claimPath, quarantinePath);\n await syncDirectory(claimsDir);\n await syncDirectory(quarantineDir);\n return true;\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\" || code === \"EEXIST\" || code === \"ENOTEMPTY\") return false;\n throw error;\n }\n }\n\n private async publishClaim(claimsDir: string, token: string): Promise<string> {\n const owner: PartitionLockOwner = {\n kind: \"tradeblocks.market-data.partition-lock-owner\",\n version: 1,\n token,\n pid: process.pid,\n hostname: CURRENT_HOSTNAME,\n bootId: CURRENT_BOOT_ID,\n createdAtMs: Date.now(),\n };\n const publishingPath = path.join(claimsDir, `.publishing-${token}`);\n const claimPath = path.join(claimsDir, token);\n await fs.mkdir(publishingPath);\n try {\n const ownerHandle = await fs.open(path.join(publishingPath, \"owner.json\"), \"wx\", 0o444);\n try {\n await ownerHandle.writeFile(canonicalJsonBytes(owner));\n await ownerHandle.sync();\n } finally {\n await ownerHandle.close();\n }\n await syncDirectory(publishingPath);\n await fs.rename(publishingPath, claimPath);\n await syncDirectory(claimsDir);\n return claimPath;\n } catch (error) {\n await fs.rm(publishingPath, { recursive: true, force: true });\n throw error;\n }\n }\n\n private async assignTicket(claimsDir: string, claimPath: string, token: string): Promise<number> {\n let maximum = 0;\n for (const entry of await fs.readdir(claimsDir, { withFileTypes: true })) {\n if (!entry.isDirectory() || !TOKEN_RE.test(entry.name)) continue;\n const ticket = await this.readCanonicalFile<PartitionLockTicket>(\n path.join(claimsDir, entry.name, \"ticket.json\"),\n );\n if (this.validTicket(ticket, entry.name)) maximum = Math.max(maximum, ticket.number);\n }\n if (!Number.isSafeInteger(maximum + 1)) throw new Error(\"Partition lock ticket overflow\");\n const ticket: PartitionLockTicket = {\n kind: \"tradeblocks.market-data.partition-lock-ticket\",\n version: 1,\n token,\n number: maximum + 1,\n };\n const handle = await fs.open(path.join(claimPath, \"ticket.json\"), \"wx\", 0o444);\n try {\n await handle.writeFile(canonicalJsonBytes(ticket));\n await handle.sync();\n } finally {\n await handle.close();\n }\n await syncDirectory(claimPath);\n return ticket.number;\n }\n\n private async releaseClaim(claimsDir: string, claimPath: string, token: string): Promise<void> {\n await partitionCommitTestFaults.get(this)?.(\"before-release-claim\");\n const owner = await this.readCanonicalFile<PartitionLockOwner>(\n path.join(claimPath, \"owner.json\"),\n );\n if (!this.validOwner(owner, token) || owner.pid !== process.pid) {\n throw new Error(\n `Refusing to release a partition claim owned by another writer: ${claimPath}`,\n );\n }\n const releasedDir = path.join(path.dirname(claimsDir), \"released\");\n await this.directories.ensure(releasedDir);\n const releasedPath = path.join(releasedDir, token);\n await fs.rename(claimPath, releasedPath);\n await syncDirectory(claimsDir);\n await syncDirectory(releasedDir);\n await fs.rm(releasedPath, { recursive: true });\n await syncDirectory(releasedDir);\n }\n\n private async withPartitionLock<T>(\n identity: PartitionIdentity,\n operation: () => Promise<T>,\n ): Promise<T> {\n validateIdentity(identity);\n const lockRoot = this.lockRoot(identity);\n const claimsDir = path.join(lockRoot, \"claims\");\n await this.directories.ensure(claimsDir);\n const token = randomUUID();\n const claimPath = await this.publishClaim(claimsDir, token);\n let ownTicket: number;\n try {\n ownTicket = await this.assignTicket(claimsDir, claimPath, token);\n } catch (error) {\n try {\n await this.releaseClaim(claimsDir, claimPath, token);\n } catch (cleanupError) {\n throw attachPartitionLockCleanupError(error, cleanupError);\n }\n throw error;\n }\n const deadline = Date.now() + this.lockWaitMs;\n let acquired = false;\n\n let operationFailed = false;\n let operationError: unknown;\n try {\n while (Date.now() <= deadline) {\n let blocked = false;\n const entries = await fs.readdir(claimsDir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory() || entry.name === token) continue;\n if (!TOKEN_RE.test(entry.name)) {\n if (!entry.name.startsWith(\".publishing-\")) blocked = true;\n continue;\n }\n const otherPath = path.join(claimsDir, entry.name);\n const owner = await this.readCanonicalFile<PartitionLockOwner>(\n path.join(otherPath, \"owner.json\"),\n );\n if (!this.validOwner(owner, entry.name)) {\n blocked = true;\n continue;\n }\n const ticket = await this.readCanonicalFile<PartitionLockTicket>(\n path.join(otherPath, \"ticket.json\"),\n );\n if (!this.validTicket(ticket, entry.name)) {\n // A missing ticket is a valid interrupted-intent state and may be\n // recovered only with a valid, provably dead owner. Malformed\n // ticket bytes are ambiguous and permanently fail closed.\n try {\n await fs.stat(path.join(otherPath, \"ticket.json\"));\n blocked = true;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n if (!(await this.recoverClaim(claimsDir, entry.name))) blocked = true;\n }\n continue;\n }\n if (ticket.number < ownTicket || (ticket.number === ownTicket && entry.name < token)) {\n if (!(await this.recoverClaim(claimsDir, entry.name))) blocked = true;\n }\n }\n if (!blocked) {\n acquired = true;\n break;\n }\n await new Promise((resolve) => setTimeout(resolve, 10));\n }\n if (!acquired) throw new Error(`Timed out acquiring partition lock: ${lockRoot}`);\n return await operation();\n } catch (error) {\n operationFailed = true;\n operationError = error;\n throw error;\n } finally {\n try {\n await this.releaseClaim(claimsDir, claimPath, token);\n } catch (cleanupError) {\n if (operationFailed) {\n throw attachPartitionLockCleanupError(operationError, cleanupError);\n }\n throw cleanupError;\n }\n }\n }\n\n private async readIndexedEvent(\n identity: PartitionIdentity,\n eventPath: string,\n address: CanonicalJsonAddress,\n ): Promise<{ event: PartitionCommitEventV1; commit: StoredPartitionCommit }> {\n const bytes = await fs.readFile(eventPath);\n if (addressBytes(bytes) !== address) {\n throw new ContentObjectCollisionError(address, eventPath);\n }\n const event = JSON.parse(bytes.toString(\"utf8\")) as PartitionCommitEventV1;\n if (!canonicalJsonBytes(event).equals(bytes)) {\n throw new ContentObjectCollisionError(address, eventPath);\n }\n if (\n event.kind !== PARTITION_COMMIT_EVENT_KIND ||\n event.version !== PARTITION_COMMIT_EVENT_VERSION ||\n event.dataset !== identity.dataset ||\n addressCanonicalJson(event.partition) !== addressCanonicalJson(identity.partition)\n ) {\n throw new Error(`Invalid partition commit event at ${eventPath}`);\n }\n parseCanonicalJsonAddress(event.receipt);\n if (event.previous !== undefined) parseCanonicalJsonAddress(event.previous);\n const commit = await this.readCommit(event.receipt);\n validateReceipt(commit.receipt, identity);\n return { event, commit };\n }\n\n private async readAuthorityTip(identity: PartitionIdentity): Promise<AuthorityTip | null> {\n const indexDir = this.eventIndexDir(identity);\n let entries: string[];\n try {\n entries = await fs.readdir(indexDir);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw error;\n }\n const events = new Map<\n CanonicalJsonAddress,\n { event: PartitionCommitEventV1; commit: StoredPartitionCommit }\n >();\n for (const entry of entries) {\n const match = /^([0-9a-f]{64})\\.json$/.exec(entry);\n if (!match) throw new Error(`Unexpected partition event index entry: ${entry}`);\n const address = `sha256:${match[1]}` as CanonicalJsonAddress;\n events.set(\n address,\n await this.readIndexedEvent(identity, path.join(indexDir, entry), address),\n );\n }\n if (events.size === 0) return null;\n\n const roots = [...events.entries()].filter(([, value]) => value.event.previous === undefined);\n if (roots.length !== 1) throw new Error(\"Partition event authority must have exactly one root\");\n let [currentAddress, current] = roots[0];\n if (current.commit.receipt.classification !== \"append\") {\n throw new Error(\"Partition event root must reference an append receipt\");\n }\n const visited = new Set<CanonicalJsonAddress>();\n while (true) {\n if (visited.has(currentAddress))\n throw new Error(\"Partition event authority contains a cycle\");\n visited.add(currentAddress);\n const children = [...events.entries()].filter(\n ([, value]) => value.event.previous === currentAddress,\n );\n if (children.length === 0) break;\n if (children.length !== 1)\n throw new Error(\"Partition event authority contains ambiguous tips\");\n const [childAddress, child] = children[0];\n if (\n child.commit.receipt.classification !== \"repair\" ||\n child.commit.receipt.parent !== current.commit.address\n ) {\n throw new Error(\"Partition event authority receipt ancestry is inconsistent\");\n }\n currentAddress = childAddress;\n current = child;\n }\n if (visited.size !== events.size) {\n throw new Error(\"Partition event authority contains a disconnected or missing-parent event\");\n }\n return { eventAddress: currentAddress, commit: current.commit };\n }\n\n private async readProjectedHead(identity: PartitionIdentity): Promise<PartitionHeadV1 | null> {\n const headPath = this.headPath(identity);\n let bytes: Buffer;\n try {\n bytes = await fs.readFile(headPath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw error;\n }\n\n try {\n const head = JSON.parse(bytes.toString(\"utf8\")) as PartitionHeadV1;\n if (!canonicalJsonBytes(head).equals(bytes)) return null;\n if (\n head.kind !== PARTITION_HEAD_KIND ||\n head.version !== PARTITION_HEAD_VERSION ||\n head.dataset !== identity.dataset ||\n addressCanonicalJson(head.partition) !== addressCanonicalJson(identity.partition)\n ) {\n return null;\n }\n parseCanonicalJsonAddress(head.receipt);\n parseCanonicalJsonAddress(head.event);\n return head;\n } catch {\n return null;\n }\n }\n\n private async writeHead(identity: PartitionIdentity, tip: AuthorityTip): Promise<void> {\n const headPath = this.headPath(identity);\n await this.directories.ensure(path.dirname(headPath));\n const tempPath = `${headPath}.tmp-${randomUUID()}`;\n const head: PartitionHeadV1 = {\n kind: PARTITION_HEAD_KIND,\n version: PARTITION_HEAD_VERSION,\n dataset: identity.dataset,\n partition: identity.partition,\n receipt: tip.commit.address,\n event: tip.eventAddress,\n };\n let handle: fs.FileHandle | undefined;\n try {\n handle = await fs.open(tempPath, \"wx\", 0o644);\n await handle.writeFile(canonicalJsonBytes(head));\n await handle.sync();\n await handle.close();\n handle = undefined;\n await fs.rename(tempPath, headPath);\n await syncDirectory(path.dirname(headPath));\n } catch (error) {\n await handle?.close();\n await fs.unlink(tempPath).catch(() => undefined);\n throw error;\n }\n }\n\n private async authorityWithRebuiltHead(\n identity: PartitionIdentity,\n ): Promise<AuthorityTip | null> {\n const tip = await this.readAuthorityTip(identity);\n const head = await this.readProjectedHead(identity);\n if (!tip) {\n if (head) throw new Error(\"Partition head exists without immutable event authority\");\n return null;\n }\n if (head?.receipt !== tip.commit.address || head.event !== tip.eventAddress) {\n await this.writeHead(identity, tip);\n }\n return tip;\n }\n\n private async appendEvent(\n identity: PartitionIdentity,\n receipt: CanonicalJsonAddress,\n previous?: CanonicalJsonAddress,\n ): Promise<CanonicalJsonAddress> {\n const event: PartitionCommitEventV1 = {\n kind: PARTITION_COMMIT_EVENT_KIND,\n version: PARTITION_COMMIT_EVENT_VERSION,\n dataset: identity.dataset,\n partition: identity.partition,\n receipt,\n ...(previous ? { previous } : {}),\n };\n const stored = await this.objects.put(event);\n const indexDir = this.eventIndexDir(identity);\n await this.directories.ensure(indexDir);\n const digest = parseCanonicalJsonAddress(stored.address);\n const eventPath = path.join(indexDir, `${digest}.json`);\n try {\n await fs.link(stored.path, eventPath);\n await syncDirectory(indexDir);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n const existing = await fs.readFile(eventPath);\n if (\n addressBytes(existing) !== stored.address ||\n !existing.equals(canonicalJsonBytes(event))\n ) {\n throw new ContentObjectCollisionError(stored.address, eventPath);\n }\n const handle = await fs.open(eventPath, \"r\");\n try {\n await handle.sync();\n } finally {\n await handle.close();\n }\n await syncDirectory(indexDir);\n }\n return stored.address;\n }\n\n async readCommit(address: CanonicalJsonAddress): Promise<StoredPartitionCommit> {\n parseCanonicalJsonAddress(address);\n const receipt = await this.objects.get<PartitionCommitReceiptV1>(address);\n validateReceipt(receipt, receipt);\n return Object.freeze({ address, receipt, created: false });\n }\n\n /**\n * Adopt an existing canonical Parquet partition after producer-owned schema,\n * identity, coverage, row-count, and exact-byte inspection.\n */\n async [INTERNAL_HISTORICAL_PARTITION_ADOPTION](\n conn: DuckDBConnection,\n identity: PartitionIdentity,\n ): Promise<StoredPartitionCommit> {\n const captured = captureIdentity(identity);\n const definition = canonicalPartitionDataset(captured.dataset) as NonNullable<\n ReturnType<typeof canonicalPartitionDataset>\n >;\n const relativePath = canonicalRelativePath(captured);\n const targetPath = path.resolve(this.targetPath(relativePath));\n return this.withPartitionLock(captured, async () => {\n const realMarketRoot = await this.validateMarketRoot();\n const validatedTargetPath = await this.validatedTargetPath(relativePath, realMarketRoot);\n if (validatedTargetPath !== targetPath) {\n throw new PartitionFileIntegrityError(\n validatedTargetPath,\n \"validated target differs from the registered path\",\n );\n }\n const opened = await openRegularFileNoFollow(targetPath);\n const snapshotRoot = path.join(this.provenanceRootDir, \"inspection-snapshots\");\n await this.directories.ensure(snapshotRoot);\n const snapshotDir = await fs.mkdtemp(path.join(snapshotRoot, \"adopt-\"));\n const snapshotPath = path.join(snapshotDir, \"partition.parquet\");\n try {\n const snapshotFingerprint = await snapshotOpenFile(opened.handle, snapshotPath);\n const snapshotObserved = await exactFileAddress(snapshotPath);\n if (\n snapshotObserved.address !== snapshotFingerprint.address ||\n snapshotObserved.bytes !== snapshotFingerprint.bytes\n ) {\n throw new PartitionFileIntegrityError(\n snapshotPath,\n \"inspection snapshot bytes disagree with the pinned canonical inode\",\n );\n }\n await partitionCommitTestFaults.get(this)?.(\"historical-after-snapshot\");\n const inspected = await inspectCanonicalParquet(conn, snapshotPath, captured);\n const snapshotAfter = await exactFileAddress(snapshotPath);\n if (\n snapshotAfter.address !== snapshotFingerprint.address ||\n snapshotAfter.bytes !== snapshotFingerprint.bytes\n ) {\n throw new PartitionFileIntegrityError(\n snapshotPath,\n \"inspection snapshot changed during semantic inspection\",\n );\n }\n const canonicalAfter = await exactOpenFileAddress(opened.handle);\n const afterStat = await opened.handle.stat();\n if (\n !afterStat.isFile() ||\n afterStat.nlink !== 1 ||\n !sameInode(opened.stat, afterStat) ||\n canonicalAfter.address !== snapshotFingerprint.address ||\n canonicalAfter.bytes !== snapshotFingerprint.bytes\n ) {\n throw new PartitionFileIntegrityError(\n targetPath,\n \"canonical inode changed during historical semantic inspection\",\n );\n }\n await requireNamedRegularInode(targetPath, opened.stat);\n return this.adoptExistingFileCommit(\n {\n dataset: captured.dataset,\n partition: captured.partition,\n schemaRevision: definition.schemaRevision,\n relativePath,\n coverage: inspected.coverage,\n quality: { inputRows: inspected.rows, writtenRows: inspected.rows, droppedRows: 0 },\n file: { ...snapshotFingerprint, rows: inspected.rows },\n },\n true,\n );\n } finally {\n await opened.handle.close();\n await fs.rm(snapshotDir, { recursive: true });\n }\n });\n }\n\n /**\n * Establish immutable authority for a canonical file that predates receipt\n * publication. This never replaces the data file: it pins and hashes the\n * existing regular inode under the partition lock, then appends authority\n * only when the caller-supplied rows/coverage/fingerprint agree exactly.\n */\n private async adoptExistingFileCommit(\n input: RecordPartitionCommitInput,\n lockHeld = false,\n ): Promise<StoredPartitionCommit> {\n const captured = captureInput(input);\n const targetPath = path.resolve(this.targetPath(captured.relativePath));\n const realMarketRoot = await this.validateMarketRoot();\n const adopt = async () => {\n const validatedTargetPath = await this.validatedTargetPath(\n captured.relativePath,\n realMarketRoot,\n );\n if (validatedTargetPath !== targetPath) {\n throw new PartitionFileIntegrityError(\n validatedTargetPath,\n \"validated target differs from the registered path\",\n );\n }\n const opened = await openRegularFileNoFollow(targetPath);\n const handle = opened.handle;\n const pinnedStat = opened.stat;\n try {\n if (\n (await this.validatedTargetPath(captured.relativePath, realMarketRoot)) !== targetPath\n ) {\n throw new PartitionFileIntegrityError(\n targetPath,\n \"target parent changed before existing-file adoption\",\n );\n }\n const observed = await exactOpenFileAddress(handle);\n const afterHash = await handle.stat();\n if (!afterHash.isFile() || afterHash.nlink !== 1 || !sameInode(pinnedStat, afterHash)) {\n throw new PartitionFileIntegrityError(targetPath, \"existing inode changed while hashing\");\n }\n await requireNamedRegularInode(targetPath, pinnedStat);\n if (observed.address !== captured.file.address || observed.bytes !== captured.file.bytes) {\n throw new Error(\"Existing partition bytes do not match the supplied fingerprint\");\n }\n const previous = await this.authorityWithRebuiltHead(captured);\n if (previous && sameCommitContent(previous.commit.receipt, captured)) {\n return previous.commit;\n }\n const receipt: PartitionCommitReceiptV1 = {\n kind: PARTITION_COMMIT_RECEIPT_KIND,\n version: PARTITION_COMMIT_RECEIPT_VERSION,\n schemaRevision: captured.schemaRevision,\n dataset: captured.dataset,\n partition: captured.partition,\n relativePath: captured.relativePath,\n coverage: captured.coverage,\n quality: captured.quality,\n file: captured.file,\n classification: previous ? \"repair\" : \"append\",\n ...(previous ? { parent: previous.commit.address } : {}),\n };\n const published = await this.objects.put(receipt);\n const stored = Object.freeze({\n address: published.address,\n receipt: published.value,\n created: published.created,\n });\n // Establish the linearization point immediately before making the\n // receipt discoverable. Out-of-band mutation after this point is an\n // ordinary repair/mismatch that inspectPartition will refuse.\n if (\n (await this.validatedTargetPath(captured.relativePath, realMarketRoot)) !== targetPath\n ) {\n throw new PartitionFileIntegrityError(\n targetPath,\n \"target parent changed before authority publication\",\n );\n }\n await requireNamedRegularInode(targetPath, pinnedStat);\n const beforeEvent = await exactOpenFileAddress(handle);\n if (\n beforeEvent.address !== stored.receipt.file.address ||\n beforeEvent.bytes !== stored.receipt.file.bytes\n ) {\n throw new Error(\"Existing partition changed before authority publication\");\n }\n const eventAddress = await this.appendEvent(\n captured,\n stored.address,\n previous?.eventAddress,\n );\n await this.writeHead(captured, { eventAddress, commit: stored });\n if (\n (await this.validatedTargetPath(captured.relativePath, realMarketRoot)) !== targetPath\n ) {\n throw new PartitionFileIntegrityError(\n targetPath,\n \"target parent changed during authority publication\",\n );\n }\n await requireNamedRegularInode(targetPath, pinnedStat);\n const finalObserved = await exactOpenFileAddress(handle);\n const afterFinalHash = await handle.stat();\n if (\n !afterFinalHash.isFile() ||\n afterFinalHash.nlink !== 1 ||\n !sameInode(pinnedStat, afterFinalHash)\n ) {\n throw new PartitionFileIntegrityError(\n targetPath,\n \"existing inode changed during final verification\",\n );\n }\n await requireNamedRegularInode(targetPath, pinnedStat);\n if (\n finalObserved.address !== stored.receipt.file.address ||\n finalObserved.bytes !== stored.receipt.file.bytes\n ) {\n throw new Error(\"Existing partition changed during authority publication\");\n }\n return stored;\n } finally {\n await handle.close();\n }\n };\n return lockHeld ? adopt() : this.withPartitionLock(captured, adopt);\n }\n\n async publishFileCommit(input: PublishPartitionFileInput): Promise<StoredPartitionCommit> {\n // Snapshot every semantic field before the first await. Callers may retain\n // and mutate their input object; those mutations cannot change the lock,\n // target, receipt, event, or comparison after publication begins.\n const captured = captureInput(input);\n const preparedPath = path.resolve(String(input.preparedPath));\n const expectedTargetPath = path.resolve(String(input.expectedTargetPath));\n const targetPath = path.resolve(this.targetPath(captured.relativePath));\n if (expectedTargetPath !== targetPath) {\n throw new TypeError(\n `Provenance target does not match the store-owned market path: ${JSON.stringify({ expected: targetPath, observed: expectedTargetPath })}`,\n );\n }\n if (preparedPath === targetPath || path.dirname(preparedPath) !== path.dirname(targetPath)) {\n throw new TypeError(\"Prepared partition file must be a distinct sibling of its target\");\n }\n // Reject an aliased or invalid configured root before lock acquisition can\n // create any authority directories through it.\n const realMarketRoot = await this.validateMarketRoot();\n return this.withPartitionLock(captured, async () => {\n const validatedTargetPath = await this.validatedTargetPath(\n captured.relativePath,\n realMarketRoot,\n );\n if (validatedTargetPath !== targetPath) {\n throw new PartitionFileIntegrityError(\n validatedTargetPath,\n \"validated target differs from the registered path\",\n );\n }\n const targetDirectory = path.dirname(targetPath);\n const claimedPath = path.join(targetDirectory, `.provenance-claim-${randomUUID()}`);\n let claimed = false;\n let targetTouched = false;\n let claimedHandle: fs.FileHandle | undefined;\n let claimedStat: Awaited<ReturnType<fs.FileHandle[\"stat\"]>> | undefined;\n try {\n // Move the caller-controlled directory entry out of its known name\n // before following or reading anything. The random sibling is then\n // opened no-follow and pinned by file descriptor through install.\n await fs.rename(preparedPath, claimedPath);\n claimed = true;\n await syncDirectory(targetDirectory);\n const opened = await openRegularFileNoFollow(claimedPath);\n claimedHandle = opened.handle;\n claimedStat = opened.stat;\n await partitionCommitTestFaults.get(this)?.(\"after-claim-open\");\n const prepared = await exactOpenFileAddress(claimedHandle);\n const afterPreparedHash = await claimedHandle.stat();\n if (\n !afterPreparedHash.isFile() ||\n afterPreparedHash.nlink !== 1 ||\n !sameInode(claimedStat, afterPreparedHash)\n ) {\n throw new PartitionFileIntegrityError(claimedPath, \"claimed inode changed while hashing\");\n }\n await requireNamedRegularInode(claimedPath, claimedStat);\n if (prepared.address !== captured.file.address || prepared.bytes !== captured.file.bytes) {\n throw new Error(\"Prepared partition bytes do not match the supplied fingerprint\");\n }\n await claimedHandle.sync();\n await syncDirectory(targetDirectory);\n\n const previous = await this.authorityWithRebuiltHead(captured);\n let stored: StoredPartitionCommit;\n let pendingEvent:\n { receipt: StoredPartitionCommit; previousEvent?: CanonicalJsonAddress } | undefined;\n if (previous && sameCommitContent(previous.commit.receipt, captured)) {\n stored = previous.commit;\n } else {\n const receipt: PartitionCommitReceiptV1 = {\n kind: PARTITION_COMMIT_RECEIPT_KIND,\n version: PARTITION_COMMIT_RECEIPT_VERSION,\n schemaRevision: captured.schemaRevision,\n dataset: captured.dataset,\n partition: captured.partition,\n relativePath: captured.relativePath,\n coverage: captured.coverage,\n quality: captured.quality,\n file: captured.file,\n classification: previous ? \"repair\" : \"append\",\n ...(previous ? { parent: previous.commit.address } : {}),\n };\n // Receipt bytes are immutable and durable before the data file is\n // installed. They are not authoritative/discoverable until the\n // event index is appended after the rename.\n const publishedReceipt = await this.objects.put(receipt);\n stored = {\n address: publishedReceipt.address,\n receipt: publishedReceipt.value,\n created: publishedReceipt.created,\n };\n Object.freeze(stored);\n pendingEvent = { receipt: stored, previousEvent: previous?.eventAddress };\n }\n\n // Revalidate the directory chain and the claimed name immediately\n // before rename. Node has no renameat(2), so the post-rename inode\n // comparison below is the final fail-closed path-swap check.\n if (\n (await this.validatedTargetPath(captured.relativePath, realMarketRoot)) !== targetPath\n ) {\n throw new PartitionFileIntegrityError(targetPath, \"target parent changed before install\");\n }\n const beforeInstall = await claimedHandle.stat();\n if (\n !beforeInstall.isFile() ||\n beforeInstall.nlink !== 1 ||\n !sameInode(claimedStat, beforeInstall)\n ) {\n throw new PartitionFileIntegrityError(\n claimedPath,\n \"claimed inode changed before install\",\n );\n }\n await requireNamedRegularInode(claimedPath, claimedStat);\n await fs.rename(claimedPath, targetPath);\n claimed = false;\n targetTouched = true;\n await syncDirectory(targetDirectory);\n await requireNamedRegularInode(targetPath, claimedStat);\n const afterInstall = await claimedHandle.stat();\n if (\n !afterInstall.isFile() ||\n afterInstall.nlink !== 1 ||\n !sameInode(claimedStat, afterInstall)\n ) {\n throw new PartitionFileIntegrityError(targetPath, \"installed inode changed\");\n }\n const observed = await exactOpenFileAddress(claimedHandle);\n const afterInstalledHash = await claimedHandle.stat();\n if (\n !afterInstalledHash.isFile() ||\n afterInstalledHash.nlink !== 1 ||\n !sameInode(claimedStat, afterInstalledHash)\n ) {\n throw new PartitionFileIntegrityError(\n targetPath,\n \"installed inode changed while hashing\",\n );\n }\n await requireNamedRegularInode(targetPath, claimedStat);\n await claimedHandle.sync();\n if (\n observed.address !== stored.receipt.file.address ||\n observed.bytes !== stored.receipt.file.bytes\n ) {\n throw new Error(\"Installed partition bytes disagree with immutable commit authority\");\n }\n\n if (pendingEvent) {\n const eventAddress = await this.appendEvent(\n captured,\n pendingEvent.receipt.address,\n pendingEvent.previousEvent,\n );\n await partitionCommitTestFaults.get(this)?.(\"after-event-before-head\");\n await this.writeHead(captured, { eventAddress, commit: pendingEvent.receipt });\n }\n const tip = await this.authorityWithRebuiltHead(captured);\n if (!tip || tip.commit.address !== stored.address) {\n throw new Error(\"Installed partition and authoritative head disagree\");\n }\n if (\n (await this.validatedTargetPath(captured.relativePath, realMarketRoot)) !== targetPath\n ) {\n throw new PartitionFileIntegrityError(\n targetPath,\n \"target parent changed before publication completed\",\n );\n }\n const beforeReturn = await claimedHandle.stat();\n if (\n !beforeReturn.isFile() ||\n beforeReturn.nlink !== 1 ||\n !sameInode(claimedStat, beforeReturn)\n ) {\n throw new PartitionFileIntegrityError(\n targetPath,\n \"installed inode changed before publication completed\",\n );\n }\n await requireNamedRegularInode(targetPath, claimedStat);\n const finalObserved = await exactOpenFileAddress(claimedHandle);\n const afterFinalHash = await claimedHandle.stat();\n if (\n !afterFinalHash.isFile() ||\n afterFinalHash.nlink !== 1 ||\n !sameInode(claimedStat, afterFinalHash)\n ) {\n throw new PartitionFileIntegrityError(\n targetPath,\n \"installed inode changed during final verification\",\n );\n }\n await requireNamedRegularInode(targetPath, claimedStat);\n if (\n finalObserved.address !== stored.receipt.file.address ||\n finalObserved.bytes !== stored.receipt.file.bytes\n ) {\n throw new Error(\"Installed partition changed before publication completed\");\n }\n return stored;\n } catch (error) {\n if (targetTouched) {\n throw new PartitionFilePublicationError(targetPath, captured.file, error);\n }\n throw error;\n } finally {\n await claimedHandle?.close();\n if (claimed) await this.restoreOrQuarantineClaim(claimedPath, preparedPath);\n }\n });\n }\n\n async inspectPartition(identity: PartitionIdentity): Promise<PartitionInspection> {\n const captured = captureIdentity(identity);\n const realMarketRoot = await this.validateMarketRoot();\n return this.withPartitionLock(captured, async () => {\n const tip = await this.authorityWithRebuiltHead(captured);\n const relativePath = tip?.commit.receipt.relativePath ?? canonicalRelativePath(captured);\n validateRegistryPath(captured, relativePath);\n let observed: Omit<ExactFileFingerprint, \"rows\">;\n try {\n const targetPath = await this.validatedTargetPath(relativePath, realMarketRoot);\n observed = await exactFileAddress(targetPath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return tip ? { status: \"missing\", receipt: tip.commit } : { status: \"absent\" };\n }\n throw error;\n }\n if (!tip) return { status: \"orphan\", observed };\n if (\n tip.commit.receipt.file.address !== observed.address ||\n tip.commit.receipt.file.bytes !== observed.bytes\n ) {\n return { status: \"mismatch\", receipt: tip.commit, observed };\n }\n return { status: \"match\", receipt: tip.commit };\n });\n }\n}\n\n/** @internal Producer-only capability marker; intentionally omitted from the public barrel. */\nexport async function publishRefreshCompletionAuthority(\n store: FilePartitionCommitStore,\n completion: CanonicalJsonAddress,\n): Promise<void> {\n const digest = parseCanonicalJsonAddress(completion);\n const source = store.objects.objectPath(completion);\n const directory = path.join(store.provenanceRootDir, \"refresh-completions\", digest.slice(0, 2));\n const marker = path.join(directory, `${digest}.json`);\n await fs.mkdir(directory, { recursive: true });\n try {\n await fs.link(source, marker);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n }\n const bytes = await fs.readFile(marker);\n if (addressBytes(bytes) !== completion) {\n throw new ContentObjectCollisionError(completion, marker);\n }\n const handle = await fs.open(marker, \"r\");\n try {\n await handle.sync();\n } finally {\n await handle.close();\n }\n const directoryHandle = await fs.open(directory, \"r\");\n try {\n await directoryHandle.sync();\n } finally {\n await directoryHandle.close();\n }\n}\n\n/** @internal Verifies publication through the producer-only completion rail. */\nexport async function verifyRefreshCompletionAuthority(\n store: FilePartitionCommitStore,\n completion: CanonicalJsonAddress,\n): Promise<void> {\n const digest = parseCanonicalJsonAddress(completion);\n const marker = path.join(\n store.provenanceRootDir,\n \"refresh-completions\",\n digest.slice(0, 2),\n `${digest}.json`,\n );\n const stat = await fs.lstat(marker);\n if (!stat.isFile() || stat.isSymbolicLink()) {\n throw new Error(\"Canonical refresh completion has no producer authority marker\");\n }\n const bytes = await fs.readFile(marker);\n const object = await fs.readFile(store.objects.objectPath(completion));\n if (addressBytes(bytes) !== completion || !bytes.equals(object)) {\n throw new Error(\"Canonical refresh completion authority marker is corrupt\");\n }\n}\n\nexport class PartitionFilePublicationError extends Error {\n readonly targetPath: string;\n readonly file: ExactFileFingerprint;\n\n constructor(targetPath: string, file: ExactFileFingerprint, cause: unknown) {\n super(`Partition file installed without a complete projected commit: ${targetPath}`, { cause });\n this.name = \"PartitionFilePublicationError\";\n this.targetPath = targetPath;\n this.file = file;\n }\n}\n","import * as path from \"node:path\";\n\nexport interface DatasetPartitionIdentity {\n dataset: string;\n partition: Record<string, string>;\n}\n\nexport type DatasetProvenancePosture =\n { kind: \"bounded-session\"; sessionKey: string } | { kind: \"unbounded-unsupported\" };\n\nexport interface MarketDatasetDefinition {\n subdir: string;\n partitionKeys: readonly string[];\n filename: string;\n schemaRevision: number;\n provenance: DatasetProvenancePosture;\n}\n\nexport interface BoundedMarketDatasetDefinition extends MarketDatasetDefinition {\n provenance: { kind: \"bounded-session\"; sessionKey: string };\n}\n\nconst ISO_DATE_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n/**\n * One canonical registry for every market dataset writer and provenance path.\n * Unbounded legacy files remain writable outside attempts but cannot mint\n * partition receipts or cutoff manifests until bounded slices replace them.\n */\nfunction deepFreezeDatasetRegistry<T extends Record<string, MarketDatasetDefinition>>(\n registry: T,\n): T {\n for (const definition of Object.values(registry)) {\n Object.freeze(definition.partitionKeys);\n Object.freeze(definition.provenance);\n Object.freeze(definition);\n }\n return Object.freeze(registry);\n}\n\nexport const MARKET_DATASETS = deepFreezeDatasetRegistry({\n spot: {\n subdir: \"spot\",\n partitionKeys: [\"ticker\", \"date\"],\n filename: \"data.parquet\",\n schemaRevision: 1,\n provenance: { kind: \"bounded-session\", sessionKey: \"date\" },\n },\n enriched: {\n subdir: \"enriched\",\n partitionKeys: [\"ticker\", \"date\"],\n filename: \"data.parquet\",\n schemaRevision: 1,\n provenance: { kind: \"bounded-session\", sessionKey: \"date\" },\n },\n enriched_context: {\n subdir: \"enriched/context\",\n partitionKeys: [\"date\"],\n filename: \"data.parquet\",\n schemaRevision: 1,\n provenance: { kind: \"bounded-session\", sessionKey: \"date\" },\n },\n option_chain: {\n subdir: \"option_chain\",\n partitionKeys: [\"underlying\", \"date\"],\n filename: \"data.parquet\",\n schemaRevision: 1,\n provenance: { kind: \"bounded-session\", sessionKey: \"date\" },\n },\n option_quote_minutes: {\n subdir: \"option_quote_minutes\",\n partitionKeys: [\"underlying\", \"date\"],\n filename: \"data.parquet\",\n schemaRevision: 1,\n provenance: { kind: \"bounded-session\", sessionKey: \"date\" },\n },\n option_oi_daily: {\n subdir: \"option_oi_daily\",\n partitionKeys: [\"underlying\", \"date\"],\n filename: \"data.parquet\",\n schemaRevision: 1,\n provenance: { kind: \"bounded-session\", sessionKey: \"date\" },\n },\n} satisfies Record<string, MarketDatasetDefinition>);\n\nexport type MarketDatasetName = keyof typeof MARKET_DATASETS;\n\nexport function isRealMarketSessionDate(value: string): boolean {\n if (!ISO_DATE_RE.test(value)) return false;\n const parsed = new Date(`${value}T00:00:00.000Z`);\n return Number.isFinite(parsed.getTime()) && parsed.toISOString().slice(0, 10) === value;\n}\n\nexport function marketDatasetDefinition(dataset: string): MarketDatasetDefinition | undefined {\n return Object.hasOwn(MARKET_DATASETS, dataset)\n ? MARKET_DATASETS[dataset as MarketDatasetName]\n : undefined;\n}\n\nexport function canonicalPartitionDataset(\n dataset: string,\n): BoundedMarketDatasetDefinition | undefined {\n const definition = marketDatasetDefinition(dataset);\n return definition?.provenance.kind === \"bounded-session\"\n ? (definition as BoundedMarketDatasetDefinition)\n : undefined;\n}\n\nexport function validatePartitionIdentity(identity: DatasetPartitionIdentity): void {\n const definition = canonicalPartitionDataset(identity.dataset);\n if (!definition) {\n throw new TypeError(`Unregistered provenance dataset: ${JSON.stringify(identity.dataset)}`);\n }\n const expectedKeys = [...definition.partitionKeys].sort();\n const observedKeys = Object.keys(identity.partition).sort();\n if (\n observedKeys.length !== expectedKeys.length ||\n observedKeys.some((key, index) => key !== expectedKeys[index])\n ) {\n throw new TypeError(\n `Invalid provenance partition keys: ${JSON.stringify({ dataset: identity.dataset, observedKeys, expectedKeys })}`,\n );\n }\n for (const [key, value] of Object.entries(identity.partition)) {\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key) || !/^[A-Za-z0-9._-]+$/.test(value)) {\n throw new TypeError(`Invalid provenance partition: ${JSON.stringify({ key, value })}`);\n }\n }\n const session = identity.partition[definition.provenance.sessionKey];\n if (!isRealMarketSessionDate(session)) {\n throw new TypeError(`Invalid provenance partition date: ${JSON.stringify(session)}`);\n }\n}\n\nexport function canonicalPartitionRelativePath(identity: DatasetPartitionIdentity): string {\n validatePartitionIdentity(identity);\n const definition = canonicalPartitionDataset(identity.dataset) as BoundedMarketDatasetDefinition;\n return path.posix.join(\n definition.subdir,\n ...definition.partitionKeys.map((key) => `${key}=${identity.partition[key]}`),\n definition.filename,\n );\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { PartitionCommitRecorder, StoredPartitionCommit } from \"./partition-commit-store.ts\";\nimport type { CanonicalJsonAddress } from \"./canonical-json.ts\";\n\nexport interface PartitionCommitAttemptOptions {\n /** Caller-owned correlation identifier; not part of receipt content identity. */\n attemptId: string;\n recorder: PartitionCommitRecorder;\n}\n\nexport interface PartitionCommitAttemptResult<T> {\n attemptId: string;\n value: T;\n receipts: readonly StoredPartitionCommit[];\n}\n\ninterface ActivePartitionCommitAttempt extends PartitionCommitAttemptOptions {\n receiptAddresses: CanonicalJsonAddress[];\n}\n\nconst attempts = new AsyncLocalStorage<ActivePartitionCommitAttempt>();\n\nfunction compareCodePoints(left: string, right: string): number {\n const leftPoints = Array.from(left, (character) => character.codePointAt(0) as number);\n const rightPoints = Array.from(right, (character) => character.codePointAt(0) as number);\n const length = Math.min(leftPoints.length, rightPoints.length);\n for (let index = 0; index < length; index++) {\n if (leftPoints[index] !== rightPoints[index]) return leftPoints[index] - rightPoints[index];\n }\n return leftPoints.length - rightPoints.length;\n}\n\nfunction commitTuple(commit: StoredPartitionCommit): string[] {\n const partition = Object.entries(commit.receipt.partition)\n .sort(([left], [right]) => compareCodePoints(left, right))\n .flatMap(([key, value]) => [key, value]);\n return [commit.receipt.dataset, ...partition, commit.address];\n}\n\nfunction compareTuple(left: string[], right: string[]): number {\n const length = Math.min(left.length, right.length);\n for (let index = 0; index < length; index++) {\n const compared = compareCodePoints(left[index], right[index]);\n if (compared !== 0) return compared;\n }\n return left.length - right.length;\n}\n\n/**\n * Run an ingest/write operation with exact-byte partition receipt capture.\n *\n * Store APIs remain unchanged: canonical dataset writers discover this async\n * scope, persist receipts through its recorder, and append successful commits\n * to the returned list. Outside a scope, those writers retain legacy behavior\n * and skip the hashing/receipt work entirely.\n */\nexport async function runPartitionCommitAttempt<T>(\n options: PartitionCommitAttemptOptions,\n operation: () => Promise<T>,\n): Promise<PartitionCommitAttemptResult<T>> {\n if (options.attemptId.trim().length === 0) {\n throw new TypeError(\"Partition commit attemptId must not be empty\");\n }\n const active: ActivePartitionCommitAttempt = { ...options, receiptAddresses: [] };\n const value = await attempts.run(active, operation);\n const receipts = await Promise.all(\n [...new Set(active.receiptAddresses)].map((address) => active.recorder.readCommit(address)),\n );\n receipts.sort((left, right) => compareTuple(commitTuple(left), commitTuple(right)));\n return {\n attemptId: active.attemptId,\n value,\n receipts: Object.freeze(receipts),\n };\n}\n\n/** @internal Package-internal canonical writer hook; omitted from the public barrel. */\nexport function activePartitionCommitAttempt():\n Pick<ActivePartitionCommitAttempt, \"attemptId\" | \"recorder\"> | undefined {\n return attempts.getStore();\n}\n\n/** @internal Package-internal hook; captures only successfully projected commits. */\nexport function capturePartitionCommitReceipt(receipt: StoredPartitionCommit): void {\n const active = attempts.getStore();\n if (!active) return;\n active.receiptAddresses.push(receipt.address);\n}\n","// Generated by tools/generate-replay-calendar.mjs from the bounded lib XNYS calendar.\nexport const XNYS_SESSION_CALENDAR_REVISION = \"xnys-full-day-2022-2030-v1\" as const;\nexport const XNYS_SESSION_CALENDAR_SUPPORTED_FROM = \"2022-01-01\" as const;\nexport const XNYS_SESSION_CALENDAR_SUPPORTED_THROUGH = \"2030-12-31\" as const;\nexport const CLOSED_DATES: ReadonlySet<string> = new Set([\n \"2022-01-17\",\n \"2022-02-21\",\n \"2022-04-15\",\n \"2022-05-30\",\n \"2022-06-20\",\n \"2022-07-04\",\n \"2022-09-05\",\n \"2022-11-24\",\n \"2022-12-26\",\n \"2023-01-02\",\n \"2023-01-16\",\n \"2023-02-20\",\n \"2023-04-07\",\n \"2023-05-29\",\n \"2023-06-19\",\n \"2023-07-04\",\n \"2023-09-04\",\n \"2023-11-23\",\n \"2023-12-25\",\n \"2024-01-01\",\n \"2024-01-15\",\n \"2024-02-19\",\n \"2024-03-29\",\n \"2024-05-27\",\n \"2024-06-19\",\n \"2024-07-04\",\n \"2024-09-02\",\n \"2024-11-28\",\n \"2024-12-25\",\n \"2025-01-01\",\n \"2025-01-09\",\n \"2025-01-20\",\n \"2025-02-17\",\n \"2025-04-18\",\n \"2025-05-26\",\n \"2025-06-19\",\n \"2025-07-04\",\n \"2025-09-01\",\n \"2025-11-27\",\n \"2025-12-25\",\n \"2026-01-01\",\n \"2026-01-19\",\n \"2026-02-16\",\n \"2026-04-03\",\n \"2026-05-25\",\n \"2026-06-19\",\n \"2026-07-03\",\n \"2026-09-07\",\n \"2026-11-26\",\n \"2026-12-25\",\n \"2027-01-01\",\n \"2027-01-18\",\n \"2027-02-15\",\n \"2027-03-26\",\n \"2027-05-31\",\n \"2027-06-18\",\n \"2027-07-05\",\n \"2027-09-06\",\n \"2027-11-25\",\n \"2027-12-24\",\n \"2028-01-17\",\n \"2028-02-21\",\n \"2028-04-14\",\n \"2028-05-29\",\n \"2028-06-19\",\n \"2028-07-04\",\n \"2028-09-04\",\n \"2028-11-23\",\n \"2028-12-25\",\n \"2029-01-01\",\n \"2029-01-15\",\n \"2029-02-19\",\n \"2029-03-30\",\n \"2029-05-28\",\n \"2029-06-19\",\n \"2029-07-04\",\n \"2029-09-03\",\n \"2029-11-22\",\n \"2029-12-25\",\n \"2030-01-01\",\n \"2030-01-21\",\n \"2030-02-18\",\n \"2030-04-19\",\n \"2030-05-27\",\n \"2030-06-19\",\n \"2030-07-04\",\n \"2030-09-02\",\n \"2030-11-28\",\n \"2030-12-25\",\n]);\nexport const EARLY_CLOSE_DATES: ReadonlySet<string> = new Set([\n \"2022-11-25\",\n \"2023-07-03\",\n \"2023-11-24\",\n \"2024-07-03\",\n \"2024-11-29\",\n \"2024-12-24\",\n \"2025-07-03\",\n \"2025-11-28\",\n \"2025-12-24\",\n \"2026-11-27\",\n \"2026-12-24\",\n \"2027-11-26\",\n \"2028-07-03\",\n \"2028-11-24\",\n \"2029-07-03\",\n \"2029-11-23\",\n \"2029-12-24\",\n \"2030-07-03\",\n \"2030-11-29\",\n \"2030-12-24\",\n]);\n","import {\n CLOSED_DATES,\n EARLY_CLOSE_DATES,\n XNYS_SESSION_CALENDAR_REVISION,\n XNYS_SESSION_CALENDAR_SUPPORTED_FROM,\n XNYS_SESSION_CALENDAR_SUPPORTED_THROUGH,\n} from \"./xnys-calendar-data.ts\";\n\nexport {\n XNYS_SESSION_CALENDAR_REVISION,\n XNYS_SESSION_CALENDAR_SUPPORTED_FROM,\n XNYS_SESSION_CALENDAR_SUPPORTED_THROUGH,\n};\n\n// The published MCP package cannot import the private library at runtime.\n// Membership snapshots are generated from that library's sole calendar authority.\nfunction supportedDate(value: string, label: string): Date {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(value)) {\n throw new TypeError(\n `${label} must be an ISO calendar date (YYYY-MM-DD): ${JSON.stringify(value)}`,\n );\n }\n const date = new Date(`${value}T00:00:00.000Z`);\n if (!Number.isFinite(date.getTime()) || date.toISOString().slice(0, 10) !== value) {\n throw new TypeError(`${label} is not a real calendar date: ${JSON.stringify(value)}`);\n }\n if (\n value < XNYS_SESSION_CALENDAR_SUPPORTED_FROM ||\n value > XNYS_SESSION_CALENDAR_SUPPORTED_THROUGH\n ) {\n throw new RangeError(\n `${label} ${JSON.stringify(value)} is outside XNYS calendar revision ${XNYS_SESSION_CALENDAR_REVISION} ` +\n `[${XNYS_SESSION_CALENDAR_SUPPORTED_FROM}, ${XNYS_SESSION_CALENDAR_SUPPORTED_THROUGH}]`,\n );\n }\n return date;\n}\n\nexport function isXnysSessionDate(value: string): boolean {\n const date = supportedDate(value, \"XNYS session date\");\n const weekday = date.getUTCDay();\n return weekday !== 0 && weekday !== 6 && !CLOSED_DATES.has(value);\n}\n\nexport function isEarlyCloseSession(value: string): boolean {\n return isXnysSessionDate(value) && EARLY_CLOSE_DATES.has(value);\n}\n\nexport function enumerateXnysSessions(from: string, through: string): readonly string[] {\n const first = supportedDate(from, \"XNYS session range from\");\n const last = supportedDate(through, \"XNYS session range through\");\n if (first.getTime() > last.getTime()) {\n throw new RangeError(\n `XNYS session range from ${JSON.stringify(from)} exceeds through ${JSON.stringify(through)}`,\n );\n }\n const sessions: string[] = [];\n for (\n let cursor = first;\n cursor.getTime() <= last.getTime();\n cursor.setUTCDate(cursor.getUTCDate() + 1)\n ) {\n const date = cursor.toISOString().slice(0, 10);\n if (isXnysSessionDate(date)) sessions.push(date);\n }\n return Object.freeze(sessions);\n}\n","import type { DuckDBConnection } from \"@duckdb/node-api\";\nimport { existsSync, readdirSync } from \"node:fs\";\nimport * as path from \"node:path\";\nimport {\n resolveMarketDir,\n writeEnrichedContextPartition,\n writeEnrichedTickerPartition,\n} from \"../../db/market-datasets.ts\";\nimport {\n activePartitionCommitAttempt,\n capturePartitionCommitReceipt,\n} from \"../provenance/partition-commit-attempt.ts\";\nimport { isRealMarketSessionDate } from \"../provenance/dataset-registry.ts\";\nimport {\n INTERNAL_HISTORICAL_PARTITION_ADOPTION,\n type PartitionIdentity,\n type StoredPartitionCommit,\n} from \"../provenance/partition-commit-store.ts\";\nimport { isXnysSessionDate } from \"../provenance/xnys-session-calendar.ts\";\nimport { TICKER_RE } from \"../tickers/schemas.ts\";\n\nfunction escapeSqlLiteral(value: string): string {\n return value.replace(/'/g, \"''\");\n}\n\nexport class LegacyEnrichedMigrationError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"LegacyEnrichedMigrationError\";\n }\n}\n\nasync function legacyDates(conn: DuckDBConnection, filePath: string): Promise<string[]> {\n const escaped = escapeSqlLiteral(filePath);\n const reader = await conn.runAndReadAll(\n `SELECT CAST(date AS VARCHAR) AS logical_date, count(*) AS row_count\n FROM read_parquet('${escaped}', hive_partitioning=false)\n GROUP BY logical_date\n ORDER BY logical_date`,\n );\n const dates: string[] = [];\n for (const [rawDate, rawCount] of reader.getRows()) {\n const date = String(rawDate);\n const count = Number(rawCount);\n if (!isRealMarketSessionDate(date) || count !== 1) {\n throw new LegacyEnrichedMigrationError(\n `Legacy enriched file cannot be split safely: ${JSON.stringify({ filePath, date, rows: count })}`,\n );\n }\n try {\n if (isXnysSessionDate(date)) dates.push(date);\n } catch (error) {\n // Whole-file reads predate the bounded provenance calendar. Preserve\n // valid historical/future rows for ordinary reads, but keep known\n // in-horizon closures excluded.\n if (error instanceof RangeError) {\n dates.push(date);\n continue;\n }\n throw new LegacyEnrichedMigrationError(\n `Legacy enriched file has an invalid session date: ${JSON.stringify({ filePath, date })}`,\n { cause: error },\n );\n }\n }\n return dates;\n}\n\nfunction migrationEligibleSessionDate(date: string): boolean {\n try {\n return isXnysSessionDate(date);\n } catch (error) {\n if (error instanceof RangeError) return false;\n throw error;\n }\n}\n\nexport interface LegacyEnrichedSource {\n filePath: string;\n dates: string[];\n}\n\nexport interface LegacyMigrationBounds {\n from?: string;\n to?: string;\n}\n\nfunction insideBounds(date: string, bounds?: LegacyMigrationBounds): boolean {\n return (!bounds?.from || date >= bounds.from) && (!bounds?.to || date <= bounds.to);\n}\n\nexport async function inspectLegacyEnrichedTicker(\n conn: DuckDBConnection,\n dataDir: string,\n ticker: string,\n): Promise<LegacyEnrichedSource | null> {\n if (!TICKER_RE.test(ticker)) {\n throw new LegacyEnrichedMigrationError(\n `Legacy enriched ticker is not safe to read or migrate: ${JSON.stringify(ticker)}`,\n );\n }\n const tickerDir = path.join(resolveMarketDir(dataDir), \"enriched\", `ticker=${ticker}`);\n const legacyPath = path.join(tickerDir, \"data.parquet\");\n if (!existsSync(legacyPath)) return null;\n const escapedLegacy = escapeSqlLiteral(legacyPath);\n const observedTickers = await conn.runAndReadAll(\n `SELECT DISTINCT CAST(ticker AS VARCHAR)\n FROM read_parquet('${escapedLegacy}', hive_partitioning=false)\n ORDER BY 1`,\n );\n const values = observedTickers.getRows().map((row) => String(row[0]));\n if (values.length !== 1 || values[0] !== ticker) {\n throw new LegacyEnrichedMigrationError(\n `Legacy enriched ticker identity disagrees with its path: ${JSON.stringify({ ticker, observed: values })}`,\n );\n }\n return { filePath: legacyPath, dates: await legacyDates(conn, legacyPath) };\n}\n\nasync function establishExistingAuthority(\n conn: DuckDBConnection,\n dataset: string,\n partition: Record<string, string>,\n): Promise<void> {\n const attempt = activePartitionCommitAttempt();\n if (!attempt) return;\n const internalRecorder = attempt.recorder as typeof attempt.recorder & {\n [INTERNAL_HISTORICAL_PARTITION_ADOPTION]?: (\n connection: DuckDBConnection,\n identity: PartitionIdentity,\n ) => Promise<StoredPartitionCommit>;\n };\n const adopt = internalRecorder[INTERNAL_HISTORICAL_PARTITION_ADOPTION];\n if (!adopt) {\n throw new LegacyEnrichedMigrationError(\n `Active migration recorder cannot adopt existing ${dataset} partition authority`,\n );\n }\n const stored = await adopt.call(internalRecorder, conn, { dataset, partition });\n capturePartitionCommitReceipt(stored);\n}\n\n/**\n * Split a 3.3.x `enriched/ticker=X/data.parquet` file into missing bounded\n * session slices. Existing slices are never replaced: the bounded layout is\n * authoritative when old and new files coexist.\n */\nexport async function migrateLegacyEnrichedTicker(\n conn: DuckDBConnection,\n dataDir: string,\n ticker: string,\n bounds?: LegacyMigrationBounds,\n): Promise<void> {\n const tickerDir = path.join(resolveMarketDir(dataDir), \"enriched\", `ticker=${ticker}`);\n\n try {\n const legacy = await inspectLegacyEnrichedTicker(conn, dataDir, ticker);\n if (!legacy) return;\n const escapedLegacy = escapeSqlLiteral(legacy.filePath);\n for (const date of legacy.dates.filter(\n (candidate) => insideBounds(candidate, bounds) && migrationEligibleSessionDate(candidate),\n )) {\n const targetPath = path.join(tickerDir, `date=${date}`, \"data.parquet\");\n if (existsSync(targetPath)) {\n await establishExistingAuthority(conn, \"enriched\", { ticker, date });\n continue;\n }\n await writeEnrichedTickerPartition(conn, {\n dataDir,\n ticker,\n date,\n selectQuery:\n `SELECT * FROM read_parquet('${escapedLegacy}', hive_partitioning=false) ` +\n `WHERE ticker = '${escapeSqlLiteral(ticker)}' AND CAST(date AS VARCHAR) = '${date}'`,\n quality: { kind: \"writer-input-complete\" },\n });\n }\n } catch (error) {\n if (error instanceof LegacyEnrichedMigrationError) throw error;\n const detail = error instanceof Error ? `: ${error.message}` : \"\";\n throw new LegacyEnrichedMigrationError(\n `Failed to migrate legacy enriched ticker file for ${ticker}${detail}`,\n { cause: error },\n );\n }\n}\n\nfunction completeContextRow(row: unknown[]): boolean {\n const [, volRegime, termStructure, trendDirection, vixSpikePct, vixGapPct] = row;\n return (\n Number.isInteger(volRegime) &&\n Number(volRegime) >= 1 &&\n Number(volRegime) <= 6 &&\n Number.isInteger(termStructure) &&\n [-1, 0, 1].includes(Number(termStructure)) &&\n typeof trendDirection === \"string\" &&\n [\"up\", \"down\", \"flat\"].includes(trendDirection) &&\n typeof vixSpikePct === \"number\" &&\n Number.isFinite(vixSpikePct) &&\n typeof vixGapPct === \"number\" &&\n Number.isFinite(vixGapPct)\n );\n}\n\nexport async function inspectLegacyEnrichedContext(\n conn: DuckDBConnection,\n dataDir: string,\n): Promise<LegacyEnrichedSource | null> {\n const legacyPath = path.join(resolveMarketDir(dataDir), \"enriched\", \"context\", \"data.parquet\");\n if (!existsSync(legacyPath)) return null;\n const escapedLegacy = escapeSqlLiteral(legacyPath);\n const completeDates: string[] = [];\n for (const date of await legacyDates(conn, legacyPath)) {\n const selected = await conn.runAndReadAll(\n `SELECT date, Vol_Regime, Term_Structure_State, Trend_Direction,\n VIX_Spike_Pct, VIX_Gap_Pct\n FROM read_parquet('${escapedLegacy}', hive_partitioning=false)\n WHERE CAST(date AS VARCHAR) = '${date}'`,\n );\n const rows = selected.getRows();\n if (rows.length === 1 && completeContextRow(rows[0])) completeDates.push(date);\n }\n return { filePath: legacyPath, dates: completeDates };\n}\n\n/**\n * Split the 3.3.x `enriched/context/data.parquet` file into complete bounded\n * sessions. Partial context rows remain in the legacy file but are omitted\n * from canonical authority rather than being represented as complete inputs.\n */\nexport async function migrateLegacyEnrichedContext(\n conn: DuckDBConnection,\n dataDir: string,\n bounds?: LegacyMigrationBounds,\n): Promise<void> {\n const contextDir = path.join(resolveMarketDir(dataDir), \"enriched\", \"context\");\n const legacyPath = path.join(contextDir, \"data.parquet\");\n if (!existsSync(legacyPath)) return;\n\n try {\n const legacy = await inspectLegacyEnrichedContext(conn, dataDir);\n if (!legacy) return;\n const escapedLegacy = escapeSqlLiteral(legacy.filePath);\n for (const date of legacy.dates.filter(\n (candidate) => insideBounds(candidate, bounds) && migrationEligibleSessionDate(candidate),\n )) {\n const targetPath = path.join(contextDir, `date=${date}`, \"data.parquet\");\n if (existsSync(targetPath)) {\n await establishExistingAuthority(conn, \"enriched_context\", { date });\n continue;\n }\n await writeEnrichedContextPartition(conn, {\n dataDir,\n date,\n selectQuery:\n `SELECT * FROM read_parquet('${escapedLegacy}', hive_partitioning=false) ` +\n `WHERE CAST(date AS VARCHAR) = '${date}'`,\n quality: { kind: \"writer-input-complete\" },\n });\n }\n } catch (error) {\n if (error instanceof LegacyEnrichedMigrationError) throw error;\n const detail = error instanceof Error ? `: ${error.message}` : \"\";\n throw new LegacyEnrichedMigrationError(\n `Failed to migrate legacy enriched context file: ${legacyPath}${detail}`,\n { cause: error },\n );\n }\n}\n\n/** Migrate every legacy per-ticker file plus the shared context file. */\nexport async function migrateAllLegacyEnrichedFiles(\n conn: DuckDBConnection,\n dataDir: string,\n bounds?: LegacyMigrationBounds,\n): Promise<void> {\n const enrichedDir = path.join(resolveMarketDir(dataDir), \"enriched\");\n if (existsSync(enrichedDir)) {\n let entries: string[];\n try {\n entries = readdirSync(enrichedDir);\n } catch (error) {\n throw new LegacyEnrichedMigrationError(\n `Cannot enumerate legacy enriched data: ${enrichedDir}`,\n { cause: error },\n );\n }\n for (const entry of entries.sort()) {\n if (!entry.startsWith(\"ticker=\")) continue;\n const ticker = entry.slice(\"ticker=\".length);\n if (existsSync(path.join(enrichedDir, entry, \"data.parquet\"))) {\n await migrateLegacyEnrichedTicker(conn, dataDir, ticker, bounds);\n }\n }\n }\n await migrateLegacyEnrichedContext(conn, dataDir, bounds);\n}\n","import type { DuckDBConnection } from \"@duckdb/node-api\";\nimport * as path from \"path\";\nimport { getDataRoot } from \"./data-root.ts\";\nimport {\n writeParquetAtomic,\n writeParquetPartition,\n type ParquetWriteResult,\n} from \"./parquet-writer.ts\";\nimport { MARKET_DATASETS } from \"../market/provenance/dataset-registry.ts\";\n\nexport type CanonicalSingleFileDataset = \"daily\" | \"date_context\";\nexport type CanonicalPartitionedDataset = \"intraday\" | \"option_chain\" | \"option_quote_minutes\";\nexport type CanonicalMarketDataset = CanonicalSingleFileDataset | CanonicalPartitionedDataset;\n\nconst SINGLE_FILE_DATASETS: Record<CanonicalSingleFileDataset, string> = {\n daily: \"daily.parquet\",\n date_context: \"date_context.parquet\",\n};\n\nconst PARTITIONED_DATASETS: Record<CanonicalPartitionedDataset, string> = {\n intraday: \"intraday\",\n option_chain: \"option_chain\",\n option_quote_minutes: \"option_quote_minutes\",\n};\n\nexport function resolveMarketDir(dataDir: string): string {\n return path.join(getDataRoot(dataDir), \"market\");\n}\n\nexport function resolveCanonicalMarketFile(\n dataDir: string,\n dataset: CanonicalSingleFileDataset,\n): string {\n return path.join(resolveMarketDir(dataDir), SINGLE_FILE_DATASETS[dataset]);\n}\n\nexport function resolveCanonicalMarketPartitionDir(\n dataDir: string,\n dataset: CanonicalPartitionedDataset,\n): string {\n return path.join(resolveMarketDir(dataDir), PARTITIONED_DATASETS[dataset]);\n}\n\nexport function resolveCanonicalMarketPartitionPath(\n dataDir: string,\n dataset: CanonicalPartitionedDataset,\n date: string,\n): string {\n return path.join(resolveCanonicalMarketPartitionDir(dataDir, dataset), `date=${date}`);\n}\n\nexport function resolveCanonicalMarketPartitionFile(\n dataDir: string,\n dataset: CanonicalPartitionedDataset,\n date: string,\n): string {\n return path.join(resolveCanonicalMarketPartitionPath(dataDir, dataset, date), \"data.parquet\");\n}\n\nexport function canonicalMarketTableName(dataset: CanonicalMarketDataset): string {\n return `market.${dataset}`;\n}\n\n// ============================================================================\n// Declarative dataset registry — canonical Parquet layout\n//\n// spot: spot/ticker=X/date=Y/data.parquet\n// enriched: enriched/ticker=X/data.parquet\n// enriched_context: enriched/context/data.parquet\n// option_chain: option_chain/underlying=X/date=Y/data.parquet\n// option_quote_minutes: option_quote_minutes/underlying=X/date=Y/data.parquet\n//\n// This mutable exported registry is a compatibility contract for the public\n// tradeblocks-mcp/db/market-datasets subpath. Bounded provenance writers use\n// the separate frozen internal registry below.\n// ============================================================================\n\nexport interface DatasetDef {\n subdir: string;\n partitionKeys: string[];\n filename: string;\n}\n\nexport type DatasetWriteQuality =\n { inputRows: number; droppedRows: number } | { kind: \"writer-input-complete\" };\n\nfunction provenanceOptions(\n dataset: string,\n partition: Record<string, string>,\n schemaRevision: number,\n relativePath: string,\n coverage: { kind: \"prepared-date-range\"; column: string },\n quality?: DatasetWriteQuality,\n) {\n return { dataset, partition, schemaRevision, relativePath, coverage, quality };\n}\n\nexport const DATASETS_V3: Record<string, DatasetDef> = {\n spot: { subdir: \"spot\", partitionKeys: [\"ticker\", \"date\"], filename: \"data.parquet\" },\n enriched: { subdir: \"enriched\", partitionKeys: [\"ticker\"], filename: \"data.parquet\" },\n enriched_context: { subdir: \"enriched/context\", partitionKeys: [], filename: \"data.parquet\" },\n option_chain: {\n subdir: \"option_chain\",\n partitionKeys: [\"underlying\", \"date\"],\n filename: \"data.parquet\",\n },\n option_quote_minutes: {\n subdir: \"option_quote_minutes\",\n partitionKeys: [\"underlying\", \"date\"],\n filename: \"data.parquet\",\n },\n option_oi_daily: {\n subdir: \"option_oi_daily\",\n partitionKeys: [\"underlying\", \"date\"],\n filename: \"data.parquet\",\n },\n};\n\ntype BoundedProvenanceDatasetRegistry = typeof MARKET_DATASETS;\nconst BOUNDED_PROVENANCE_DATASETS: BoundedProvenanceDatasetRegistry = MARKET_DATASETS;\n\nfunction assertCanonicalPartitionDate(value: unknown, helper: string): asserts value is string {\n if (typeof value !== \"string\" || !/^\\d{4}-\\d{2}-\\d{2}$/.test(value)) {\n throw new TypeError(\n `${helper}: date must be an ISO calendar date (YYYY-MM-DD): ${JSON.stringify(value)}`,\n );\n }\n const parsed = new Date(`${value}T00:00:00.000Z`);\n if (!Number.isFinite(parsed.getTime()) || parsed.toISOString().slice(0, 10) !== value) {\n throw new TypeError(`${helper}: date is not a real calendar date: ${JSON.stringify(value)}`);\n }\n}\n\n// ------ Per-dataset write helpers ------\n//\n// Each helper reads its DatasetDef, composes the partitions map in the order\n// given by DatasetDef.partitionKeys, and delegates to writeParquetPartition\n// (the generic multi-level writer from parquet-writer.ts).\n//\n// Security note: writeParquetPartition applies a whitelist to every partition\n// key and value — /^[A-Za-z0-9._-]+$/ on values, /^[A-Za-z_][A-Za-z0-9_]*$/ on keys.\n// That is the deepest defense-in-depth layer against path traversal. Bounded\n// helpers additionally validate dates before composing paths or provenance.\n\nexport async function writeSpotPartition(\n conn: DuckDBConnection,\n args: {\n dataDir: string;\n ticker: string;\n date: string;\n selectQuery: string;\n compression?: string;\n quality?: DatasetWriteQuality;\n },\n): Promise<ParquetWriteResult> {\n assertCanonicalPartitionDate(args.date, \"writeSpotPartition\");\n const def = BOUNDED_PROVENANCE_DATASETS.spot;\n return writeParquetPartition(conn, {\n baseDir: path.join(resolveMarketDir(args.dataDir), def.subdir),\n partitions: { ticker: args.ticker, date: args.date }, // order matches def.partitionKeys\n selectQuery: args.selectQuery,\n compression: args.compression,\n filename: def.filename,\n provenance: provenanceOptions(\n \"spot\",\n { ticker: args.ticker, date: args.date },\n def.schemaRevision,\n path.posix.join(def.subdir, `ticker=${args.ticker}`, `date=${args.date}`, def.filename),\n { kind: \"prepared-date-range\", column: \"date\" },\n args.quality,\n ),\n });\n}\n\nexport async function writeChainPartition(\n conn: DuckDBConnection,\n args: {\n dataDir: string;\n underlying: string;\n date: string;\n selectQuery: string;\n compression?: string;\n quality?: DatasetWriteQuality;\n },\n): Promise<ParquetWriteResult> {\n assertCanonicalPartitionDate(args.date, \"writeChainPartition\");\n const def = BOUNDED_PROVENANCE_DATASETS.option_chain;\n return writeParquetPartition(conn, {\n baseDir: path.join(resolveMarketDir(args.dataDir), def.subdir),\n partitions: { underlying: args.underlying, date: args.date },\n selectQuery: args.selectQuery,\n compression: args.compression,\n filename: def.filename,\n provenance: provenanceOptions(\n \"option_chain\",\n { underlying: args.underlying, date: args.date },\n def.schemaRevision,\n path.posix.join(\n def.subdir,\n `underlying=${args.underlying}`,\n `date=${args.date}`,\n def.filename,\n ),\n { kind: \"prepared-date-range\", column: \"date\" },\n args.quality,\n ),\n });\n}\n\nexport async function writeQuoteMinutesPartition(\n conn: DuckDBConnection,\n args: {\n dataDir: string;\n underlying: string;\n date: string;\n selectQuery: string;\n compression?: string;\n quality?: DatasetWriteQuality;\n },\n): Promise<ParquetWriteResult> {\n assertCanonicalPartitionDate(args.date, \"writeQuoteMinutesPartition\");\n const def = BOUNDED_PROVENANCE_DATASETS.option_quote_minutes;\n // Sort rows by (ticker, time) before writing so DuckDB row groups in the\n // resulting parquet have tight min/max statistics on `ticker`. The\n // dominant read pattern is ticker-windowed scans across a time range\n // (querying a specific symbol across many minutes/days), so sorting\n // partitions by `(ticker, time)` lets DuckDB prune row groups by ticker\n // first and gives column-statistics benefits within each ticker.\n //\n // The previous `(time, ticker)` order favored single-minute multi-ticker\n // scans; that shape regresses slightly under the new sort, but it is no\n // longer the dominant consumer pattern.\n //\n // Wrapping the caller's selectQuery is safer than asking every caller to\n // remember to ORDER BY: writes go through one funnel.\n //\n // If you change this, also re-run `tools/sort-quote-parquet.mjs` to\n // re-sort existing partitions. The tool is idempotent (skips\n // already-sorted files via row-group ticker stats).\n const sortedSelect = `SELECT * FROM (${args.selectQuery}) AS q ORDER BY q.ticker, q.time`;\n return writeParquetPartition(conn, {\n baseDir: path.join(resolveMarketDir(args.dataDir), def.subdir),\n partitions: { underlying: args.underlying, date: args.date },\n selectQuery: sortedSelect,\n compression: args.compression,\n filename: def.filename,\n provenance: provenanceOptions(\n \"option_quote_minutes\",\n { underlying: args.underlying, date: args.date },\n def.schemaRevision,\n path.posix.join(\n def.subdir,\n `underlying=${args.underlying}`,\n `date=${args.date}`,\n def.filename,\n ),\n { kind: \"prepared-date-range\", column: \"date\" },\n args.quality,\n ),\n });\n}\n\nexport async function writeOiDailyPartition(\n conn: DuckDBConnection,\n args: {\n dataDir: string;\n underlying: string;\n date: string;\n selectQuery: string;\n compression?: string;\n quality?: DatasetWriteQuality;\n },\n): Promise<ParquetWriteResult> {\n assertCanonicalPartitionDate(args.date, \"writeOiDailyPartition\");\n const def = BOUNDED_PROVENANCE_DATASETS.option_oi_daily;\n // Sort rows by ticker before writing so DuckDB row groups carry tight\n // min/max statistics on `ticker` — the dominant read pattern is a\n // ticker-windowed scan within a (underlying, date) partition, matching the\n // quote store's (ticker, time) sort rationale (one value per ticker per day\n // here, so ticker alone is the sort key).\n const sortedSelect = `SELECT * FROM (${args.selectQuery}) AS q ORDER BY q.ticker`;\n return writeParquetPartition(conn, {\n baseDir: path.join(resolveMarketDir(args.dataDir), def.subdir),\n partitions: { underlying: args.underlying, date: args.date },\n selectQuery: sortedSelect,\n compression: args.compression,\n filename: def.filename,\n provenance: provenanceOptions(\n \"option_oi_daily\",\n { underlying: args.underlying, date: args.date },\n def.schemaRevision,\n path.posix.join(\n def.subdir,\n `underlying=${args.underlying}`,\n `date=${args.date}`,\n def.filename,\n ),\n { kind: \"prepared-date-range\", column: \"date\" },\n args.quality,\n ),\n });\n}\n\n/**\n * Backward-compatible whole-file writer for the legacy 3.3.x layout:\n * enriched/ticker=X/data.parquet.\n */\nexport async function writeEnrichedTickerFile(\n conn: DuckDBConnection,\n args: { dataDir: string; ticker: string; selectQuery: string; compression?: string },\n): Promise<{ rowCount: number }> {\n const def = DATASETS_V3.enriched;\n return writeParquetPartition(conn, {\n baseDir: path.join(resolveMarketDir(args.dataDir), def.subdir),\n partitions: { ticker: args.ticker },\n selectQuery: args.selectQuery,\n compression: args.compression,\n filename: def.filename,\n });\n}\n\n/**\n * Writes one bounded ticker/session slice:\n * enriched/ticker=X/date=Y/data.parquet.\n */\nexport async function writeEnrichedTickerPartition(\n conn: DuckDBConnection,\n args: {\n dataDir: string;\n ticker: string;\n date: string;\n selectQuery: string;\n compression?: string;\n quality?: DatasetWriteQuality;\n },\n): Promise<ParquetWriteResult> {\n assertCanonicalPartitionDate(args.date, \"writeEnrichedTickerPartition\");\n const def = BOUNDED_PROVENANCE_DATASETS.enriched;\n return writeParquetPartition(conn, {\n baseDir: path.join(resolveMarketDir(args.dataDir), def.subdir),\n partitions: { ticker: args.ticker, date: args.date },\n selectQuery: args.selectQuery,\n compression: args.compression,\n filename: def.filename,\n provenance: provenanceOptions(\n \"enriched\",\n { ticker: args.ticker, date: args.date },\n def.schemaRevision,\n path.posix.join(def.subdir, `ticker=${args.ticker}`, `date=${args.date}`, def.filename),\n { kind: \"prepared-date-range\", column: \"date\" },\n args.quality,\n ),\n });\n}\n\n/**\n * Backward-compatible whole-file writer for the legacy 3.3.x layout:\n * enriched/context/data.parquet.\n */\nexport async function writeEnrichedContext(\n conn: DuckDBConnection,\n args: { dataDir: string; selectQuery: string; compression?: string },\n): Promise<{ rowCount: number }> {\n const def = DATASETS_V3.enriched_context;\n return writeParquetAtomic(conn, {\n targetPath: path.join(resolveMarketDir(args.dataDir), def.subdir, def.filename),\n selectQuery: args.selectQuery,\n compression: args.compression,\n });\n}\n\n/**\n * Writes one bounded cross-ticker context session:\n * enriched/context/date=Y/data.parquet.\n */\nexport async function writeEnrichedContextPartition(\n conn: DuckDBConnection,\n args: {\n dataDir: string;\n date: string;\n selectQuery: string;\n compression?: string;\n quality?: DatasetWriteQuality;\n },\n): Promise<ParquetWriteResult> {\n assertCanonicalPartitionDate(args.date, \"writeEnrichedContextPartition\");\n const completeness = await conn.runAndReadAll(\n `SELECT date, Vol_Regime, Term_Structure_State, Trend_Direction,\n VIX_Spike_Pct, VIX_Gap_Pct\n FROM (${args.selectQuery}) AS bounded_enriched_context`,\n );\n const rows = completeness.getRows();\n if (rows.length !== 1) {\n throw new Error(\n `Enriched context partition ${args.date} must contain exactly one logical session row`,\n );\n }\n const [date, volRegime, termStructure, trendDirection, vixSpikePct, vixGapPct] = rows[0];\n if (String(date) !== args.date) {\n throw new Error(`Enriched context partition ${args.date} contains a different logical date`);\n }\n if (\n !Number.isInteger(volRegime) ||\n Number(volRegime) < 1 ||\n Number(volRegime) > 6 ||\n !Number.isInteger(termStructure) ||\n ![-1, 0, 1].includes(Number(termStructure)) ||\n typeof trendDirection !== \"string\" ||\n ![\"up\", \"down\", \"flat\"].includes(trendDirection) ||\n typeof vixSpikePct !== \"number\" ||\n !Number.isFinite(vixSpikePct) ||\n typeof vixGapPct !== \"number\" ||\n !Number.isFinite(vixGapPct)\n ) {\n throw new Error(\n `Enriched context partition ${args.date} is missing required VIX completeness fields`,\n );\n }\n const def = BOUNDED_PROVENANCE_DATASETS.enriched_context;\n return writeParquetPartition(conn, {\n baseDir: path.join(resolveMarketDir(args.dataDir), def.subdir),\n partitions: { date: args.date },\n selectQuery: args.selectQuery,\n compression: args.compression,\n filename: def.filename,\n provenance: provenanceOptions(\n \"enriched_context\",\n { date: args.date },\n def.schemaRevision,\n path.posix.join(def.subdir, `date=${args.date}`, def.filename),\n { kind: \"prepared-date-range\", column: \"date\" },\n args.quality,\n ),\n });\n}\n","/**\n * Data Root Directory Override\n *\n * When --data-root is set, shared data (market/, market-meta/, strategies/, blocks/)\n * lives under this path instead of alongside DuckDB files.\n *\n * Set via --data-root CLI flag or TRADEBLOCKS_DATA_ROOT env var.\n * When not set, getDataRoot() falls back to its argument (backward compat).\n *\n * Stored on globalThis so all bundle instances in the same process share state.\n * tsup duplicates this module across separate bundles; a module-scoped variable\n * would give each bundle its own _dataRoot, leaving one path correct (set by\n * the CLI parser) and the other null (a consumer reads its own copy and falls\n * back to the default → wrong path).\n *\n * Note: globalThis is per-realm. Consumers running this across Workers, VM\n * contexts, or sandboxed iframes will see the same divergence across realm\n * boundaries and must coordinate state another way.\n */\nimport path from \"node:path\";\n\nconst KEY = \"__tradeblocks_data_root__\";\ntype GlobalSlot = { [KEY]?: string | null };\n\n/**\n * The DuckDB files that live under a data root's `database/` subdirectory.\n * - `analytics` — the base DB hosting the `trades` schema (CSV-imported blocks)\n * - `market` — attached market data (`market.duckdb`)\n * - `backtests` — the backtest run-persistence index (`backtests.duckdb`)\n */\nexport type DbKind = \"analytics\" | \"market\" | \"backtests\";\n\n/**\n * Single source of truth for where a DuckDB file lives under a data root:\n * `<dataRoot>/database/<kind>.duckdb`. Every writer and reader across the fleet\n * (the engine's backtests-db resolver, the console reader, the calibration\n * probe) MUST resolve through this so the `database/` segment can never drift —\n * a missing segment silently splits reads from writes (runs succeed, the console\n * shows an empty history forever).\n */\nexport function resolveDbPath(dataRoot: string, kind: DbKind): string {\n return path.join(dataRoot, \"database\", `${kind}.duckdb`);\n}\n\nexport function setDataRoot(dir: string): void {\n (globalThis as GlobalSlot)[KEY] = dir;\n}\n\nexport function getDataRoot(fallback: string): string {\n return (globalThis as GlobalSlot)[KEY] ?? fallback;\n}\n\n/** Reset for testing. Not used in production. */\nexport function resetDataRoot(): void {\n (globalThis as GlobalSlot)[KEY] = null;\n}\n","/**\n * Parquet Writer Utility\n *\n * Provides atomic Parquet file writing via DuckDB's COPY TO command.\n * Used by all market data importers and enrichers when TRADEBLOCKS_PARQUET=true.\n *\n * Pattern: INSERT into staging temp table -> COPY TO Parquet -> DROP staging.\n * This ensures atomicity: if COPY TO fails, the original Parquet file is untouched.\n *\n * Exports:\n * - isParquetMode() - Check if Parquet write mode is enabled\n * - resolveMarketDir() - Centralized market directory path\n * - writeParquetAtomic() - Atomic single-file Parquet write via staging table\n * - writeParquetPartition() - Hive-partitioned write. Two overloads:\n * (a) legacy { baseDir, date, selectQuery } → baseDir/date=Y/data.parquet\n * (b) generic { baseDir, partitions: {...}, ... } → baseDir/k1=v1/k2=v2/.../data.parquet\n */\n\nimport type { DuckDBConnection } from \"@duckdb/node-api\";\nimport { createHash } from \"node:crypto\";\nimport { createReadStream, existsSync } from \"node:fs\";\nimport * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport type {\n ExactFileFingerprint,\n LogicalCoverage,\n PartitionQualityCounts,\n StoredPartitionCommit,\n} from \"../market/provenance/partition-commit-store.ts\";\nimport {\n PartitionFilePublicationError,\n assertCanonicalParquetSchema,\n} from \"../market/provenance/partition-commit-store.ts\";\nimport {\n activePartitionCommitAttempt,\n capturePartitionCommitReceipt,\n} from \"../market/provenance/partition-commit-attempt.ts\";\nimport { canonicalJsonBytes } from \"../market/provenance/canonical-json.ts\";\nexport { resolveMarketDir } from \"./market-datasets.ts\";\n\n// ---------------------------------------------------------------------------\n// Parquet mode detection\n// ---------------------------------------------------------------------------\n\n/**\n * Check if Parquet write mode is enabled.\n * Reads process.env.TRADEBLOCKS_PARQUET on each call for testability.\n *\n * @returns true when TRADEBLOCKS_PARQUET === 'true', false otherwise\n */\nexport function isParquetMode(): boolean {\n return process.env.TRADEBLOCKS_PARQUET === \"true\";\n}\n\n// ---------------------------------------------------------------------------\n// Atomic Parquet write\n// ---------------------------------------------------------------------------\n\nexport interface WriteParquetAtomicOpts {\n /** Target Parquet file path (e.g., '{dataDir}/market/daily.parquet') */\n targetPath: string;\n /** SELECT query that produces the final dataset */\n selectQuery: string;\n /** Temp table name (default: _staging_{Date.now()}) */\n stagingName?: string;\n /** Parquet compression codec (default: 'ZSTD') */\n compression?: string;\n /** Optional exact-byte partition provenance. Omit for legacy behavior. */\n provenance?: WriteParquetProvenanceOpts;\n}\n\nexport interface WriteParquetProvenanceOpts {\n dataset: string;\n partition: Record<string, string>;\n schemaRevision: number;\n /** Stable path relative to the canonical market directory. */\n relativePath: string;\n /** Coverage is measured from the completed Parquet bytes, never staging state. */\n coverage: { kind: \"prepared-date-range\"; column: string };\n /** Required inside a provenance attempt; omitted legacy writes remain supported. */\n quality?: { inputRows: number; droppedRows: number } | { kind: \"writer-input-complete\" };\n}\n\nexport interface ParquetWriteResult {\n rowCount: number;\n /** Additive writer-level evidence; store facades intentionally strip this field. */\n provenance?: StoredPartitionCommit;\n}\n\nfunction captureWriteProvenance(\n provenance: WriteParquetProvenanceOpts | undefined,\n): WriteParquetProvenanceOpts | undefined {\n if (!provenance) return undefined;\n const captured = {\n dataset: provenance.dataset,\n partition: provenance.partition,\n schemaRevision: provenance.schemaRevision,\n relativePath: provenance.relativePath,\n coverage: provenance.coverage,\n ...(provenance.quality === undefined ? {} : { quality: provenance.quality }),\n };\n return JSON.parse(canonicalJsonBytes(captured).toString(\"utf8\")) as WriteParquetProvenanceOpts;\n}\n\n/**\n * The Parquet rename succeeded but the immutable receipt/head update failed.\n * The target is intentionally left in place and must be reconciled before a\n * manifest can treat it as committed.\n */\nexport class ParquetProvenanceOrphanError extends Error {\n readonly targetPath: string;\n readonly file: ExactFileFingerprint;\n\n constructor(targetPath: string, file: ExactFileFingerprint, cause: unknown) {\n super(`Parquet data committed without provenance receipt: ${targetPath}`, { cause });\n this.name = \"ParquetProvenanceOrphanError\";\n this.targetPath = targetPath;\n this.file = file;\n }\n}\n\n/** An active commit attempt encountered a write with no registered receipt shape. */\nexport class UnmanifestedParquetWriteError extends Error {\n readonly targetPath: string;\n\n constructor(targetPath: string) {\n super(`Active partition commit attempt refuses an unregistered Parquet write: ${targetPath}`);\n this.name = \"UnmanifestedParquetWriteError\";\n this.targetPath = targetPath;\n }\n}\n\nasync function exactFileFingerprint(filePath: string, rows: number): Promise<ExactFileFingerprint> {\n const hash = createHash(\"sha256\");\n let bytes = 0;\n for await (const chunk of createReadStream(filePath)) {\n const buffer = chunk as Buffer;\n bytes += buffer.byteLength;\n hash.update(buffer);\n }\n return { address: `sha256:${hash.digest(\"hex\")}`, bytes, rows };\n}\n\nfunction escapeSqlLiteral(value: string): string {\n return value.replaceAll(\"'\", \"''\");\n}\n\nconst MIN_QUOTE_PARTITION_ROW_FRACTION = 0.5;\n\nclass QuotePartitionShrinkError extends Error {\n constructor(partition: Record<string, string>, existing: number, candidate: number) {\n super(\n `Quote partition shrink refused: underlying=${partition.underlying}/date=${partition.date}; ` +\n `existing=${existing}, candidate=${candidate}, threshold=${MIN_QUOTE_PARTITION_ROW_FRACTION}`,\n );\n this.name = \"QuotePartitionShrinkError\";\n }\n}\n\nasync function assertQuotePartitionRowCount(\n conn: DuckDBConnection,\n targetPath: string,\n provenance: WriteParquetProvenanceOpts | undefined,\n candidate: number,\n): Promise<void> {\n // Canonical quote writes carry this dataset identity even outside a provenance attempt.\n if (provenance?.dataset !== \"option_quote_minutes\" || !existsSync(targetPath)) return;\n const reader = await conn.runAndReadAll(\n `SELECT COUNT(*) FROM read_parquet('${escapeSqlLiteral(targetPath)}', hive_partitioning=false)`,\n );\n const existing = Number(reader.getRows()[0][0]);\n if (candidate < existing * MIN_QUOTE_PARTITION_ROW_FRACTION) {\n throw new QuotePartitionShrinkError(provenance.partition, existing, candidate);\n }\n}\n\nasync function inspectPreparedParquet(\n conn: DuckDBConnection,\n preparedPath: string,\n coverage: WriteParquetProvenanceOpts[\"coverage\"],\n): Promise<{ rowCount: number; coverage: LogicalCoverage }> {\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(coverage.column)) {\n throw new TypeError(`Unsafe provenance coverage column: ${JSON.stringify(coverage.column)}`);\n }\n // Never let Hive path keys synthesize/override the stored date column. The\n // coverage proof must inspect exact file content, not its destination name.\n const source = `read_parquet('${escapeSqlLiteral(preparedPath)}', hive_partitioning=false)`;\n const reader = await conn.runAndReadAll(\n `SELECT COUNT(*)::BIGINT,\n COUNT(\"${coverage.column}\")::BIGINT,\n MIN(CAST(\"${coverage.column}\" AS VARCHAR)),\n MAX(CAST(\"${coverage.column}\" AS VARCHAR))\n FROM ${source}`,\n );\n const row = reader.getRows()[0];\n const rowCount = Number(row[0]);\n const coveredRows = Number(row[1]);\n if (!Number.isSafeInteger(rowCount) || rowCount < 0 || !Number.isSafeInteger(coveredRows)) {\n throw new Error(\"Prepared Parquet returned an invalid row count\");\n }\n if (rowCount === 0) {\n if (coveredRows !== 0 || row[2] != null || row[3] != null) {\n throw new Error(\"Empty prepared Parquet returned inconsistent logical coverage\");\n }\n return { rowCount, coverage: { kind: \"empty\" } };\n }\n if (coveredRows !== rowCount || row[2] == null || row[3] == null) {\n throw new Error(\n `Prepared Parquet contains NULL or incomplete logical coverage in ${coverage.column}`,\n );\n }\n return {\n rowCount,\n coverage: { kind: \"date-range\", from: String(row[2]), through: String(row[3]) },\n };\n}\n\nasync function syncFile(filePath: string): Promise<void> {\n const handle = await fs.open(filePath, \"r\");\n try {\n await handle.sync();\n } finally {\n await handle.close();\n }\n}\n\nasync function syncDirectory(directory: string): Promise<void> {\n const handle = await fs.open(directory, \"r\");\n try {\n await handle.sync();\n } finally {\n await handle.close();\n }\n}\n\nfunction resolveQuality(\n rowCount: number,\n quality: WriteParquetProvenanceOpts[\"quality\"],\n): PartitionQualityCounts {\n if (!quality) {\n throw new Error(\"Partition provenance requires explicit inputRows and droppedRows\");\n }\n if (\"kind\" in quality) {\n return { inputRows: rowCount, writtenRows: rowCount, droppedRows: 0 };\n }\n if (\n !Number.isSafeInteger(quality.inputRows) ||\n !Number.isSafeInteger(quality.droppedRows) ||\n quality.inputRows < 0 ||\n quality.droppedRows < 0 ||\n quality.inputRows !== rowCount + quality.droppedRows\n ) {\n throw new Error(\n `Partition provenance quality must satisfy inputRows (${quality.inputRows}) = writtenRows (${rowCount}) + droppedRows (${quality.droppedRows})`,\n );\n }\n return {\n inputRows: quality.inputRows,\n writtenRows: rowCount,\n droppedRows: quality.droppedRows,\n };\n}\n\n/**\n * Atomic single-file Parquet write via DuckDB staging table.\n *\n * 1. CREATE TEMP TABLE {staging} AS {selectQuery}\n * 2. mkdir -p parent directory\n * 3. COPY {staging} TO '{targetPath}' (FORMAT PARQUET, COMPRESSION {compression})\n * 4. COUNT(*) for rowCount\n * 5. DROP staging in finally block\n *\n * Path-traversal mitigation: targetPath is always constructed by callers via\n * path.join(dataDir, 'market', ...) with no user-supplied path components.\n * Identifier-injection mitigation: staging table names use Date.now() — no user input.\n *\n * @param conn - Active DuckDB connection\n * @param opts - Write options\n * @returns Object with rowCount of written rows\n */\nexport async function writeParquetAtomic(\n conn: DuckDBConnection,\n opts: WriteParquetAtomicOpts,\n): Promise<ParquetWriteResult> {\n const {\n targetPath,\n selectQuery,\n stagingName = `_staging_${Date.now()}`,\n compression = \"ZSTD\",\n provenance: callerProvenance,\n } = opts;\n const provenance = captureWriteProvenance(callerProvenance);\n const provenanceAttempt = activePartitionCommitAttempt();\n if (provenanceAttempt && !provenance) throw new UnmanifestedParquetWriteError(targetPath);\n\n // Write to a temp sibling path, then atomic-rename into place. DuckDB's\n // COPY ... TO 'data.parquet' writes directly to the target — concurrent\n // readers (e.g. createMarketParquetViews globbing the archive) can observe\n // the file as empty / truncated / missing during the write. fs.rename is\n // atomic on local filesystems (APFS, ext4), so after this block a reader\n // either sees the old file or the new file, never a partially-written or\n // absent one. The temp name ends in `.tmp-PID-TS` (not `.parquet`) so\n // `**/data.parquet` and `**/*.parquet` globs both skip it.\n const tempPath = `${targetPath}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n try {\n // Stage data into a temp table\n await conn.run(`CREATE TEMP TABLE \"${stagingName}\" AS ${selectQuery}`);\n\n // Ensure parent directory exists\n await fs.mkdir(path.dirname(targetPath), { recursive: true });\n\n // Write to sidecar temp path\n await conn.run(\n `COPY \"${stagingName}\" TO '${tempPath}' (FORMAT PARQUET, COMPRESSION ${compression})`,\n );\n\n // Inside a partition commit attempt the completed temp sibling must\n // already match the canonical dataset schema before any fingerprint,\n // receipt, event, or install step can observe it.\n if (provenanceAttempt && provenance) {\n await assertCanonicalParquetSchema(conn, tempPath, provenance.dataset);\n }\n\n // Re-open the exact completed bytes. Counts and coverage must describe the\n // file being installed, not mutable staging state that merely preceded it.\n const inspected = provenanceAttempt\n ? await inspectPreparedParquet(conn, tempPath, provenance!.coverage)\n : undefined;\n const rowCount = inspected\n ? inspected.rowCount\n : Number(\n (\n await conn.runAndReadAll(`SELECT COUNT(*)::INTEGER AS cnt FROM \"${stagingName}\"`)\n ).getRows()[0][0],\n );\n await assertQuotePartitionRowCount(conn, targetPath, provenance, rowCount);\n const logicalCoverage = inspected?.coverage;\n const quality = provenanceAttempt ? resolveQuality(rowCount, provenance!.quality) : undefined;\n const fingerprint = provenanceAttempt\n ? await exactFileFingerprint(tempPath, rowCount)\n : undefined;\n\n if (provenance && provenanceAttempt && fingerprint && logicalCoverage && quality) {\n try {\n const stored = await provenanceAttempt.recorder.publishFileCommit({\n dataset: provenance.dataset,\n partition: provenance.partition,\n schemaRevision: provenance.schemaRevision,\n relativePath: provenance.relativePath,\n coverage: logicalCoverage,\n quality,\n file: fingerprint,\n preparedPath: tempPath,\n expectedTargetPath: targetPath,\n });\n capturePartitionCommitReceipt(stored);\n return { rowCount, provenance: stored };\n } catch (error) {\n if (error instanceof PartitionFilePublicationError) {\n throw new ParquetProvenanceOrphanError(targetPath, fingerprint, error);\n }\n throw error;\n }\n }\n\n await syncFile(tempPath);\n await syncDirectory(path.dirname(tempPath));\n await fs.rename(tempPath, targetPath);\n await syncDirectory(path.dirname(targetPath));\n\n return { rowCount };\n } catch (writeErr) {\n // Clean up sidecar on failure so the next attempt starts fresh\n try {\n await fs.unlink(tempPath);\n } catch {\n /* may not exist */\n }\n throw writeErr;\n } finally {\n // Always clean up staging table\n try {\n await conn.run(`DROP TABLE IF EXISTS \"${stagingName}\"`);\n } catch {\n // Non-fatal: table may not exist if creation failed\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Hive-partitioned Parquet write\n// ---------------------------------------------------------------------------\n\nexport interface WriteParquetPartitionOpts {\n /** Base directory for Hive partitions (e.g., '{dataDir}/market/intraday') */\n baseDir: string;\n /** Partition date (e.g., '2025-01-06') */\n date: string;\n /** SELECT query that produces rows for this date */\n selectQuery: string;\n /** Parquet compression codec (default: 'ZSTD') */\n compression?: string;\n provenance?: WriteParquetProvenanceOpts;\n}\n\n/**\n * Generic multi-level Hive partition writer options.\n *\n * Insertion order of `partitions` determines the Hive directory component order.\n * ES2015 guarantees string-keyed object insertion order is preserved by `Object.entries`.\n *\n * Examples:\n * { partitions: { ticker: 'SPX', date: '2025-01-06' } }\n * → baseDir/ticker=SPX/date=2025-01-06/data.parquet\n * { partitions: { underlying: 'SPX', date: '2025-01-06' } }\n * → baseDir/underlying=SPX/date=2025-01-06/data.parquet\n * { partitions: { ticker: 'VIX' } }\n * → baseDir/ticker=VIX/data.parquet\n * { partitions: {} }\n * → baseDir/data.parquet (callers that need this path should prefer writeParquetAtomic)\n */\nexport interface WriteParquetPartitionOptsV3 {\n baseDir: string;\n /** Key=value pairs composed in insertion order into Hive directory segments. */\n partitions: Record<string, string>;\n selectQuery: string;\n compression?: string;\n /** Defaults to 'data.parquet'. */\n filename?: string;\n provenance?: WriteParquetProvenanceOpts;\n}\n\n// Partition-value whitelist — deepest defense-in-depth boundary against path\n// traversal. Allows uppercase/lowercase alnum, dot, underscore, hyphen.\n// Rejects / \\ .. null whitespace and newlines. Zod schemas and the ticker\n// registry also validate upstream.\nconst PARTITION_VALUE_RE = /^[A-Za-z0-9._-]+$/;\n// Partition-key whitelist — keys become `key=` prefix in directory names.\n// Must start with letter or underscore (no leading digit), then alnum/underscore.\nconst PARTITION_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\n/**\n * Write a single Hive partition to the correct directory layout.\n *\n * Two supported shapes (via TypeScript overloads):\n * 1. Generic multi-level:\n * writeParquetPartition(conn, { baseDir, partitions: {ticker,date}, selectQuery })\n * → baseDir/ticker=X/date=Y/data.parquet\n * 2. Legacy single-{date} shim (retained for existing callers):\n * writeParquetPartition(conn, { baseDir, date, selectQuery })\n * → baseDir/date=Y/data.parquet (byte-identical to historical behavior)\n *\n * Overwrites existing partition file (idempotent — safe to re-run).\n *\n * Security: partition keys and values are validated against strict whitelists\n * BEFORE any filesystem operation. Unsafe input throws immediately.\n *\n * @param conn - Active DuckDB connection\n * @param opts - Partition write options (either shape)\n * @returns Object with rowCount of written rows\n */\n// Overload: generic multi-level signature\nexport function writeParquetPartition(\n conn: DuckDBConnection,\n opts: WriteParquetPartitionOptsV3,\n): Promise<ParquetWriteResult>;\n// Overload: legacy single-{date} signature\nexport function writeParquetPartition(\n conn: DuckDBConnection,\n opts: WriteParquetPartitionOpts,\n): Promise<ParquetWriteResult>;\n// Implementation\nexport async function writeParquetPartition(\n conn: DuckDBConnection,\n opts: WriteParquetPartitionOpts | WriteParquetPartitionOptsV3,\n): Promise<ParquetWriteResult> {\n // Runtime dispatch — this boolean is load-bearing.\n // The legacy shape has `date` but no `partitions`; the generic shape has `partitions`.\n const isLegacy = \"date\" in opts && !(\"partitions\" in opts);\n const partitions: Record<string, string> = isLegacy\n ? { date: (opts as WriteParquetPartitionOpts).date }\n : (opts as WriteParquetPartitionOptsV3).partitions;\n const filename = isLegacy\n ? \"data.parquet\"\n : ((opts as WriteParquetPartitionOptsV3).filename ?? \"data.parquet\");\n\n // Path-traversal mitigation: whitelist every partition key and value BEFORE\n // composing any path. Reject unsafe input (separators, whitespace, nulls).\n for (const [k, v] of Object.entries(partitions)) {\n if (!PARTITION_KEY_RE.test(k)) {\n throw new Error(`writeParquetPartition: unsafe partition key: ${JSON.stringify(k)}`);\n }\n if (!PARTITION_VALUE_RE.test(v)) {\n throw new Error(\n `writeParquetPartition: unsafe partition value for ${k}: ${JSON.stringify(v)}`,\n );\n }\n }\n\n // Preserve insertion order (ES2015 guarantees for string keys).\n const partitionSegments = Object.entries(partitions).map(([k, v]) => `${k}=${v}`);\n const targetPath = path.join(opts.baseDir, ...partitionSegments, filename);\n\n // writeParquetAtomic (existing, unchanged) handles: staging table → mkdir -p\n // (arbitrary depth) → COPY TO → rowCount → cleanup in finally.\n return writeParquetAtomic(conn, {\n targetPath,\n selectQuery: opts.selectQuery,\n compression: opts.compression,\n provenance: opts.provenance,\n });\n}\n","/**\n * Zod schemas for the ticker registry.\n *\n * Applied at three trust boundaries (defense in depth per RESEARCH.md Pitfall 3):\n * 1. MCP tool input boundary (schemas exported here, consumed by src/tools/tickers.ts in Plan 05)\n * 2. Registry constructor / register (registry.ts applies the same regex)\n * 3. Writer partition-value whitelist (src/db/parquet-writer.ts — Plan 03)\n */\nimport { z } from \"zod\";\n\n/**\n * Whitelist for ticker-like strings. Must START with an uppercase letter\n * (forbids \"..\" and other digit/punctuation-only inputs from validating).\n *\n * Accepts after the leading letter: uppercase A-Z, digits 0-9, and `^ _ -`\n * which appear in a handful of real-world option roots and continuous-futures\n * symbols. Forbids `.` (and therefore `..`), `/`, `\\`, whitespace, null bytes,\n * newlines, and any other non-filesystem-safe characters.\n */\nexport const TICKER_RE = /^[A-Z][A-Z0-9^_-]*$/;\n\nexport const UnderlyingsFileSchema = z.object({\n version: z.literal(1),\n underlyings: z.array(\n z.object({\n underlying: z.string().min(1).max(16).regex(TICKER_RE),\n roots: z.array(z.string().min(1).max(16).regex(TICKER_RE)).min(1).max(32),\n }),\n ),\n});\n\n// MCP tool input schemas (consumed by src/tools/tickers.ts in Plan 05).\nexport const registerUnderlyingSchema = z.object({\n underlying: z\n .string()\n .min(1)\n .max(16)\n .regex(TICKER_RE)\n .describe(\"Canonical underlying symbol, e.g. SPX\"),\n roots: z\n .array(z.string().min(1).max(16).regex(TICKER_RE))\n .min(1)\n .max(32)\n .describe(\"OCC roots that resolve to this underlying, e.g. ['SPX','SPXW','SPXQ']\"),\n});\n\nexport const unregisterUnderlyingSchema = z.object({\n underlying: z\n .string()\n .min(1)\n .max(16)\n .regex(TICKER_RE)\n .describe(\"Underlying to remove. Bundled defaults cannot be removed.\"),\n});\n\nexport const listUnderlyingsSchema = z.object({});\n\nexport const resolveRootSchema = z.object({\n input: z\n .string()\n .min(1)\n .max(32)\n .describe(\"Bare root ('SPXW') or full OCC ticker ('SPXW251219C05000000')\"),\n});\n","import type { DuckDBConnection } from \"@duckdb/node-api\";\nimport { constants } from \"node:fs\";\nimport * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { canonicalJson, type CanonicalJsonAddress, type Sha256Address } from \"./canonical-json.ts\";\nimport type { ContentObjectStore, PutContentObjectResult } from \"./content-object-store.ts\";\nimport {\n type CutoffManifestV1,\n type InputClosureObservationV1,\n type InputResolverRegistryV1,\n type ManifestInputResolver,\n type ManifestLeafReferenceV1,\n type ManifestResolution,\n type MaterializedResolverClassV1,\n type PartitionedResolverClassV1,\n proveCutoffManifestPrefix,\n publishCutoffManifest,\n publishInputResolverRegistry,\n publishMissingProbeEvidence,\n publishSemanticInputLeaf,\n restrictInputClosureDescriptor,\n verifyCutoffManifest,\n verifyInputClosure,\n verifyInputResolverRegistry,\n verifySemanticInputLeaf,\n} from \"./content-manifest.ts\";\nimport {\n MARKET_DATASETS,\n isRealMarketSessionDate,\n type BoundedMarketDatasetDefinition,\n} from \"./dataset-registry.ts\";\nimport {\n FilePartitionCommitStore,\n INTERNAL_HISTORICAL_PARTITION_ADOPTION,\n type StoredPartitionCommit,\n} from \"./partition-commit-store.ts\";\nimport {\n XNYS_SESSION_CALENDAR_REVISION,\n enumerateXnysSessions,\n isXnysSessionDate,\n} from \"./xnys-session-calendar.ts\";\nimport { verifyCanonicalRefreshCompletion } from \"./refresh-completion.ts\";\nimport { publishCanonicalRateSlice, type CanonicalRateDataClass } from \"./rate-slices.ts\";\n\nexport const CANONICAL_MARKET_RESOLVER_REVISION = \"tradeblocks-market-resolver-v1\" as const;\nexport const BLACKOUT_SLICE_KIND = \"tradeblocks.market-data.blackout-slice\" as const;\nexport const BLACKOUT_SLICE_VERSION = 1 as const;\n\nexport interface CanonicalControlIdentity {\n dataClass: string;\n role: string;\n relativePath: string;\n}\n\nexport interface PublishCanonicalMarketRegistryInput {\n /** Engine-observed data-root-relative control paths. */\n controlFiles?: readonly string[];\n}\n\nexport interface AdoptCanonicalHistoricalClosureResult {\n readonly closure: CanonicalJsonAddress;\n readonly completeThrough: string;\n readonly receipts: readonly StoredPartitionCommit[];\n}\n\nfunction compareCodePoints(left: string, right: string): number {\n const leftPoints = Array.from(left, (character) => character.codePointAt(0) as number);\n const rightPoints = Array.from(right, (character) => character.codePointAt(0) as number);\n const length = Math.min(leftPoints.length, rightPoints.length);\n for (let index = 0; index < length; index += 1) {\n if (leftPoints[index] !== rightPoints[index]) return leftPoints[index] - rightPoints[index];\n }\n return leftPoints.length - rightPoints.length;\n}\n\nexport function canonicalControlIdentity(relativePath: string): CanonicalControlIdentity {\n const normalized = relativePath.normalize(\"NFC\").replaceAll(\"\\\\\", \"/\");\n const match = /^blackouts\\/([A-Za-z_][A-Za-z0-9._-]*)\\.json$/.exec(normalized);\n if (!match) {\n throw new TypeError(\n `Unsupported canonical market control path: ${JSON.stringify(relativePath)}`,\n );\n }\n const role = `blackout.${match[1]}`;\n return Object.freeze({ dataClass: role, role, relativePath: normalized });\n}\n\nfunction canonicalPartitionedClasses(): PartitionedResolverClassV1[] {\n return Object.entries(MARKET_DATASETS).flatMap(([dataset, candidate]) => {\n if (candidate.provenance.kind !== \"bounded-session\") return [];\n const definition = candidate as BoundedMarketDatasetDefinition;\n return [\n {\n kind: \"partitioned\" as const,\n dataClass: dataset,\n dataset,\n selectorKeys: definition.partitionKeys,\n sessionKey: definition.provenance.sessionKey,\n pathPrefix: definition.subdir,\n filename: definition.filename,\n supportedSchemaRevisions: [definition.schemaRevision],\n resolverRevision: CANONICAL_MARKET_RESOLVER_REVISION,\n calendarRevision: XNYS_SESSION_CALENDAR_REVISION,\n },\n ];\n });\n}\n\nfunction canonicalMaterializedClasses(): MaterializedResolverClassV1[] {\n return ([\"sofr_rates\", \"treasury_rates\"] as const).map((dataClass) => ({\n kind: \"materialized\",\n dataClass,\n selectorKeys: [\"date\"],\n sessionKey: \"date\",\n supportedSchemaRevisions: [1],\n resolverRevision: CANONICAL_MARKET_RESOLVER_REVISION,\n calendarRevision: XNYS_SESSION_CALENDAR_REVISION,\n }));\n}\n\nfunction canonicalRegistryClasses(controls: readonly CanonicalControlIdentity[]) {\n return [\n ...canonicalPartitionedClasses(),\n ...canonicalMaterializedClasses(),\n ...controls.map((control) => ({\n kind: \"static\" as const,\n ...control,\n supportedSchemaRevisions: [1],\n resolverRevision: CANONICAL_MARKET_RESOLVER_REVISION,\n })),\n ].sort((left, right) => {\n const byClass = compareCodePoints(left.dataClass, right.dataClass);\n return byClass === 0 ? compareCodePoints(left.kind, right.kind) : byClass;\n });\n}\n\nfunction validateCanonicalRegistry(registry: InputResolverRegistryV1): void {\n const controls = registry.classes\n .filter((entry) => entry.kind === \"static\")\n .map((entry) => canonicalControlIdentity(entry.relativePath))\n .sort((left, right) => compareCodePoints(left.dataClass, right.dataClass));\n const expectedRevision = `${CANONICAL_MARKET_RESOLVER_REVISION}.${XNYS_SESSION_CALENDAR_REVISION}`;\n if (\n registry.revision !== expectedRevision ||\n canonicalJson(registry.classes) !== canonicalJson(canonicalRegistryClasses(controls))\n ) {\n throw new Error(\"Input resolver registry is not the canonical producer registry\");\n }\n}\n\nexport async function publishCanonicalMarketResolverRegistry(\n objects: ContentObjectStore,\n input: PublishCanonicalMarketRegistryInput = {},\n): Promise<PutContentObjectResult<InputResolverRegistryV1>> {\n const controls = [\n ...new Map(\n (input.controlFiles ?? []).map((controlPath) => {\n const identity = canonicalControlIdentity(controlPath);\n return [identity.relativePath, identity] as const;\n }),\n ).values(),\n ].sort((left, right) => compareCodePoints(left.dataClass, right.dataClass));\n return publishInputResolverRegistry(objects, {\n revision: `${CANONICAL_MARKET_RESOLVER_REVISION}.${XNYS_SESSION_CALENDAR_REVISION}`,\n classes: canonicalRegistryClasses(controls),\n });\n}\n\n/**\n * Bring existing canonical-layout Parquet bytes under producer authority for\n * one authenticated input closure. The caller cannot nominate arbitrary files:\n * identities are derived only from the verified canonical registry + closure,\n * and the store independently validates schema, partition values, coverage,\n * row count, inode stability, and exact bytes before publishing each receipt.\n *\n * This is the bounded migration seam for data that predates receipt stamping.\n * It deliberately does not mint refresh-completion authority or a cutoff; a\n * normal canonical refresh must still finalize the requested tail session.\n */\nexport async function adoptCanonicalHistoricalInputClosure(\n partitions: FilePartitionCommitStore,\n conn: DuckDBConnection,\n closureAddress: CanonicalJsonAddress,\n completeThrough: string,\n): Promise<AdoptCanonicalHistoricalClosureResult> {\n if (!isXnysSessionDate(completeThrough)) {\n throw new Error(\n `Historical adoption cutoff is not a supported XNYS session: ${completeThrough}`,\n );\n }\n const verifiedClosure = await verifyInputClosure(partitions.objects, closureAddress);\n const registryObject = await verifyInputResolverRegistry(\n partitions.objects,\n verifiedClosure.value.registry,\n );\n validateCanonicalRegistry(registryObject.value);\n const closure = restrictInputClosureDescriptor(verifiedClosure.value, completeThrough);\n const identities = new Map<string, { dataset: string; partition: Record<string, string> }>();\n\n for (const observation of closure.observations) {\n if (observation.kind === \"unmanifestable\") {\n throw new Error(`Historical adoption closure is unmanifestable: ${observation.reasonCode}`);\n }\n if (observation.kind === \"control-file\") continue;\n if (\n (observation.kind === \"exact\" || observation.kind === \"missing-probe\") &&\n !isXnysSessionDate(observation.session)\n ) {\n throw new Error(\n `Historical adoption ${observation.kind} is not an XNYS session: ${observation.session}`,\n );\n }\n if (observation.kind === \"missing-probe\") {\n const resolverClass = registryObject.value.classes.find(\n (entry) => entry.dataClass === observation.dataClass,\n );\n if (!resolverClass || resolverClass.kind !== \"partitioned\") {\n throw new Error(\"Historical adoption missing-probe is not partition-backed\");\n }\n const inspected = await partitions.inspectPartition({\n dataset: resolverClass.dataset,\n partition: observation.selector,\n });\n if (inspected.status !== \"absent\") {\n throw new Error(\n `Historical adoption missing-probe is no longer absent: ${resolverClass.dataset} ${canonicalJson(observation.selector)} (${inspected.status})`,\n );\n }\n continue;\n }\n const resolverClass = requireCanonicalClass(registryObject.value, observation);\n if (resolverClass.kind !== \"partitioned\") continue;\n const sessions =\n observation.kind === \"exact\"\n ? [sessionFromObservation(observation) as string]\n : enumerateXnysSessions(observation.fromSession, observation.throughSession);\n for (const session of sessions) {\n const partition =\n observation.kind === \"exact\"\n ? { ...observation.selector }\n : { ...observation.selectorPrefix, [resolverClass.sessionKey]: session };\n const identity = { dataset: resolverClass.dataset, partition };\n identities.set(canonicalJson(identity), identity);\n }\n }\n\n const receipts: StoredPartitionCommit[] = [];\n for (const identity of [...identities.values()].sort((left, right) =>\n compareCodePoints(canonicalJson(left), canonicalJson(right)),\n )) {\n receipts.push(await partitions[INTERNAL_HISTORICAL_PARTITION_ADOPTION](conn, identity));\n }\n return Object.freeze({\n closure: verifiedClosure.address,\n completeThrough,\n receipts: Object.freeze(receipts),\n });\n}\n\nfunction requireCanonicalClass(\n registry: InputResolverRegistryV1,\n observation: Exclude<InputClosureObservationV1, { kind: \"unmanifestable\" }>,\n) {\n const resolverClass = registry.classes.find((entry) => entry.dataClass === observation.dataClass);\n if (!resolverClass) throw new Error(`Unknown canonical input class ${observation.dataClass}`);\n if (resolverClass.resolverRevision !== CANONICAL_MARKET_RESOLVER_REVISION) {\n throw new Error(`Unsupported resolver revision for ${observation.dataClass}`);\n }\n if (\n resolverClass.kind !== \"static\" &&\n resolverClass.calendarRevision !== XNYS_SESSION_CALENDAR_REVISION\n ) {\n throw new Error(`Unsupported calendar revision for ${observation.dataClass}`);\n }\n return resolverClass;\n}\n\nfunction partitionLeafReference(\n leaf: CanonicalJsonAddress,\n receipt: CanonicalJsonAddress,\n): ManifestLeafReferenceV1 {\n return { leaf, evidence: { kind: \"partition-receipt\", receipt } };\n}\n\nfunction sessionFromObservation(observation: InputClosureObservationV1): string | undefined {\n return observation.kind === \"exact\" || observation.kind === \"missing-probe\"\n ? observation.session\n : undefined;\n}\n\nasync function readCanonicalBlackoutSlice(\n objects: ContentObjectStore,\n dataRootDir: string,\n identity: CanonicalControlIdentity,\n completeThrough: string,\n) {\n const root = await fs.realpath(path.resolve(dataRootDir));\n const components = identity.relativePath.split(\"/\");\n let parent = root;\n for (const component of components.slice(0, -1)) {\n parent = path.join(parent, component);\n const stat = await fs.lstat(parent);\n if (!stat.isDirectory() || stat.isSymbolicLink()) {\n throw new Error(\"Canonical control parents must be real directories\");\n }\n }\n const realParent = await fs.realpath(parent);\n const containment = path.relative(root, realParent);\n if (\n containment === \"..\" ||\n containment.startsWith(`..${path.sep}`) ||\n path.isAbsolute(containment)\n ) {\n throw new Error(\"Canonical control path escapes the configured data root\");\n }\n const candidate = path.join(parent, components.at(-1) as string);\n const handle = await fs.open(\n candidate,\n constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK,\n );\n try {\n const before = await handle.stat({ bigint: true });\n if (!before.isFile() || before.nlink !== 1n) {\n throw new Error(\"Canonical control input must be a singly-linked regular file\");\n }\n const bytes = await handle.readFile();\n const after = await handle.stat({ bigint: true });\n if (\n !after.isFile() ||\n after.nlink !== 1n ||\n before.dev !== after.dev ||\n before.ino !== after.ino ||\n before.size !== after.size ||\n before.mtimeNs !== after.mtimeNs ||\n before.ctimeNs !== after.ctimeNs\n ) {\n throw new Error(\"Canonical control input changed while it was read\");\n }\n let revalidatedParent = root;\n for (const component of components.slice(0, -1)) {\n revalidatedParent = path.join(revalidatedParent, component);\n const stat = await fs.lstat(revalidatedParent);\n if (!stat.isDirectory() || stat.isSymbolicLink()) {\n throw new Error(\"Canonical control parent changed while it was read\");\n }\n }\n if ((await fs.realpath(revalidatedParent)) !== realParent) {\n throw new Error(\"Canonical control parent changed while it was read\");\n }\n const named = await fs.lstat(candidate, { bigint: true });\n if (\n !named.isFile() ||\n named.isSymbolicLink() ||\n named.nlink !== 1n ||\n named.dev !== after.dev ||\n named.ino !== after.ino ||\n named.size !== after.size ||\n named.mtimeNs !== after.mtimeNs ||\n named.ctimeNs !== after.ctimeNs\n ) {\n throw new Error(\"Canonical control input name changed while it was read\");\n }\n const parsed = JSON.parse(bytes.toString(\"utf8\")) as unknown;\n const dates = Array.isArray(parsed)\n ? parsed\n : parsed !== null && typeof parsed === \"object\" && !Array.isArray(parsed)\n ? (parsed as { dates?: unknown }).dates\n : undefined;\n if (!Array.isArray(dates)) throw new Error(\"Blackout control input has no dates array\");\n const normalized = dates.map((date, index) => {\n if (typeof date !== \"string\" || !isRealMarketSessionDate(date)) {\n throw new Error(`Blackout control date ${index} is invalid`);\n }\n return date.normalize(\"NFC\");\n });\n normalized.sort(compareCodePoints);\n const unique = normalized.filter(\n (date, index) => date <= completeThrough && (index === 0 || date !== normalized[index - 1]),\n );\n return objects.put({\n kind: BLACKOUT_SLICE_KIND,\n version: BLACKOUT_SLICE_VERSION,\n role: identity.role,\n dates: unique,\n });\n } finally {\n await handle.close();\n }\n}\n\nfunction normalizeBlackoutSlice(\n value: unknown,\n expectedRole: string,\n completeThrough: string,\n): {\n kind: typeof BLACKOUT_SLICE_KIND;\n version: typeof BLACKOUT_SLICE_VERSION;\n role: string;\n dates: string[];\n} {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n throw new Error(\"Blackout slice must be an object\");\n }\n const record = value as Record<string, unknown>;\n const keys = Object.keys(record).sort(compareCodePoints);\n if (canonicalJson(keys) !== canonicalJson([\"dates\", \"kind\", \"role\", \"version\"])) {\n throw new Error(\"Blackout slice has unknown or missing fields\");\n }\n if (\n record.kind !== BLACKOUT_SLICE_KIND ||\n record.version !== BLACKOUT_SLICE_VERSION ||\n record.role !== expectedRole ||\n !Array.isArray(record.dates)\n ) {\n throw new Error(\"Blackout slice identity is invalid\");\n }\n const dates = record.dates.map((date, index) => {\n if (typeof date !== \"string\" || !isRealMarketSessionDate(date) || date > completeThrough) {\n throw new Error(`Blackout slice date ${index} is invalid`);\n }\n return date.normalize(\"NFC\");\n });\n const sorted = [...dates].sort(compareCodePoints);\n if (canonicalJson(dates) !== canonicalJson(sorted) || new Set(dates).size !== dates.length) {\n throw new Error(\"Blackout slice dates are not normalized\");\n }\n return {\n kind: BLACKOUT_SLICE_KIND,\n version: BLACKOUT_SLICE_VERSION,\n role: expectedRole,\n dates,\n };\n}\n\n/**\n * Producer-owned resolver for the bounded market registry.\n *\n * Range completeness comes from XNYS session enumeration, never from the set\n * of files that happen to exist. Every expected partition must have a current\n * exact-byte authority tip before the resolver reports a complete horizon.\n */\nexport class CanonicalMarketInputResolver implements ManifestInputResolver {\n readonly dataRootDir: string;\n readonly partitions: FilePartitionCommitStore;\n\n constructor(partitions: FilePartitionCommitStore) {\n this.partitions = partitions;\n const marketRoot = path.resolve(partitions.marketRootDir);\n if (path.basename(marketRoot) !== \"market\") {\n throw new Error(\"Canonical market resolver requires a data-root/market authority store\");\n }\n this.dataRootDir = path.dirname(marketRoot);\n }\n\n private async resolvePartition(\n registryAddress: CanonicalJsonAddress,\n observation: Exclude<\n InputClosureObservationV1,\n { kind: \"control-file\" | \"unmanifestable\" | \"missing-probe\" }\n >,\n resolverClass: PartitionedResolverClassV1,\n partition: Record<string, string>,\n ): Promise<ManifestLeafReferenceV1> {\n const inspected = await this.partitions.inspectPartition({\n dataset: resolverClass.dataset,\n partition,\n });\n if (inspected.status !== \"match\") {\n throw new Error(\n `Canonical partition is not complete/current: ${resolverClass.dataset} ${JSON.stringify(partition)} (${inspected.status})`,\n );\n }\n const receipt = inspected.receipt.receipt;\n const session = partition[resolverClass.sessionKey];\n if (\n !resolverClass.supportedSchemaRevisions.includes(receipt.schemaRevision) ||\n receipt.file.rows <= 0 ||\n receipt.coverage.kind !== \"date-range\" ||\n receipt.coverage.from !== session ||\n receipt.coverage.through !== session ||\n receipt.quality.writtenRows !== receipt.file.rows ||\n receipt.quality.inputRows !== receipt.file.rows ||\n receipt.quality.droppedRows !== 0\n ) {\n throw new Error(\n `Canonical partition is not a complete zero-drop cutoff partition: ${resolverClass.dataset} ${JSON.stringify(partition)}`,\n );\n }\n const leaf = await publishSemanticInputLeaf(this.partitions.objects, {\n registry: registryAddress,\n observation,\n source: {\n kind: \"partition-projection\",\n dataset: receipt.dataset,\n partition: receipt.partition,\n relativePath: receipt.relativePath,\n session,\n schemaRevision: receipt.schemaRevision,\n coverage: receipt.coverage,\n quality: receipt.quality,\n file: receipt.file,\n },\n });\n return partitionLeafReference(leaf.address, inspected.receipt.address);\n }\n\n private async resolveMaterializedRate(\n registryAddress: CanonicalJsonAddress,\n observation: Extract<InputClosureObservationV1, { kind: \"exact\" | \"range\" }>,\n resolverClass: MaterializedResolverClassV1,\n selector: Record<string, string>,\n ): Promise<ManifestLeafReferenceV1> {\n const session = selector[resolverClass.sessionKey];\n const object = await publishCanonicalRateSlice(\n this.partitions.objects,\n resolverClass.dataClass as CanonicalRateDataClass,\n session,\n );\n const leaf = await publishSemanticInputLeaf(this.partitions.objects, {\n registry: registryAddress,\n observation,\n source: {\n kind: \"materialized-slice\",\n selector,\n session,\n schemaRevision: 1,\n object: { address: object.address, bytes: object.bytes },\n },\n });\n return {\n leaf: leaf.address,\n evidence: { kind: \"content-object\", object: object.address },\n };\n }\n\n async resolve(input: {\n registry: InputResolverRegistryV1;\n closure: import(\"./content-manifest.ts\").InputClosureDescriptorV1;\n observation: InputClosureObservationV1;\n dependency: CanonicalJsonAddress;\n completeThrough: string;\n }): Promise<ManifestResolution> {\n const { registry, observation, completeThrough } = input;\n if (observation.kind === \"unmanifestable\") {\n return { kind: \"unmanifestable\", reasonCode: observation.reasonCode };\n }\n try {\n validateCanonicalRegistry(registry);\n if (!isXnysSessionDate(completeThrough)) {\n return { kind: \"unresolved\", reasonCode: \"cutoff-not-xnys-session\" };\n }\n const resolverClass = requireCanonicalClass(registry, observation);\n if (observation.kind === \"control-file\") {\n if (resolverClass.kind !== \"static\") {\n return { kind: \"unmanifestable\", reasonCode: \"control-class-not-static\" };\n }\n const identity = canonicalControlIdentity(resolverClass.relativePath);\n if (identity.role !== observation.role || identity.role !== resolverClass.role) {\n return { kind: \"unmanifestable\", reasonCode: \"control-identity-mismatch\" };\n }\n const object = await readCanonicalBlackoutSlice(\n this.partitions.objects,\n this.dataRootDir,\n identity,\n completeThrough,\n );\n const leaf = await publishSemanticInputLeaf(this.partitions.objects, {\n registry: input.closure.registry,\n observation,\n source: {\n kind: \"control-file\",\n role: identity.role,\n relativePath: identity.relativePath,\n schemaRevision: 1,\n object: { address: object.address, bytes: object.bytes },\n },\n });\n return {\n kind: \"resolved\",\n completeThrough,\n entries: [\n {\n leaf: leaf.address,\n evidence: { kind: \"content-object\", object: object.address },\n },\n ],\n };\n }\n if (resolverClass.kind === \"static\") {\n return { kind: \"unmanifestable\", reasonCode: \"session-observation-class-is-static\" };\n }\n if (observation.kind === \"missing-probe\") {\n if (resolverClass.kind !== \"partitioned\") {\n return { kind: \"unmanifestable\", reasonCode: \"probe-class-not-partitioned\" };\n }\n if (!isXnysSessionDate(observation.session)) {\n return { kind: \"unmanifestable\", reasonCode: \"probe-not-xnys-session\" };\n }\n const inspected = await this.partitions.inspectPartition({\n dataset: resolverClass.dataset,\n partition: observation.selector,\n });\n if (inspected.status !== \"absent\") {\n return { kind: \"unresolved\", reasonCode: `probe-${inspected.status}` };\n }\n const evidence = await publishMissingProbeEvidence(this.partitions.objects, {\n registry: input.closure.registry,\n observation,\n completeThrough,\n });\n const leaf = await publishSemanticInputLeaf(this.partitions.objects, {\n registry: input.closure.registry,\n observation,\n source: { kind: \"missing-probe\", session: observation.session },\n });\n return {\n kind: \"resolved\",\n completeThrough,\n entries: [\n {\n leaf: leaf.address,\n evidence: { kind: \"absence-object\", object: evidence.address },\n },\n ],\n };\n }\n const sessions =\n observation.kind === \"exact\"\n ? [sessionFromObservation(observation) as string]\n : enumerateXnysSessions(observation.fromSession, observation.throughSession);\n if (sessions.length === 0) {\n return { kind: \"unresolved\", reasonCode: \"range-has-no-xnys-sessions\" };\n }\n const entries: ManifestLeafReferenceV1[] = [];\n for (const session of sessions) {\n if (!isXnysSessionDate(session)) {\n return { kind: \"unmanifestable\", reasonCode: \"exact-not-xnys-session\" };\n }\n const partition =\n observation.kind === \"exact\"\n ? observation.selector\n : { ...observation.selectorPrefix, [resolverClass.sessionKey]: session };\n entries.push(\n resolverClass.kind === \"partitioned\"\n ? await this.resolvePartition(\n input.closure.registry,\n observation,\n resolverClass,\n partition,\n )\n : await this.resolveMaterializedRate(\n input.closure.registry,\n observation,\n resolverClass,\n partition,\n ),\n );\n }\n return { kind: \"resolved\", completeThrough, entries };\n } catch (error) {\n return {\n kind: \"unresolved\",\n reasonCode: error instanceof Error ? error.message : \"canonical-resolution-failed\",\n };\n }\n }\n\n async projectStaticPrefix(input: {\n registry: InputResolverRegistryV1;\n registryAddress: CanonicalJsonAddress;\n dataClass: string;\n ancestorCompleteThrough: string;\n descendantCompleteThrough: string;\n descendantEntries: readonly ManifestLeafReferenceV1[];\n }): Promise<readonly ManifestLeafReferenceV1[]> {\n validateCanonicalRegistry(input.registry);\n const resolverClass = input.registry.classes.find(\n (entry) => entry.dataClass === input.dataClass,\n );\n if (!resolverClass || resolverClass.kind !== \"static\") {\n throw new Error(\"Canonical static prefix projection requires a static registry class\");\n }\n if (input.descendantEntries.length !== 1) {\n throw new Error(\"Canonical static prefix projection requires exactly one descendant leaf\");\n }\n const reference = input.descendantEntries[0];\n const leaf = await verifySemanticInputLeaf(this.partitions.objects, reference.leaf);\n if (\n leaf.value.registry !== input.registryAddress ||\n leaf.value.dataClass !== input.dataClass ||\n leaf.value.scope.kind !== \"static\" ||\n leaf.value.source.kind !== \"control-file\" ||\n reference.evidence.kind !== \"content-object\" ||\n reference.evidence.object !== leaf.value.source.object.address\n ) {\n throw new Error(\"Canonical static prefix projection received invalid descendant evidence\");\n }\n const descendantObject = await this.partitions.objects.get<unknown>(reference.evidence.object);\n const descendantSlice = normalizeBlackoutSlice(\n descendantObject,\n resolverClass.role,\n input.descendantCompleteThrough,\n );\n const projectedObject = await this.partitions.objects.put({\n ...descendantSlice,\n dates: descendantSlice.dates.filter((date) => date <= input.ancestorCompleteThrough),\n });\n const observation: InputClosureObservationV1 = {\n kind: \"control-file\",\n dataClass: input.dataClass,\n role: resolverClass.role,\n };\n const projectedLeaf = await publishSemanticInputLeaf(this.partitions.objects, {\n registry: input.registryAddress,\n observation,\n source: {\n ...leaf.value.source,\n object: { address: projectedObject.address, bytes: projectedObject.bytes },\n },\n });\n return [\n {\n leaf: projectedLeaf.address,\n evidence: { kind: \"content-object\", object: projectedObject.address },\n },\n ];\n }\n}\n\nexport async function finalizeCanonicalMarketDataCutoff(\n partitions: FilePartitionCommitStore,\n input: {\n closure: CanonicalJsonAddress;\n completeThrough: string;\n refreshCompletion: CanonicalJsonAddress;\n predecessor?: { manifest: CanonicalJsonAddress; aggregateRoot: Sha256Address };\n },\n): Promise<PutContentObjectResult<CutoffManifestV1>> {\n if (!isXnysSessionDate(input.completeThrough)) {\n throw new Error(`Canonical cutoff is not a supported XNYS session: ${input.completeThrough}`);\n }\n const completion = await verifyCanonicalRefreshCompletion(partitions, input.refreshCompletion);\n if (\n completion.value.plan.asOf !== input.completeThrough ||\n completion.value.closure !== input.closure\n ) {\n throw new Error(\"Canonical refresh completion does not authorize this closure and cutoff\");\n }\n const manifest = await publishCutoffManifest(partitions, {\n closure: input.closure,\n completeThrough: input.completeThrough,\n resolver: new CanonicalMarketInputResolver(partitions),\n refreshCompletion: completion.address,\n ...(input.predecessor ? { predecessor: input.predecessor } : {}),\n });\n await verifyCanonicalRefreshCompletion(partitions, completion.address);\n return manifest;\n}\n\nexport async function verifyCanonicalMarketDataCutoff(\n partitions: FilePartitionCommitStore,\n manifest: CanonicalJsonAddress,\n) {\n const verified = await verifyCutoffManifest(\n partitions,\n manifest,\n new CanonicalMarketInputResolver(partitions),\n );\n if (!verified.manifest.refreshCompletion) {\n throw new Error(\"Canonical cutoff manifest has no refresh completion authority\");\n }\n const completion = await verifyCanonicalRefreshCompletion(\n partitions,\n verified.manifest.refreshCompletion,\n );\n if (\n completion.value.plan.asOf !== verified.manifest.completeThrough ||\n completion.value.closure !== verified.manifest.closure\n ) {\n throw new Error(\"Canonical cutoff manifest refresh authority is inconsistent\");\n }\n return verified;\n}\n\nexport async function proveCanonicalMarketDataPrefix(\n partitions: FilePartitionCommitStore,\n ancestor: CanonicalJsonAddress,\n descendant: CanonicalJsonAddress,\n) {\n await verifyCanonicalMarketDataCutoff(partitions, ancestor);\n await verifyCanonicalMarketDataCutoff(partitions, descendant);\n const proof = await proveCutoffManifestPrefix(\n partitions,\n ancestor,\n descendant,\n new CanonicalMarketInputResolver(partitions),\n );\n await verifyCanonicalMarketDataCutoff(partitions, ancestor);\n await verifyCanonicalMarketDataCutoff(partitions, descendant);\n return proof;\n}\n","import {\n addressCanonicalJson,\n canonicalJson,\n canonicalJsonBytes,\n parseCanonicalJsonAddress,\n parseSha256Address,\n type CanonicalJsonAddress,\n type Sha256Address,\n} from \"./canonical-json.ts\";\nimport { ContentObjectStore, type PutContentObjectResult } from \"./content-object-store.ts\";\nimport {\n canonicalPartitionRelativePath,\n isRealMarketSessionDate,\n marketDatasetDefinition,\n} from \"./dataset-registry.ts\";\nimport type {\n ExactFileFingerprint,\n FilePartitionCommitStore,\n LogicalCoverage,\n PartitionQualityCounts,\n} from \"./partition-commit-store.ts\";\n\nexport const INPUT_RESOLVER_REGISTRY_KIND =\n \"tradeblocks.market-data.input-resolver-registry\" as const;\nexport const INPUT_RESOLVER_REGISTRY_VERSION = 1 as const;\nexport const INPUT_CLOSURE_DESCRIPTOR_KIND = \"tradeblocks.market-data.input-closure\" as const;\nexport const INPUT_CLOSURE_DESCRIPTOR_VERSION = 1 as const;\nexport const INPUT_DEPENDENCY_KEY_KIND = \"tradeblocks.market-data.input-dependency\" as const;\nexport const INPUT_DEPENDENCY_KEY_VERSION = 1 as const;\nexport const SEMANTIC_INPUT_LEAF_KIND = \"tradeblocks.market-data.semantic-input-leaf\" as const;\nexport const SEMANTIC_INPUT_LEAF_VERSION = 1 as const;\nexport const MISSING_PROBE_EVIDENCE_KIND =\n \"tradeblocks.market-data.missing-probe-evidence\" as const;\nexport const MISSING_PROBE_EVIDENCE_VERSION = 1 as const;\nexport const CUTOFF_MANIFEST_KIND = \"tradeblocks.market-data.cutoff-manifest\" as const;\nexport const CUTOFF_MANIFEST_VERSION = 1 as const;\n\nexport class ManifestVerificationError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"ManifestVerificationError\";\n }\n}\n\nexport interface PartitionedResolverClassV1 {\n kind: \"partitioned\";\n dataClass: string;\n dataset: string;\n selectorKeys: readonly string[];\n sessionKey: string;\n pathPrefix: string;\n filename: string;\n supportedSchemaRevisions: readonly number[];\n resolverRevision: string;\n calendarRevision: string;\n}\n\nexport interface StaticResolverClassV1 {\n kind: \"static\";\n dataClass: string;\n role: string;\n relativePath: string;\n supportedSchemaRevisions: readonly number[];\n resolverRevision: string;\n}\n\nexport interface MaterializedResolverClassV1 {\n kind: \"materialized\";\n dataClass: string;\n selectorKeys: readonly string[];\n sessionKey: string;\n supportedSchemaRevisions: readonly number[];\n resolverRevision: string;\n calendarRevision: string;\n}\n\nexport type InputResolverClassV1 =\n PartitionedResolverClassV1 | StaticResolverClassV1 | MaterializedResolverClassV1;\n\nexport interface InputResolverRegistryV1 {\n kind: typeof INPUT_RESOLVER_REGISTRY_KIND;\n version: typeof INPUT_RESOLVER_REGISTRY_VERSION;\n revision: string;\n classes: readonly InputResolverClassV1[];\n}\n\nexport type InputResolverRegistryInputV1 = Omit<InputResolverRegistryV1, \"kind\" | \"version\">;\n\nexport type InputClosureObservationV1 =\n | {\n kind: \"exact\";\n dataClass: string;\n selector: Record<string, string>;\n session: string;\n }\n | {\n kind: \"range\";\n dataClass: string;\n selectorPrefix: Record<string, string>;\n fromSession: string;\n throughSession: string;\n }\n | {\n kind: \"missing-probe\";\n dataClass: string;\n selector: Record<string, string>;\n session: string;\n }\n | { kind: \"control-file\"; dataClass: string; role: string }\n | { kind: \"unmanifestable\"; readClass: string; reasonCode: string };\n\nexport interface InputClosureDescriptorV1 {\n kind: typeof INPUT_CLOSURE_DESCRIPTOR_KIND;\n version: typeof INPUT_CLOSURE_DESCRIPTOR_VERSION;\n registry: CanonicalJsonAddress;\n observations: readonly InputClosureObservationV1[];\n}\n\nexport interface PartitionProjectionV1 {\n kind: \"partition-projection\";\n dataset: string;\n partition: Record<string, string>;\n relativePath: string;\n session: string;\n schemaRevision: number;\n coverage: LogicalCoverage;\n quality: PartitionQualityCounts;\n file: ExactFileFingerprint;\n}\n\nexport interface MaterializedSliceV1 {\n kind: \"materialized-slice\";\n selector: Record<string, string>;\n session: string;\n schemaRevision: number;\n object: { address: CanonicalJsonAddress; bytes: number };\n}\n\nexport interface ControlFileProjectionV1 {\n kind: \"control-file\";\n role: string;\n relativePath: string;\n schemaRevision: number;\n object: { address: CanonicalJsonAddress; bytes: number };\n}\n\nexport interface MissingProbeProjectionV1 {\n kind: \"missing-probe\";\n session: string;\n}\n\nexport type SemanticInputSourceV1 =\n PartitionProjectionV1 | MaterializedSliceV1 | ControlFileProjectionV1 | MissingProbeProjectionV1;\n\nexport interface SemanticInputLeafV1 {\n kind: typeof SEMANTIC_INPUT_LEAF_KIND;\n version: typeof SEMANTIC_INPUT_LEAF_VERSION;\n registry: CanonicalJsonAddress;\n dependency: CanonicalJsonAddress;\n dataClass: string;\n scope: { kind: \"session\"; session: string } | { kind: \"static\" };\n source: SemanticInputSourceV1;\n}\n\nexport interface MissingProbeEvidenceV1 {\n kind: typeof MISSING_PROBE_EVIDENCE_KIND;\n version: typeof MISSING_PROBE_EVIDENCE_VERSION;\n registry: CanonicalJsonAddress;\n dependency: CanonicalJsonAddress;\n completeThrough: string;\n}\n\nexport type ManifestLeafEvidenceV1 =\n | { kind: \"partition-receipt\"; receipt: CanonicalJsonAddress }\n | { kind: \"content-object\"; object: CanonicalJsonAddress }\n | { kind: \"absence-object\"; object: CanonicalJsonAddress };\n\nexport interface ManifestLeafReferenceV1 {\n leaf: CanonicalJsonAddress;\n evidence: ManifestLeafEvidenceV1;\n}\n\nexport interface ManifestClassV1 {\n dataClass: string;\n completeThrough: string;\n entries: readonly ManifestLeafReferenceV1[];\n leafCount: number;\n root: Sha256Address;\n}\n\nexport interface CutoffManifestV1 {\n kind: typeof CUTOFF_MANIFEST_KIND;\n version: typeof CUTOFF_MANIFEST_VERSION;\n closure: CanonicalJsonAddress;\n completeThrough: string;\n classes: readonly ManifestClassV1[];\n aggregateRoot: Sha256Address;\n refreshCompletion?: CanonicalJsonAddress;\n predecessor?: { manifest: CanonicalJsonAddress; aggregateRoot: Sha256Address };\n}\n\nexport type ManifestResolution =\n | {\n kind: \"resolved\";\n completeThrough: string;\n entries: readonly ManifestLeafReferenceV1[];\n }\n | { kind: \"unresolved\" | \"unmanifestable\"; reasonCode: string };\n\nexport interface ManifestInputResolver {\n resolve(input: {\n registry: InputResolverRegistryV1;\n closure: InputClosureDescriptorV1;\n observation: InputClosureObservationV1;\n dependency: CanonicalJsonAddress;\n completeThrough: string;\n }): Promise<ManifestResolution>;\n /**\n * Project immutable descendant static leaves back to an older cutoff.\n *\n * Partition/session leaves are always checked directly from the descendant\n * manifest. A static class may opt into cutoff projection only when its\n * producer can derive the older value from the descendant's immutable\n * content object; re-reading mutable live state is not a valid projection.\n */\n projectStaticPrefix?(input: {\n registry: InputResolverRegistryV1;\n registryAddress: CanonicalJsonAddress;\n dataClass: string;\n ancestorCompleteThrough: string;\n descendantCompleteThrough: string;\n descendantEntries: readonly ManifestLeafReferenceV1[];\n }): Promise<readonly ManifestLeafReferenceV1[]>;\n}\n\ntype JsonRecord = Record<string, unknown>;\n\nconst IDENTIFIER_RE = /^[A-Za-z_][A-Za-z0-9._-]*$/;\nconst SAFE_PATH_COMPONENT_RE = /^[A-Za-z0-9._=-]+$/;\nconst OBSERVATION_RANK: Readonly<Record<InputClosureObservationV1[\"kind\"], number>> = Object.freeze(\n {\n exact: 0,\n range: 1,\n \"missing-probe\": 2,\n \"control-file\": 3,\n unmanifestable: 4,\n },\n);\n\nexport function compareUnicodeCodePoints(left: string, right: string): number {\n const leftPoints = Array.from(left, (character) => character.codePointAt(0) as number);\n const rightPoints = Array.from(right, (character) => character.codePointAt(0) as number);\n const length = Math.min(leftPoints.length, rightPoints.length);\n for (let index = 0; index < length; index += 1) {\n if (leftPoints[index] !== rightPoints[index]) return leftPoints[index] - rightPoints[index];\n }\n return leftPoints.length - rightPoints.length;\n}\n\nfunction fail(message: string): never {\n throw new ManifestVerificationError(message);\n}\n\nfunction plainRecord(value: unknown, label: string): JsonRecord {\n if (\n value === null ||\n typeof value !== \"object\" ||\n Array.isArray(value) ||\n (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null)\n ) {\n fail(`${label} must be a plain object`);\n }\n return value as JsonRecord;\n}\n\nfunction exactKeys(record: JsonRecord, expected: readonly string[], label: string): void {\n const observed = Object.keys(record).sort(compareUnicodeCodePoints);\n const wanted = [...expected].sort(compareUnicodeCodePoints);\n if (observed.length !== wanted.length || observed.some((key, index) => key !== wanted[index])) {\n fail(`${label} has unknown or missing fields`);\n }\n for (const key of observed) {\n if (record[key] === null) fail(`${label}.${key} must use omission instead of null`);\n }\n}\n\nfunction nonemptyString(value: unknown, label: string): string {\n if (typeof value !== \"string\" || value.length === 0) fail(`${label} must be a non-empty string`);\n return value.normalize(\"NFC\");\n}\n\nfunction identifier(value: unknown, label: string): string {\n const normalized = nonemptyString(value, label);\n if (!IDENTIFIER_RE.test(normalized)) fail(`${label} is not a safe identifier`);\n return normalized;\n}\n\nfunction revision(value: unknown, label: string): string {\n const normalized = nonemptyString(value, label);\n if (!/^[A-Za-z0-9._-]+$/.test(normalized)) fail(`${label} is not a safe revision`);\n return normalized;\n}\n\nfunction sessionDate(value: unknown, label: string): string {\n const normalized = nonemptyString(value, label);\n if (!isRealMarketSessionDate(normalized)) fail(`${label} is not a valid session date`);\n return normalized;\n}\n\nfunction relativePath(value: unknown, label: string): string {\n const normalized = nonemptyString(value, label).replaceAll(\"\\\\\", \"/\");\n if (\n normalized.startsWith(\"/\") ||\n normalized.endsWith(\"/\") ||\n normalized\n .split(\"/\")\n .some((part) => !SAFE_PATH_COMPONENT_RE.test(part) || part === \".\" || part === \"..\")\n ) {\n fail(`${label} is not a safe relative path`);\n }\n return normalized;\n}\n\nfunction stringMap(value: unknown, label: string): Record<string, string> {\n const record = plainRecord(value, label);\n const normalized: Record<string, string> = {};\n const normalizedKeys = new Map<string, string>();\n for (const sourceKey of Object.keys(record)) {\n const key = identifier(sourceKey, `${label} key`);\n const collision = normalizedKeys.get(key);\n if (collision !== undefined && collision !== sourceKey) {\n fail(`${label} has an NFC-normalized key collision`);\n }\n normalizedKeys.set(key, sourceKey);\n normalized[key] = nonemptyString(record[sourceKey], `${label}.${sourceKey}`);\n }\n return Object.fromEntries(\n Object.entries(normalized).sort(([left], [right]) => compareUnicodeCodePoints(left, right)),\n );\n}\n\nfunction positiveSafeInteger(value: unknown, label: string): number {\n if (!Number.isSafeInteger(value) || (value as number) <= 0)\n fail(`${label} must be a positive safe integer`);\n return value as number;\n}\n\nfunction address(value: unknown, label: string): CanonicalJsonAddress {\n const normalized = nonemptyString(value, label);\n try {\n parseCanonicalJsonAddress(normalized);\n } catch (error) {\n throw new ManifestVerificationError(`${label} is not a canonical object address`, {\n cause: error,\n });\n }\n return normalized as CanonicalJsonAddress;\n}\n\nfunction snapshot<T>(value: unknown, label: string): T {\n try {\n return JSON.parse(canonicalJsonBytes(value).toString(\"utf8\")) as T;\n } catch (error) {\n throw new ManifestVerificationError(`${label} is not canonical JSON v1`, { cause: error });\n }\n}\n\nfunction rawStableJson(value: unknown): string {\n if (value === null || typeof value !== \"object\") return JSON.stringify(value);\n if (Array.isArray(value)) return `[${value.map(rawStableJson).join(\",\")}]`;\n const record = value as JsonRecord;\n return `{${Object.keys(record)\n .sort(compareUnicodeCodePoints)\n .map((key) => `${JSON.stringify(key)}:${rawStableJson(record[key])}`)\n .join(\",\")}}`;\n}\n\nfunction normalizeSchemaRevisions(value: unknown, label: string): readonly number[] {\n if (!Array.isArray(value) || value.length === 0) fail(`${label} must be a non-empty array`);\n const revisions = value.map((entry, index) => positiveSafeInteger(entry, `${label}[${index}]`));\n const sorted = [...revisions].sort((left, right) => left - right);\n if (sorted.some((entry, index) => index > 0 && entry === sorted[index - 1])) {\n fail(`${label} contains a duplicate revision`);\n }\n return sorted;\n}\n\nfunction normalizeSelectorKeys(value: unknown, label: string): readonly string[] {\n if (!Array.isArray(value) || value.length === 0) fail(`${label} must be a non-empty array`);\n const keys = value.map((entry, index) => identifier(entry, `${label}[${index}]`));\n if (new Set(keys).size !== keys.length) fail(`${label} contains a duplicate key`);\n return keys;\n}\n\nfunction normalizeRegistryClass(value: unknown, label: string): InputResolverClassV1 {\n const record = plainRecord(value, label);\n const kind = record.kind;\n if (kind === \"partitioned\") {\n exactKeys(\n record,\n [\n \"kind\",\n \"dataClass\",\n \"dataset\",\n \"selectorKeys\",\n \"sessionKey\",\n \"pathPrefix\",\n \"filename\",\n \"supportedSchemaRevisions\",\n \"resolverRevision\",\n \"calendarRevision\",\n ],\n label,\n );\n const dataClass = identifier(record.dataClass, `${label}.dataClass`);\n const dataset = identifier(record.dataset, `${label}.dataset`);\n const selectorKeys = normalizeSelectorKeys(record.selectorKeys, `${label}.selectorKeys`);\n const sessionKey = identifier(record.sessionKey, `${label}.sessionKey`);\n const pathPrefix = relativePath(record.pathPrefix, `${label}.pathPrefix`);\n const filename = relativePath(record.filename, `${label}.filename`);\n if (filename.includes(\"/\")) fail(`${label}.filename must be one path component`);\n const supportedSchemaRevisions = normalizeSchemaRevisions(\n record.supportedSchemaRevisions,\n `${label}.supportedSchemaRevisions`,\n );\n const resolverRevision = revision(record.resolverRevision, `${label}.resolverRevision`);\n const calendarRevision = revision(record.calendarRevision, `${label}.calendarRevision`);\n const shared = marketDatasetDefinition(dataset);\n if (!shared || shared.provenance.kind !== \"bounded-session\") {\n fail(`${label} references an unsupported or unbounded dataset`);\n }\n if (\n dataClass !== dataset ||\n canonicalJson(selectorKeys) !== canonicalJson(shared.partitionKeys) ||\n sessionKey !== shared.provenance.sessionKey ||\n pathPrefix !== shared.subdir ||\n filename !== shared.filename ||\n canonicalJson(supportedSchemaRevisions) !== canonicalJson([shared.schemaRevision])\n ) {\n fail(`${label} disagrees with the canonical dataset registry`);\n }\n return {\n kind,\n dataClass,\n dataset,\n selectorKeys,\n sessionKey,\n pathPrefix,\n filename,\n supportedSchemaRevisions,\n resolverRevision,\n calendarRevision,\n };\n }\n if (kind === \"static\") {\n exactKeys(\n record,\n [\"kind\", \"dataClass\", \"role\", \"relativePath\", \"supportedSchemaRevisions\", \"resolverRevision\"],\n label,\n );\n return {\n kind,\n dataClass: identifier(record.dataClass, `${label}.dataClass`),\n role: identifier(record.role, `${label}.role`),\n relativePath: relativePath(record.relativePath, `${label}.relativePath`),\n supportedSchemaRevisions: normalizeSchemaRevisions(\n record.supportedSchemaRevisions,\n `${label}.supportedSchemaRevisions`,\n ),\n resolverRevision: revision(record.resolverRevision, `${label}.resolverRevision`),\n };\n }\n if (kind === \"materialized\") {\n exactKeys(\n record,\n [\n \"kind\",\n \"dataClass\",\n \"selectorKeys\",\n \"sessionKey\",\n \"supportedSchemaRevisions\",\n \"resolverRevision\",\n \"calendarRevision\",\n ],\n label,\n );\n const selectorKeys = normalizeSelectorKeys(record.selectorKeys, `${label}.selectorKeys`);\n const sessionKey = identifier(record.sessionKey, `${label}.sessionKey`);\n if (!selectorKeys.includes(sessionKey)) {\n fail(`${label}.sessionKey is not one of its selector keys`);\n }\n return {\n kind,\n dataClass: identifier(record.dataClass, `${label}.dataClass`),\n selectorKeys,\n sessionKey,\n supportedSchemaRevisions: normalizeSchemaRevisions(\n record.supportedSchemaRevisions,\n `${label}.supportedSchemaRevisions`,\n ),\n resolverRevision: revision(record.resolverRevision, `${label}.resolverRevision`),\n calendarRevision: revision(record.calendarRevision, `${label}.calendarRevision`),\n };\n }\n fail(`${label}.kind is unsupported`);\n}\n\nfunction normalizeRegistry(value: unknown): InputResolverRegistryV1 {\n const captured = snapshot<unknown>(value, \"input resolver registry\");\n const record = plainRecord(captured, \"input resolver registry\");\n exactKeys(record, [\"kind\", \"version\", \"revision\", \"classes\"], \"input resolver registry\");\n if (record.kind !== INPUT_RESOLVER_REGISTRY_KIND) fail(\"input resolver registry kind is invalid\");\n if (record.version !== INPUT_RESOLVER_REGISTRY_VERSION) {\n fail(\"input resolver registry version is unsupported\");\n }\n if (!Array.isArray(record.classes) || record.classes.length === 0) {\n fail(\"input resolver registry classes must be a non-empty array\");\n }\n const classes = record.classes.map((entry, index) =>\n normalizeRegistryClass(entry, `input resolver registry classes[${index}]`),\n );\n classes.sort((left, right) => {\n const byClass = compareUnicodeCodePoints(left.dataClass, right.dataClass);\n return byClass === 0 ? compareUnicodeCodePoints(left.kind, right.kind) : byClass;\n });\n for (let index = 1; index < classes.length; index += 1) {\n if (classes[index - 1].dataClass === classes[index].dataClass) {\n fail(\n `input resolver registry repeats data class ${JSON.stringify(classes[index].dataClass)}`,\n );\n }\n }\n return {\n kind: INPUT_RESOLVER_REGISTRY_KIND,\n version: INPUT_RESOLVER_REGISTRY_VERSION,\n revision: revision(record.revision, \"input resolver registry revision\"),\n classes,\n };\n}\n\nexport async function publishInputResolverRegistry(\n objects: ContentObjectStore,\n input: InputResolverRegistryInputV1,\n): Promise<PutContentObjectResult<InputResolverRegistryV1>> {\n const registry = normalizeRegistry({\n kind: INPUT_RESOLVER_REGISTRY_KIND,\n version: INPUT_RESOLVER_REGISTRY_VERSION,\n revision: input.revision,\n classes: input.classes,\n });\n return objects.put(registry);\n}\n\nexport async function verifyInputResolverRegistry(\n objects: ContentObjectStore,\n registryAddress: CanonicalJsonAddress,\n): Promise<PutContentObjectResult<InputResolverRegistryV1>> {\n address(registryAddress, \"input resolver registry address\");\n const stored = await objects.get<unknown>(registryAddress);\n const registry = normalizeRegistry(stored);\n if (!canonicalJsonBytes(registry).equals(canonicalJsonBytes(stored))) {\n fail(\"input resolver registry is not normalized and deterministically ordered\");\n }\n return {\n address: registryAddress,\n value: registry,\n path: objects.objectPath(registryAddress),\n bytes: canonicalJsonBytes(stored).byteLength,\n created: false,\n };\n}\n\nfunction normalizeObservation(value: unknown, label: string): InputClosureObservationV1 {\n const record = plainRecord(snapshot(value, label), label);\n switch (record.kind) {\n case \"exact\":\n case \"missing-probe\": {\n exactKeys(record, [\"kind\", \"dataClass\", \"selector\", \"session\"], label);\n return {\n kind: record.kind,\n dataClass: identifier(record.dataClass, `${label}.dataClass`),\n selector: stringMap(record.selector, `${label}.selector`),\n session: sessionDate(record.session, `${label}.session`),\n };\n }\n case \"range\": {\n exactKeys(\n record,\n [\"kind\", \"dataClass\", \"selectorPrefix\", \"fromSession\", \"throughSession\"],\n label,\n );\n const fromSession = sessionDate(record.fromSession, `${label}.fromSession`);\n const throughSession = sessionDate(record.throughSession, `${label}.throughSession`);\n if (fromSession > throughSession) fail(`${label} has an inverted session range`);\n return {\n kind: record.kind,\n dataClass: identifier(record.dataClass, `${label}.dataClass`),\n selectorPrefix: stringMap(record.selectorPrefix, `${label}.selectorPrefix`),\n fromSession,\n throughSession,\n };\n }\n case \"control-file\":\n exactKeys(record, [\"kind\", \"dataClass\", \"role\"], label);\n return {\n kind: record.kind,\n dataClass: identifier(record.dataClass, `${label}.dataClass`),\n role: identifier(record.role, `${label}.role`),\n };\n case \"unmanifestable\":\n exactKeys(record, [\"kind\", \"readClass\", \"reasonCode\"], label);\n return {\n kind: record.kind,\n readClass: identifier(record.readClass, `${label}.readClass`),\n reasonCode: revision(record.reasonCode, `${label}.reasonCode`),\n };\n default:\n fail(`${label}.kind is unsupported`);\n }\n}\n\nfunction observationTuple(observation: InputClosureObservationV1): readonly string[] {\n switch (observation.kind) {\n case \"exact\":\n case \"missing-probe\":\n return [\n String(OBSERVATION_RANK[observation.kind]),\n observation.dataClass,\n canonicalJson(observation.selector),\n observation.session,\n ];\n case \"range\":\n return [\n String(OBSERVATION_RANK[observation.kind]),\n observation.dataClass,\n canonicalJson(observation.selectorPrefix),\n observation.fromSession,\n observation.throughSession,\n ];\n case \"control-file\":\n return [String(OBSERVATION_RANK[observation.kind]), observation.dataClass, observation.role];\n case \"unmanifestable\":\n return [\n String(OBSERVATION_RANK[observation.kind]),\n observation.readClass,\n observation.reasonCode,\n ];\n }\n}\n\nfunction compareTuples(left: readonly string[], right: readonly string[]): number {\n const length = Math.min(left.length, right.length);\n for (let index = 0; index < length; index += 1) {\n const compared = compareUnicodeCodePoints(left[index], right[index]);\n if (compared !== 0) return compared;\n }\n return left.length - right.length;\n}\n\nfunction normalizeObservations(value: unknown): readonly InputClosureObservationV1[] {\n if (!Array.isArray(value) || value.length === 0) {\n fail(\"input closure observations must be a non-empty array\");\n }\n const normalized = value.map((entry, index) => ({\n value: normalizeObservation(entry, `input closure observations[${index}]`),\n raw: rawStableJson(entry),\n }));\n normalized.sort((left, right) =>\n compareTuples(observationTuple(left.value), observationTuple(right.value)),\n );\n const result: InputClosureObservationV1[] = [];\n let previousNormalized: string | undefined;\n let previousRaw: string | undefined;\n for (const entry of normalized) {\n const encoded = canonicalJson(entry.value);\n if (encoded === previousNormalized) {\n if (entry.raw !== previousRaw) {\n fail(\"input closure observations collide after NFC normalization\");\n }\n continue;\n }\n result.push(entry.value);\n previousNormalized = encoded;\n previousRaw = entry.raw;\n }\n return result;\n}\n\nfunction normalizeDescriptor(value: unknown): InputClosureDescriptorV1 {\n const captured = snapshot<unknown>(value, \"input closure descriptor\");\n const record = plainRecord(captured, \"input closure descriptor\");\n exactKeys(record, [\"kind\", \"version\", \"registry\", \"observations\"], \"input closure descriptor\");\n if (record.kind !== INPUT_CLOSURE_DESCRIPTOR_KIND)\n fail(\"input closure descriptor kind is invalid\");\n if (record.version !== INPUT_CLOSURE_DESCRIPTOR_VERSION) {\n fail(\"input closure descriptor version is unsupported\");\n }\n return {\n kind: INPUT_CLOSURE_DESCRIPTOR_KIND,\n version: INPUT_CLOSURE_DESCRIPTOR_VERSION,\n registry: address(record.registry, \"input closure registry\"),\n observations: normalizeObservations(record.observations),\n };\n}\n\nfunction sameStringSet(observed: readonly string[], expected: readonly string[]): boolean {\n const left = [...observed].sort(compareUnicodeCodePoints);\n const right = [...expected].sort(compareUnicodeCodePoints);\n return left.length === right.length && left.every((entry, index) => entry === right[index]);\n}\n\nfunction validateObservationAgainstRegistry(\n observation: InputClosureObservationV1,\n registry: InputResolverRegistryV1,\n): void {\n if (observation.kind === \"unmanifestable\") return;\n const resolverClass = registry.classes.find((entry) => entry.dataClass === observation.dataClass);\n if (!resolverClass) {\n fail(`input closure references unknown data class ${JSON.stringify(observation.dataClass)}`);\n }\n if (observation.kind === \"control-file\") {\n if (resolverClass.kind !== \"static\" || resolverClass.role !== observation.role) {\n fail(\"control-file observation disagrees with its registry class\");\n }\n return;\n }\n if (resolverClass.kind === \"static\") {\n fail(`${observation.kind} observation requires a session-scoped registry class`);\n }\n if (observation.kind === \"range\") {\n const expectedPrefixKeys = resolverClass.selectorKeys.filter(\n (key) => key !== resolverClass.sessionKey,\n );\n const observedKeys = Object.keys(observation.selectorPrefix);\n if (!sameStringSet(observedKeys, expectedPrefixKeys)) {\n fail(\"range selector prefix disagrees with its registry class\");\n }\n return;\n }\n const observedKeys = Object.keys(observation.selector);\n if (!sameStringSet(observedKeys, resolverClass.selectorKeys)) {\n fail(`${observation.kind} selector disagrees with its registry class`);\n }\n if (observation.selector[resolverClass.sessionKey] !== observation.session) {\n fail(`${observation.kind} selector session disagrees with its explicit session`);\n }\n}\n\nfunction validateDescriptorAgainstRegistry(\n descriptor: InputClosureDescriptorV1,\n registry: InputResolverRegistryV1,\n): void {\n for (const observation of descriptor.observations) {\n validateObservationAgainstRegistry(observation, registry);\n }\n}\n\nexport function createInputClosureDescriptor(\n registry: CanonicalJsonAddress,\n observations: readonly InputClosureObservationV1[],\n): InputClosureDescriptorV1 {\n return normalizeDescriptor({\n kind: INPUT_CLOSURE_DESCRIPTOR_KIND,\n version: INPUT_CLOSURE_DESCRIPTOR_VERSION,\n registry: address(registry, \"input closure registry\"),\n observations,\n });\n}\n\nexport async function publishInputClosure(\n objects: ContentObjectStore,\n input: {\n registry: CanonicalJsonAddress;\n observations: readonly InputClosureObservationV1[];\n },\n): Promise<PutContentObjectResult<InputClosureDescriptorV1>> {\n const descriptor = createInputClosureDescriptor(input.registry, input.observations);\n const registry = await verifyInputResolverRegistry(objects, descriptor.registry);\n validateDescriptorAgainstRegistry(descriptor, registry.value);\n return objects.put(descriptor);\n}\n\nexport async function verifyInputClosure(\n objects: ContentObjectStore,\n closureAddress: CanonicalJsonAddress,\n): Promise<PutContentObjectResult<InputClosureDescriptorV1>> {\n address(closureAddress, \"input closure address\");\n const stored = await objects.get<unknown>(closureAddress);\n const descriptor = normalizeDescriptor(stored);\n if (!canonicalJsonBytes(descriptor).equals(canonicalJsonBytes(stored))) {\n fail(\"input closure is not normalized and deterministically ordered\");\n }\n const registry = await verifyInputResolverRegistry(objects, descriptor.registry);\n validateDescriptorAgainstRegistry(descriptor, registry.value);\n return {\n address: closureAddress,\n value: descriptor,\n path: objects.objectPath(closureAddress),\n bytes: canonicalJsonBytes(stored).byteLength,\n created: false,\n };\n}\n\nfunction stableDependencyObservation(\n observation: InputClosureObservationV1,\n):\n | Exclude<InputClosureObservationV1, { kind: \"unmanifestable\" }>\n | Omit<Extract<InputClosureObservationV1, { kind: \"range\" }>, \"throughSession\"> {\n if (observation.kind === \"unmanifestable\") {\n fail(\"unmanifestable observations do not have resolvable dependency keys\");\n }\n if (observation.kind !== \"range\") return observation;\n return {\n kind: observation.kind,\n dataClass: observation.dataClass,\n selectorPrefix: observation.selectorPrefix,\n fromSession: observation.fromSession,\n };\n}\n\nexport function dependencyKeyAddress(\n registry: CanonicalJsonAddress,\n observation: InputClosureObservationV1,\n): CanonicalJsonAddress {\n const normalizedRegistry = address(registry, \"input dependency registry\");\n const normalizedObservation = normalizeObservation(observation, \"input dependency observation\");\n return addressCanonicalJson({\n kind: INPUT_DEPENDENCY_KEY_KIND,\n version: INPUT_DEPENDENCY_KEY_VERSION,\n registry: normalizedRegistry,\n observation: stableDependencyObservation(normalizedObservation),\n });\n}\n\nexport function restrictInputClosureDescriptor(\n descriptor: InputClosureDescriptorV1,\n completeThrough: string,\n): InputClosureDescriptorV1 {\n const normalized = normalizeDescriptor(descriptor);\n const cutoff = sessionDate(completeThrough, \"input closure restriction cutoff\");\n const observations: InputClosureObservationV1[] = [];\n for (const observation of normalized.observations) {\n switch (observation.kind) {\n case \"exact\":\n case \"missing-probe\":\n if (observation.session <= cutoff) observations.push(observation);\n break;\n case \"range\":\n if (observation.fromSession <= cutoff) {\n observations.push({\n ...observation,\n throughSession:\n observation.throughSession <= cutoff ? observation.throughSession : cutoff,\n });\n }\n break;\n case \"control-file\":\n case \"unmanifestable\":\n observations.push(observation);\n break;\n }\n }\n if (observations.length === 0) {\n fail(\"input closure restriction removed every observation\");\n }\n return createInputClosureDescriptor(normalized.registry, observations);\n}\n\nfunction nonnegativeSafeInteger(value: unknown, label: string): number {\n if (!Number.isSafeInteger(value) || (value as number) < 0) {\n fail(`${label} must be a non-negative safe integer`);\n }\n return value as number;\n}\n\nfunction sha256Address(value: unknown, label: string): Sha256Address {\n const normalized = nonemptyString(value, label);\n try {\n parseSha256Address(normalized);\n } catch (error) {\n throw new ManifestVerificationError(`${label} is not a SHA-256 address`, { cause: error });\n }\n return normalized as Sha256Address;\n}\n\nfunction normalizeCoverage(value: unknown, label: string): LogicalCoverage {\n const record = plainRecord(value, label);\n if (record.kind === \"empty\") {\n exactKeys(record, [\"kind\"], label);\n return { kind: \"empty\" };\n }\n if (record.kind === \"date-range\") {\n exactKeys(record, [\"kind\", \"from\", \"through\"], label);\n const from = sessionDate(record.from, `${label}.from`);\n const through = sessionDate(record.through, `${label}.through`);\n if (from > through) fail(`${label} has an inverted date range`);\n return { kind: \"date-range\", from, through };\n }\n fail(`${label}.kind is unsupported`);\n}\n\nfunction normalizeQuality(value: unknown, label: string): PartitionQualityCounts {\n const record = plainRecord(value, label);\n exactKeys(record, [\"inputRows\", \"writtenRows\", \"droppedRows\"], label);\n const quality = {\n inputRows: nonnegativeSafeInteger(record.inputRows, `${label}.inputRows`),\n writtenRows: nonnegativeSafeInteger(record.writtenRows, `${label}.writtenRows`),\n droppedRows: nonnegativeSafeInteger(record.droppedRows, `${label}.droppedRows`),\n };\n if (quality.inputRows !== quality.writtenRows + quality.droppedRows) {\n fail(`${label} row counts are inconsistent`);\n }\n return quality;\n}\n\nfunction normalizeFile(value: unknown, label: string): ExactFileFingerprint {\n const record = plainRecord(value, label);\n exactKeys(record, [\"address\", \"bytes\", \"rows\"], label);\n return {\n address: sha256Address(record.address, `${label}.address`),\n bytes: nonnegativeSafeInteger(record.bytes, `${label}.bytes`),\n rows: nonnegativeSafeInteger(record.rows, `${label}.rows`),\n };\n}\n\nfunction normalizeObjectReference(\n value: unknown,\n label: string,\n): { address: CanonicalJsonAddress; bytes: number } {\n const record = plainRecord(value, label);\n exactKeys(record, [\"address\", \"bytes\"], label);\n return {\n address: address(record.address, `${label}.address`),\n bytes: positiveSafeInteger(record.bytes, `${label}.bytes`),\n };\n}\n\nfunction registryClass(registry: InputResolverRegistryV1, dataClass: string): InputResolverClassV1 {\n const found = registry.classes.find((entry) => entry.dataClass === dataClass);\n if (!found) fail(`semantic input references unknown data class ${JSON.stringify(dataClass)}`);\n return found;\n}\n\nfunction normalizePartitionProjection(\n record: JsonRecord,\n label: string,\n resolverClass: PartitionedResolverClassV1,\n): PartitionProjectionV1 {\n exactKeys(\n record,\n [\n \"kind\",\n \"dataset\",\n \"partition\",\n \"relativePath\",\n \"session\",\n \"schemaRevision\",\n \"coverage\",\n \"quality\",\n \"file\",\n ],\n label,\n );\n const dataset = identifier(record.dataset, `${label}.dataset`);\n const partition = stringMap(record.partition, `${label}.partition`);\n const relative = relativePath(record.relativePath, `${label}.relativePath`);\n const session = sessionDate(record.session, `${label}.session`);\n const schemaRevision = positiveSafeInteger(record.schemaRevision, `${label}.schemaRevision`);\n const coverage = normalizeCoverage(record.coverage, `${label}.coverage`);\n const quality = normalizeQuality(record.quality, `${label}.quality`);\n const file = normalizeFile(record.file, `${label}.file`);\n if (dataset !== resolverClass.dataset) fail(`${label}.dataset disagrees with the registry`);\n if (!sameStringSet(Object.keys(partition), resolverClass.selectorKeys)) {\n fail(`${label}.partition disagrees with the registry selector keys`);\n }\n if (partition[resolverClass.sessionKey] !== session) {\n fail(`${label}.partition session disagrees with its explicit session`);\n }\n const expectedPath = canonicalPartitionRelativePath({ dataset, partition });\n if (relative !== expectedPath) fail(`${label}.relativePath disagrees with the registry`);\n if (!resolverClass.supportedSchemaRevisions.includes(schemaRevision)) {\n fail(`${label}.schemaRevision is unsupported`);\n }\n if (quality.writtenRows !== file.rows) fail(`${label}.quality disagrees with file rows`);\n if (coverage.kind === \"empty\" && file.rows !== 0) {\n fail(`${label}.coverage is empty for a non-empty file`);\n }\n if (coverage.kind === \"date-range\" && file.rows === 0) {\n fail(`${label}.coverage is non-empty for an empty file`);\n }\n return {\n kind: \"partition-projection\",\n dataset,\n partition,\n relativePath: relative,\n session,\n schemaRevision,\n coverage,\n quality,\n file,\n };\n}\n\nfunction normalizeMaterializedSlice(\n record: JsonRecord,\n label: string,\n resolverClass: MaterializedResolverClassV1,\n): MaterializedSliceV1 {\n exactKeys(record, [\"kind\", \"selector\", \"session\", \"schemaRevision\", \"object\"], label);\n const selector = stringMap(record.selector, `${label}.selector`);\n const session = sessionDate(record.session, `${label}.session`);\n const schemaRevision = positiveSafeInteger(record.schemaRevision, `${label}.schemaRevision`);\n if (!sameStringSet(Object.keys(selector), resolverClass.selectorKeys)) {\n fail(`${label}.selector disagrees with the registry selector keys`);\n }\n if (selector[resolverClass.sessionKey] !== session) {\n fail(`${label}.selector session disagrees with its explicit session`);\n }\n if (!resolverClass.supportedSchemaRevisions.includes(schemaRevision)) {\n fail(`${label}.schemaRevision is unsupported`);\n }\n return {\n kind: \"materialized-slice\",\n selector,\n session,\n schemaRevision,\n object: normalizeObjectReference(record.object, `${label}.object`),\n };\n}\n\nfunction normalizeSemanticSource(\n value: unknown,\n label: string,\n resolverClass: InputResolverClassV1,\n): SemanticInputSourceV1 {\n const record = plainRecord(snapshot(value, label), label);\n switch (record.kind) {\n case \"partition-projection\":\n if (resolverClass.kind !== \"partitioned\") {\n fail(`${label} requires a partitioned registry class`);\n }\n return normalizePartitionProjection(record, label, resolverClass);\n case \"control-file\": {\n if (resolverClass.kind !== \"static\") fail(`${label} requires a static registry class`);\n exactKeys(record, [\"kind\", \"role\", \"relativePath\", \"schemaRevision\", \"object\"], label);\n const role = identifier(record.role, `${label}.role`);\n const relative = relativePath(record.relativePath, `${label}.relativePath`);\n const schemaRevision = positiveSafeInteger(record.schemaRevision, `${label}.schemaRevision`);\n if (role !== resolverClass.role || relative !== resolverClass.relativePath) {\n fail(`${label} disagrees with the static registry class`);\n }\n if (!resolverClass.supportedSchemaRevisions.includes(schemaRevision)) {\n fail(`${label}.schemaRevision is unsupported`);\n }\n return {\n kind: \"control-file\",\n role,\n relativePath: relative,\n schemaRevision,\n object: normalizeObjectReference(record.object, `${label}.object`),\n };\n }\n case \"missing-probe\": {\n if (resolverClass.kind !== \"partitioned\") {\n fail(`${label} requires a partitioned registry class`);\n }\n exactKeys(record, [\"kind\", \"session\"], label);\n return {\n kind: \"missing-probe\",\n session: sessionDate(record.session, `${label}.session`),\n };\n }\n case \"materialized-slice\":\n if (resolverClass.kind !== \"materialized\") {\n fail(`${label} requires a materialized registry class`);\n }\n return normalizeMaterializedSlice(record, label, resolverClass);\n default:\n fail(`${label}.kind is unsupported`);\n }\n}\n\nfunction expectedScope(\n observation: Exclude<InputClosureObservationV1, { kind: \"unmanifestable\" }>,\n source: SemanticInputSourceV1,\n): SemanticInputLeafV1[\"scope\"] {\n if (observation.kind === \"control-file\") return { kind: \"static\" };\n if (source.kind === \"control-file\") {\n fail(`${observation.kind} observation cannot use ${source.kind} source evidence`);\n }\n return { kind: \"session\", session: source.session };\n}\n\nfunction validateSourceAgainstObservation(\n source: SemanticInputSourceV1,\n observation: Exclude<InputClosureObservationV1, { kind: \"unmanifestable\" }>,\n resolverClass: InputResolverClassV1,\n options: { allowRangeFuture?: boolean } = {},\n): \"included\" | \"future\" {\n if (observation.kind === \"control-file\") {\n if (source.kind !== \"control-file\" || resolverClass.kind !== \"static\") {\n fail(\"control-file observation has incompatible semantic source evidence\");\n }\n if (source.role !== observation.role) fail(\"control-file source role is incorrect\");\n return \"included\";\n }\n if (observation.kind === \"missing-probe\") {\n if (source.kind !== \"missing-probe\") {\n fail(\"missing-probe observation has incompatible semantic source evidence\");\n }\n if (source.session !== observation.session) fail(\"missing-probe source session is incorrect\");\n return \"included\";\n }\n if (\n (source.kind !== \"partition-projection\" || resolverClass.kind !== \"partitioned\") &&\n (source.kind !== \"materialized-slice\" || resolverClass.kind !== \"materialized\")\n ) {\n fail(`${observation.kind} observation requires compatible session evidence`);\n }\n const selector = source.kind === \"partition-projection\" ? source.partition : source.selector;\n if (observation.kind === \"exact\") {\n if (\n source.session !== observation.session ||\n canonicalJson(selector) !== canonicalJson(observation.selector)\n ) {\n fail(\"exact source partition is incorrect\");\n }\n return \"included\";\n }\n for (const [key, value] of Object.entries(observation.selectorPrefix)) {\n if (selector[key] !== value) fail(\"range source partition prefix is incorrect\");\n }\n if (source.session < observation.fromSession) fail(\"range source precedes the requested range\");\n if (source.session > observation.throughSession) {\n if (options.allowRangeFuture) return \"future\";\n fail(\"range source exceeds the requested range\");\n }\n return \"included\";\n}\n\nfunction normalizeSemanticLeaf(value: unknown): SemanticInputLeafV1 {\n const captured = snapshot<unknown>(value, \"semantic input leaf\");\n const record = plainRecord(captured, \"semantic input leaf\");\n exactKeys(\n record,\n [\"kind\", \"version\", \"registry\", \"dependency\", \"dataClass\", \"scope\", \"source\"],\n \"semantic input leaf\",\n );\n if (record.kind !== SEMANTIC_INPUT_LEAF_KIND) fail(\"semantic input leaf kind is invalid\");\n if (record.version !== SEMANTIC_INPUT_LEAF_VERSION) {\n fail(\"semantic input leaf version is unsupported\");\n }\n const registryAddress = address(record.registry, \"semantic input leaf registry\");\n const dependency = address(record.dependency, \"semantic input leaf dependency\");\n const dataClass = identifier(record.dataClass, \"semantic input leaf dataClass\");\n const scopeRecord = plainRecord(record.scope, \"semantic input leaf scope\");\n let scope: SemanticInputLeafV1[\"scope\"];\n if (scopeRecord.kind === \"static\") {\n exactKeys(scopeRecord, [\"kind\"], \"semantic input leaf scope\");\n scope = { kind: \"static\" };\n } else if (scopeRecord.kind === \"session\") {\n exactKeys(scopeRecord, [\"kind\", \"session\"], \"semantic input leaf scope\");\n scope = {\n kind: \"session\",\n session: sessionDate(scopeRecord.session, \"semantic input leaf scope.session\"),\n };\n } else {\n fail(\"semantic input leaf scope kind is unsupported\");\n }\n return {\n kind: SEMANTIC_INPUT_LEAF_KIND,\n version: SEMANTIC_INPUT_LEAF_VERSION,\n registry: registryAddress,\n dependency,\n dataClass,\n scope,\n source: record.source as SemanticInputSourceV1,\n };\n}\n\nasync function normalizeSemanticLeafWithRegistry(\n objects: ContentObjectStore,\n value: unknown,\n): Promise<SemanticInputLeafV1> {\n const leaf = normalizeSemanticLeaf(value);\n const registry = await verifyInputResolverRegistry(objects, leaf.registry);\n const resolverClass = registryClass(registry.value, leaf.dataClass);\n const source = normalizeSemanticSource(leaf.source, \"semantic input leaf source\", resolverClass);\n if (source.kind === \"control-file\") {\n if (leaf.scope.kind !== \"static\") fail(\"control-file leaf must have static scope\");\n } else {\n if (leaf.scope.kind !== \"session\" || leaf.scope.session !== source.session) {\n fail(\"semantic input leaf scope disagrees with its source\");\n }\n }\n return { ...leaf, source };\n}\n\nexport async function publishSemanticInputLeaf(\n objects: ContentObjectStore,\n input: {\n registry: CanonicalJsonAddress;\n observation: InputClosureObservationV1;\n source: SemanticInputSourceV1;\n },\n): Promise<PutContentObjectResult<SemanticInputLeafV1>> {\n const registryAddress = address(input.registry, \"semantic input registry\");\n const observation = normalizeObservation(input.observation, \"semantic input observation\");\n const capturedSource = snapshot<SemanticInputSourceV1>(input.source, \"semantic input source\");\n if (observation.kind === \"unmanifestable\") {\n fail(\"unmanifestable observations cannot publish semantic leaves\");\n }\n const registry = await verifyInputResolverRegistry(objects, registryAddress);\n validateObservationAgainstRegistry(observation, registry.value);\n const resolverClass = registryClass(registry.value, observation.dataClass);\n const source = normalizeSemanticSource(capturedSource, \"semantic input source\", resolverClass);\n validateSourceAgainstObservation(source, observation, resolverClass);\n if (source.kind === \"control-file\") {\n const stored = await objects.get<unknown>(source.object.address);\n if (canonicalJsonBytes(stored).byteLength !== source.object.bytes) {\n fail(\"control-file object byte length is incorrect\");\n }\n }\n return objects.put({\n kind: SEMANTIC_INPUT_LEAF_KIND,\n version: SEMANTIC_INPUT_LEAF_VERSION,\n registry: registryAddress,\n dependency: dependencyKeyAddress(registryAddress, observation),\n dataClass: observation.dataClass,\n scope: expectedScope(observation, source),\n source,\n });\n}\n\nexport async function verifySemanticInputLeaf(\n objects: ContentObjectStore,\n leafAddress: CanonicalJsonAddress,\n): Promise<PutContentObjectResult<SemanticInputLeafV1>> {\n address(leafAddress, \"semantic input leaf address\");\n const stored = await objects.get<unknown>(leafAddress);\n const leaf = await normalizeSemanticLeafWithRegistry(objects, stored);\n if (!canonicalJsonBytes(leaf).equals(canonicalJsonBytes(stored))) {\n fail(\"semantic input leaf is not normalized\");\n }\n return {\n address: leafAddress,\n value: leaf,\n path: objects.objectPath(leafAddress),\n bytes: canonicalJsonBytes(stored).byteLength,\n created: false,\n };\n}\n\nexport async function publishMissingProbeEvidence(\n objects: ContentObjectStore,\n input: {\n registry: CanonicalJsonAddress;\n observation: Extract<InputClosureObservationV1, { kind: \"missing-probe\" }>;\n completeThrough: string;\n },\n): Promise<PutContentObjectResult<MissingProbeEvidenceV1>> {\n const registryAddress = address(input.registry, \"missing-probe evidence registry\");\n const observation = normalizeObservation(input.observation, \"missing-probe evidence observation\");\n if (observation.kind !== \"missing-probe\") fail(\"missing-probe evidence requires a probe\");\n const completeThrough = sessionDate(\n input.completeThrough,\n \"missing-probe evidence completeThrough\",\n );\n const registry = await verifyInputResolverRegistry(objects, registryAddress);\n validateObservationAgainstRegistry(observation, registry.value);\n if (completeThrough < observation.session) {\n fail(\"missing-probe evidence complete horizon precedes the probe\");\n }\n return objects.put({\n kind: MISSING_PROBE_EVIDENCE_KIND,\n version: MISSING_PROBE_EVIDENCE_VERSION,\n registry: registryAddress,\n dependency: dependencyKeyAddress(registryAddress, observation),\n completeThrough,\n });\n}\n\nfunction normalizeMissingProbeEvidence(value: unknown): MissingProbeEvidenceV1 {\n const captured = snapshot<unknown>(value, \"missing-probe evidence\");\n const record = plainRecord(captured, \"missing-probe evidence\");\n exactKeys(\n record,\n [\"kind\", \"version\", \"registry\", \"dependency\", \"completeThrough\"],\n \"missing-probe evidence\",\n );\n if (record.kind !== MISSING_PROBE_EVIDENCE_KIND) {\n fail(\"missing-probe evidence kind is invalid\");\n }\n if (record.version !== MISSING_PROBE_EVIDENCE_VERSION) {\n fail(\"missing-probe evidence version is unsupported\");\n }\n return {\n kind: MISSING_PROBE_EVIDENCE_KIND,\n version: MISSING_PROBE_EVIDENCE_VERSION,\n registry: address(record.registry, \"missing-probe evidence registry\"),\n dependency: address(record.dependency, \"missing-probe evidence dependency\"),\n completeThrough: sessionDate(record.completeThrough, \"missing-probe evidence completeThrough\"),\n };\n}\n\nasync function verifyMissingProbeEvidence(\n objects: ContentObjectStore,\n evidenceAddress: CanonicalJsonAddress,\n): Promise<MissingProbeEvidenceV1> {\n address(evidenceAddress, \"missing-probe evidence address\");\n const stored = await objects.get<unknown>(evidenceAddress);\n const evidence = normalizeMissingProbeEvidence(stored);\n if (!canonicalJsonBytes(evidence).equals(canonicalJsonBytes(stored))) {\n fail(\"missing-probe evidence is not normalized\");\n }\n await verifyInputResolverRegistry(objects, evidence.registry);\n return evidence;\n}\n\nfunction normalizeLeafEvidence(value: unknown, label: string): ManifestLeafEvidenceV1 {\n const record = plainRecord(value, label);\n switch (record.kind) {\n case \"partition-receipt\":\n exactKeys(record, [\"kind\", \"receipt\"], label);\n return {\n kind: \"partition-receipt\",\n receipt: address(record.receipt, `${label}.receipt`),\n };\n case \"content-object\":\n exactKeys(record, [\"kind\", \"object\"], label);\n return {\n kind: \"content-object\",\n object: address(record.object, `${label}.object`),\n };\n case \"absence-object\":\n exactKeys(record, [\"kind\", \"object\"], label);\n return {\n kind: \"absence-object\",\n object: address(record.object, `${label}.object`),\n };\n default:\n fail(`${label}.kind is unsupported`);\n }\n}\n\nfunction normalizeLeafReferences(\n value: unknown,\n label: string,\n): readonly ManifestLeafReferenceV1[] {\n if (!Array.isArray(value) || value.length === 0) fail(`${label} must be a non-empty array`);\n const references = value.map((entry, index) => {\n const record = plainRecord(entry, `${label}[${index}]`);\n exactKeys(record, [\"leaf\", \"evidence\"], `${label}[${index}]`);\n return {\n leaf: address(record.leaf, `${label}[${index}].leaf`),\n evidence: normalizeLeafEvidence(record.evidence, `${label}[${index}].evidence`),\n };\n });\n references.sort((left, right) => {\n const byLeaf = compareUnicodeCodePoints(left.leaf, right.leaf);\n return byLeaf === 0\n ? compareUnicodeCodePoints(canonicalJson(left.evidence), canonicalJson(right.evidence))\n : byLeaf;\n });\n for (let index = 1; index < references.length; index += 1) {\n if (references[index - 1].leaf === references[index].leaf) {\n fail(`${label} contains a duplicate semantic leaf`);\n }\n }\n return references;\n}\n\ninterface MerkleNode {\n address: Sha256Address;\n count: number;\n}\n\nfunction merkleTreeRoot(leaves: readonly CanonicalJsonAddress[]): Sha256Address {\n if (leaves.length === 0) {\n return addressCanonicalJson({\n kind: \"tradeblocks.market-data.merkle-empty\",\n version: 1,\n count: 0,\n });\n }\n let level: MerkleNode[] = leaves.map((leaf) => ({\n address: addressCanonicalJson({\n kind: \"tradeblocks.market-data.merkle-leaf\",\n version: 1,\n count: 1,\n leaf,\n }),\n count: 1,\n }));\n while (level.length > 1) {\n const next: MerkleNode[] = [];\n for (let index = 0; index < level.length; index += 2) {\n const left = level[index];\n const right = level[index + 1];\n if (!right) {\n next.push({\n address: addressCanonicalJson({\n kind: \"tradeblocks.market-data.merkle-unary\",\n version: 1,\n count: left.count,\n child: left.address,\n }),\n count: left.count,\n });\n } else {\n const count = left.count + right.count;\n next.push({\n address: addressCanonicalJson({\n kind: \"tradeblocks.market-data.merkle-binary\",\n version: 1,\n count,\n left: left.address,\n right: right.address,\n }),\n count,\n });\n }\n }\n level = next;\n }\n return level[0].address;\n}\n\nfunction createManifestClass(\n dataClass: string,\n completeThrough: string,\n entries: readonly ManifestLeafReferenceV1[],\n): ManifestClassV1 {\n const normalizedEntries = normalizeLeafReferences(entries, `${dataClass} manifest entries`);\n const leafCount = normalizedEntries.length;\n const treeRoot = merkleTreeRoot(normalizedEntries.map((entry) => entry.leaf));\n return {\n dataClass,\n completeThrough,\n entries: normalizedEntries,\n leafCount,\n root: addressCanonicalJson({\n kind: \"tradeblocks.market-data.merkle-class\",\n version: 1,\n dataClass,\n completeThrough,\n leafCount,\n treeRoot,\n }),\n };\n}\n\nfunction normalizePredecessor(\n value: unknown,\n label: string,\n): { manifest: CanonicalJsonAddress; aggregateRoot: Sha256Address } {\n const record = plainRecord(value, label);\n exactKeys(record, [\"manifest\", \"aggregateRoot\"], label);\n return {\n manifest: address(record.manifest, `${label}.manifest`),\n aggregateRoot: sha256Address(record.aggregateRoot, `${label}.aggregateRoot`),\n };\n}\n\nfunction createCutoffManifestValue(\n closure: CanonicalJsonAddress,\n completeThrough: string,\n classes: readonly ManifestClassV1[],\n refreshCompletion?: CanonicalJsonAddress,\n predecessor?: { manifest: CanonicalJsonAddress; aggregateRoot: Sha256Address },\n): CutoffManifestV1 {\n const sortedClasses = [...classes].sort((left, right) =>\n compareUnicodeCodePoints(left.dataClass, right.dataClass),\n );\n if (sortedClasses.length === 0) fail(\"cutoff manifest must contain at least one data class\");\n const aggregateRoot = addressCanonicalJson({\n kind: \"tradeblocks.market-data.merkle-aggregate\",\n version: 1,\n closure,\n completeThrough,\n ...(refreshCompletion ? { refreshCompletion } : {}),\n classes: sortedClasses.map(({ dataClass, leafCount, root }) => ({\n dataClass,\n leafCount,\n root,\n })),\n });\n return {\n kind: CUTOFF_MANIFEST_KIND,\n version: CUTOFF_MANIFEST_VERSION,\n closure,\n completeThrough,\n classes: sortedClasses,\n aggregateRoot,\n ...(refreshCompletion ? { refreshCompletion } : {}),\n ...(predecessor ? { predecessor } : {}),\n };\n}\n\nfunction normalizeManifestClass(value: unknown, label: string): ManifestClassV1 {\n const record = plainRecord(value, label);\n exactKeys(record, [\"dataClass\", \"completeThrough\", \"entries\", \"leafCount\", \"root\"], label);\n const entries = normalizeLeafReferences(record.entries, `${label}.entries`);\n const leafCount = positiveSafeInteger(record.leafCount, `${label}.leafCount`);\n if (leafCount !== entries.length) fail(`${label}.leafCount disagrees with its entries`);\n return {\n dataClass: identifier(record.dataClass, `${label}.dataClass`),\n completeThrough: sessionDate(record.completeThrough, `${label}.completeThrough`),\n entries,\n leafCount,\n root: sha256Address(record.root, `${label}.root`),\n };\n}\n\nfunction normalizeCutoffManifest(value: unknown): CutoffManifestV1 {\n const captured = snapshot<unknown>(value, \"cutoff manifest\");\n const record = plainRecord(captured, \"cutoff manifest\");\n const expected = [\n \"kind\",\n \"version\",\n \"closure\",\n \"completeThrough\",\n \"classes\",\n \"aggregateRoot\",\n ...(Object.hasOwn(record, \"refreshCompletion\") ? [\"refreshCompletion\"] : []),\n ...(Object.hasOwn(record, \"predecessor\") ? [\"predecessor\"] : []),\n ];\n exactKeys(record, expected, \"cutoff manifest\");\n if (record.kind !== CUTOFF_MANIFEST_KIND) fail(\"cutoff manifest kind is invalid\");\n if (record.version !== CUTOFF_MANIFEST_VERSION) fail(\"cutoff manifest version is unsupported\");\n if (!Array.isArray(record.classes) || record.classes.length === 0) {\n fail(\"cutoff manifest classes must be a non-empty array\");\n }\n const classes = record.classes.map((entry, index) =>\n normalizeManifestClass(entry, `cutoff manifest classes[${index}]`),\n );\n classes.sort((left, right) => compareUnicodeCodePoints(left.dataClass, right.dataClass));\n for (let index = 1; index < classes.length; index += 1) {\n if (classes[index - 1].dataClass === classes[index].dataClass) {\n fail(\"cutoff manifest contains a duplicate data class\");\n }\n }\n return {\n kind: CUTOFF_MANIFEST_KIND,\n version: CUTOFF_MANIFEST_VERSION,\n closure: address(record.closure, \"cutoff manifest closure\"),\n completeThrough: sessionDate(record.completeThrough, \"cutoff manifest completeThrough\"),\n classes,\n aggregateRoot: sha256Address(record.aggregateRoot, \"cutoff manifest aggregateRoot\"),\n ...(record.refreshCompletion === undefined\n ? {}\n : {\n refreshCompletion: address(record.refreshCompletion, \"cutoff manifest refreshCompletion\"),\n }),\n ...(record.predecessor === undefined\n ? {}\n : { predecessor: normalizePredecessor(record.predecessor, \"cutoff manifest predecessor\") }),\n };\n}\n\nasync function verifyLeafEvidence(\n partitions: FilePartitionCommitStore,\n leaf: SemanticInputLeafV1,\n reference: ManifestLeafReferenceV1,\n observation: Exclude<InputClosureObservationV1, { kind: \"unmanifestable\" }>,\n resolverClass: InputResolverClassV1,\n completeThrough: string,\n): Promise<void> {\n switch (reference.evidence.kind) {\n case \"partition-receipt\": {\n if (leaf.source.kind !== \"partition-projection\" || resolverClass.kind !== \"partitioned\") {\n fail(\"partition receipt evidence requires a partition projection leaf\");\n }\n const commit = await partitions.readCommit(reference.evidence.receipt);\n const receipt = commit.receipt;\n const projected: PartitionProjectionV1 = {\n kind: \"partition-projection\",\n dataset: receipt.dataset,\n partition: receipt.partition,\n relativePath: receipt.relativePath,\n session: receipt.partition[resolverClass.sessionKey],\n schemaRevision: receipt.schemaRevision,\n coverage: receipt.coverage,\n quality: receipt.quality,\n file: receipt.file,\n };\n if (canonicalJson(projected) !== canonicalJson(leaf.source)) {\n fail(\"partition receipt does not reproduce the semantic leaf\");\n }\n const inspected = await partitions.inspectPartition({\n dataset: receipt.dataset,\n partition: receipt.partition,\n });\n if (\n inspected.status !== \"match\" ||\n inspected.receipt.address !== reference.evidence.receipt\n ) {\n fail(\"partition receipt is not the current exact-byte authority tip\");\n }\n return;\n }\n case \"content-object\": {\n if (leaf.source.kind !== \"control-file\" && leaf.source.kind !== \"materialized-slice\") {\n fail(\"content-object evidence requires an object-backed semantic leaf\");\n }\n if (leaf.source.object.address !== reference.evidence.object) {\n fail(\"content-object evidence address disagrees with the semantic leaf\");\n }\n const stored = await partitions.objects.get<unknown>(reference.evidence.object);\n if (canonicalJsonBytes(stored).byteLength !== leaf.source.object.bytes) {\n fail(\"content-object evidence byte length disagrees with the semantic leaf\");\n }\n return;\n }\n case \"absence-object\": {\n if (\n leaf.source.kind !== \"missing-probe\" ||\n observation.kind !== \"missing-probe\" ||\n resolverClass.kind !== \"partitioned\"\n ) {\n fail(\"absence-object evidence requires a missing-probe leaf\");\n }\n const evidence = await verifyMissingProbeEvidence(\n partitions.objects,\n reference.evidence.object,\n );\n if (\n evidence.registry !== leaf.registry ||\n evidence.dependency !== leaf.dependency ||\n evidence.completeThrough < completeThrough\n ) {\n fail(\"missing-probe evidence does not cover the requested dependency horizon\");\n }\n const inspected = await partitions.inspectPartition({\n dataset: resolverClass.dataset,\n partition: observation.selector,\n });\n if (inspected.status !== \"absent\") {\n fail(\"missing-probe evidence is stale because the partition is no longer absent\");\n }\n return;\n }\n }\n}\n\nasync function resolveManifestClasses(\n partitions: FilePartitionCommitStore,\n descriptor: InputClosureDescriptorV1,\n completeThrough: string,\n resolver: ManifestInputResolver,\n): Promise<readonly ManifestClassV1[]> {\n const cutoffClosure = restrictInputClosureDescriptor(descriptor, completeThrough);\n const registry = await verifyInputResolverRegistry(partitions.objects, cutoffClosure.registry);\n const entriesByClass = new Map<string, ManifestLeafReferenceV1[]>();\n const dependencies = new Set<string>();\n for (const observation of cutoffClosure.observations) {\n if (observation.kind === \"unmanifestable\") {\n fail(\n `input closure contains unmanifestable read ${JSON.stringify(observation.readClass)} (${observation.reasonCode})`,\n );\n }\n const dependency = dependencyKeyAddress(cutoffClosure.registry, observation);\n if (dependencies.has(dependency)) {\n fail(\"input closure contains more than one observation for the same stable dependency\");\n }\n dependencies.add(dependency);\n const resolution = await resolver.resolve({\n registry: registry.value,\n closure: cutoffClosure,\n observation,\n dependency,\n completeThrough,\n });\n if (resolution.kind !== \"resolved\") {\n fail(`input dependency is ${resolution.kind}: ${resolution.reasonCode}`);\n }\n const resolvedThrough = sessionDate(\n resolution.completeThrough,\n `resolved ${observation.dataClass} completeThrough`,\n );\n if (resolvedThrough < completeThrough) {\n fail(`resolved ${observation.dataClass} input does not reach the complete horizon`);\n }\n const resolverClass = registryClass(registry.value, observation.dataClass);\n const candidates = normalizeLeafReferences(\n resolution.entries,\n `resolved ${observation.dataClass} entries`,\n );\n const included: ManifestLeafReferenceV1[] = [];\n for (const reference of candidates) {\n const leaf = await verifySemanticInputLeaf(partitions.objects, reference.leaf);\n if (\n leaf.value.registry !== cutoffClosure.registry ||\n leaf.value.dependency !== dependency ||\n leaf.value.dataClass !== observation.dataClass\n ) {\n fail(\"resolved semantic leaf disagrees with its closure dependency\");\n }\n const posture = validateSourceAgainstObservation(\n leaf.value.source,\n observation,\n resolverClass,\n { allowRangeFuture: observation.kind === \"range\" },\n );\n if (posture === \"future\") continue;\n await verifyLeafEvidence(\n partitions,\n leaf.value,\n reference,\n observation,\n resolverClass,\n completeThrough,\n );\n included.push(reference);\n }\n if (included.length === 0) {\n fail(`resolved ${observation.dataClass} dependency has no applicable semantic leaves`);\n }\n if (observation.kind !== \"range\" && included.length !== 1) {\n fail(`${observation.kind} dependency must resolve to exactly one semantic leaf`);\n }\n const classEntries = entriesByClass.get(observation.dataClass) ?? [];\n classEntries.push(...included);\n entriesByClass.set(observation.dataClass, classEntries);\n }\n return [...entriesByClass.entries()]\n .sort(([left], [right]) => compareUnicodeCodePoints(left, right))\n .map(([dataClass, entries]) => createManifestClass(dataClass, completeThrough, entries));\n}\n\nexport async function publishCutoffManifest(\n partitions: FilePartitionCommitStore,\n input: {\n closure: CanonicalJsonAddress;\n completeThrough: string;\n resolver: ManifestInputResolver;\n refreshCompletion?: CanonicalJsonAddress;\n predecessor?: { manifest: CanonicalJsonAddress; aggregateRoot: Sha256Address };\n },\n): Promise<PutContentObjectResult<CutoffManifestV1>> {\n // Capture every caller-owned semantic field before the first await. Mutable\n // input objects must not let verification and publication use two closures.\n const closureAddress = address(input.closure, \"cutoff manifest closure\");\n const completeThrough = sessionDate(input.completeThrough, \"cutoff manifest completeThrough\");\n const resolver = input.resolver;\n const refreshCompletion = input.refreshCompletion\n ? address(input.refreshCompletion, \"cutoff manifest refreshCompletion\")\n : undefined;\n const predecessor = input.predecessor\n ? normalizePredecessor(input.predecessor, \"cutoff manifest predecessor\")\n : undefined;\n const closure = await verifyInputClosure(partitions.objects, closureAddress);\n const classes = await resolveManifestClasses(\n partitions,\n closure.value,\n completeThrough,\n resolver,\n );\n if (refreshCompletion) await partitions.objects.get<unknown>(refreshCompletion);\n const value = createCutoffManifestValue(\n closureAddress,\n completeThrough,\n classes,\n refreshCompletion,\n predecessor,\n );\n const published = await partitions.objects.put(value);\n // Evidence checks span multiple independently locked resources. Re-resolve\n // after immutable publication so a repair or control change during the first\n // pass makes this object an unadvertised orphan instead of a successful mint.\n const finalClasses = await resolveManifestClasses(\n partitions,\n closure.value,\n completeThrough,\n resolver,\n );\n const finalValue = createCutoffManifestValue(\n closureAddress,\n completeThrough,\n finalClasses,\n refreshCompletion,\n predecessor,\n );\n if (!canonicalJsonBytes(finalValue).equals(canonicalJsonBytes(value))) {\n fail(\"market inputs changed during cutoff manifest publication\");\n }\n return published;\n}\n\nexport async function verifyCutoffManifest(\n partitions: FilePartitionCommitStore,\n manifestAddress: CanonicalJsonAddress,\n resolver: ManifestInputResolver,\n): Promise<{ address: CanonicalJsonAddress; manifest: CutoffManifestV1 }> {\n address(manifestAddress, \"cutoff manifest address\");\n const stored = await partitions.objects.get<unknown>(manifestAddress);\n const manifest = normalizeCutoffManifest(stored);\n if (!canonicalJsonBytes(manifest).equals(canonicalJsonBytes(stored))) {\n fail(\"cutoff manifest is not normalized and deterministically ordered\");\n }\n if (manifest.refreshCompletion) {\n await partitions.objects.get<unknown>(manifest.refreshCompletion);\n }\n const closure = await verifyInputClosure(partitions.objects, manifest.closure);\n const classes = await resolveManifestClasses(\n partitions,\n closure.value,\n manifest.completeThrough,\n resolver,\n );\n const expected = createCutoffManifestValue(\n manifest.closure,\n manifest.completeThrough,\n classes,\n manifest.refreshCompletion,\n manifest.predecessor,\n );\n if (!canonicalJsonBytes(expected).equals(canonicalJsonBytes(manifest))) {\n fail(\"cutoff manifest does not match the resolver-owned complete input set\");\n }\n return { address: manifestAddress, manifest };\n}\n\nexport async function proveCutoffManifestPrefix(\n partitions: FilePartitionCommitStore,\n ancestorAddress: CanonicalJsonAddress,\n descendantAddress: CanonicalJsonAddress,\n resolver: ManifestInputResolver,\n): Promise<{ valid: boolean; reason?: string }> {\n const ancestor = await verifyCutoffManifest(partitions, ancestorAddress, resolver);\n const descendant = await verifyCutoffManifest(partitions, descendantAddress, resolver);\n // Prefix is reflexive for one immutable, content-addressed manifest. This is\n // the producer proof used by already-current resume operations: both reads\n // above still re-verify the exact object before equality is accepted.\n if (ancestorAddress === descendantAddress) {\n return { valid: true };\n }\n if (ancestor.manifest.completeThrough >= descendant.manifest.completeThrough) {\n return { valid: false, reason: \"cutoff-not-increasing\" };\n }\n const ancestorClosure = await verifyInputClosure(partitions.objects, ancestor.manifest.closure);\n const descendantClosure = await verifyInputClosure(\n partitions.objects,\n descendant.manifest.closure,\n );\n if (ancestorClosure.value.registry !== descendantClosure.value.registry) {\n return { valid: false, reason: \"registry-mismatch\" };\n }\n const restricted = restrictInputClosureDescriptor(\n descendantClosure.value,\n ancestor.manifest.completeThrough,\n );\n if (canonicalJson(restricted) !== canonicalJson(ancestorClosure.value)) {\n return { valid: false, reason: \"closure-restriction-mismatch\" };\n }\n if (\n descendant.manifest.predecessor &&\n (descendant.manifest.predecessor.manifest !== ancestorAddress ||\n descendant.manifest.predecessor.aggregateRoot !== ancestor.manifest.aggregateRoot)\n ) {\n return { valid: false, reason: \"predecessor-hint-mismatch\" };\n }\n const ancestorByClass = new Map(\n ancestor.manifest.classes.map((entry) => [entry.dataClass, entry]),\n );\n const descendantByClass = new Map(\n descendant.manifest.classes.map((entry) => [entry.dataClass, entry]),\n );\n if (!sameStringSet([...ancestorByClass.keys()], [...descendantByClass.keys()])) {\n return { valid: false, reason: \"class-set-mismatch\" };\n }\n const registry = await verifyInputResolverRegistry(\n partitions.objects,\n ancestorClosure.value.registry,\n );\n for (const [dataClass, ancestorClass] of ancestorByClass) {\n const descendantClass = descendantByClass.get(dataClass) as ManifestClassV1;\n const resolverClass = registryClass(registry.value, dataClass);\n let retained: readonly ManifestLeafReferenceV1[];\n if (resolverClass.kind === \"static\" && resolver.projectStaticPrefix) {\n retained = await resolver.projectStaticPrefix({\n registry: registry.value,\n registryAddress: ancestorClosure.value.registry,\n dataClass,\n ancestorCompleteThrough: ancestor.manifest.completeThrough,\n descendantCompleteThrough: descendant.manifest.completeThrough,\n descendantEntries: descendantClass.entries,\n });\n } else {\n const historical: ManifestLeafReferenceV1[] = [];\n for (const reference of descendantClass.entries) {\n const leaf = await verifySemanticInputLeaf(partitions.objects, reference.leaf);\n if (\n leaf.value.scope.kind === \"static\" ||\n leaf.value.scope.session <= ancestor.manifest.completeThrough\n ) {\n historical.push(reference);\n }\n }\n retained = historical;\n }\n const normalizedRetained = normalizeLeafReferences(retained, `prefix ${dataClass} entries`);\n for (const reference of normalizedRetained) {\n const leaf = await verifySemanticInputLeaf(partitions.objects, reference.leaf);\n if (\n leaf.value.registry !== ancestorClosure.value.registry ||\n leaf.value.dataClass !== dataClass\n ) {\n fail(\"prefix projection returned a leaf outside the manifest class\");\n }\n if (resolverClass.kind === \"static\" && leaf.value.scope.kind !== \"static\") {\n fail(\"static prefix projection returned a session-scoped leaf\");\n }\n }\n if (\n canonicalJson(normalizedRetained.map((entry) => entry.leaf)) !==\n canonicalJson(ancestorClass.entries.map((entry) => entry.leaf))\n ) {\n return { valid: false, reason: \"historical-leaf-mismatch\" };\n }\n const reproduced = createManifestClass(\n dataClass,\n ancestor.manifest.completeThrough,\n normalizedRetained,\n );\n if (reproduced.root !== ancestorClass.root) {\n return { valid: false, reason: \"historical-root-mismatch\" };\n }\n }\n // Prefix authorization must end on a fresh currentness pass; otherwise a\n // repair racing the proof walk could be accepted after its evidence changed.\n await verifyCutoffManifest(partitions, ancestorAddress, resolver);\n await verifyCutoffManifest(partitions, descendantAddress, resolver);\n return { valid: true };\n}\n","import * as path from \"node:path\";\nimport {\n canonicalJson,\n canonicalJsonBytes,\n parseCanonicalJsonAddress,\n parseSha256Address,\n type CanonicalJsonAddress,\n type Sha256Address,\n} from \"./canonical-json.ts\";\nimport type { PutContentObjectResult } from \"./content-object-store.ts\";\nimport {\n canonicalPartitionDataset,\n canonicalPartitionRelativePath,\n validatePartitionIdentity,\n type DatasetPartitionIdentity,\n} from \"./dataset-registry.ts\";\nimport {\n runPartitionCommitAttempt,\n type PartitionCommitAttemptResult,\n} from \"./partition-commit-attempt.ts\";\nimport {\n FilePartitionCommitStore,\n publishRefreshCompletionAuthority,\n verifyRefreshCompletionAuthority,\n type StoredPartitionCommit,\n} from \"./partition-commit-store.ts\";\nimport { isXnysSessionDate } from \"./xnys-session-calendar.ts\";\nimport {\n finalizeCanonicalMarketDataCutoff,\n verifyCanonicalMarketDataCutoff,\n} from \"./canonical-market-resolver.ts\";\nimport { verifyInputClosure, verifyInputResolverRegistry } from \"./content-manifest.ts\";\nimport type { MarketIngestor, MarketIngestorDeps } from \"../ingestor/market-ingestor.ts\";\nimport type {\n BulkProgressEvent,\n BulkProgressReporter,\n IngestResult,\n RefreshOptions,\n RefreshResult,\n} from \"../ingestor/types.ts\";\nimport { bulkQuoteRootsForUnderlying } from \"../../utils/providers/thetadata/bulk-roots.ts\";\nimport { getEnrichedThrough, upsertEnrichedThrough } from \"../../db/json-adapters.ts\";\n\nexport const CANONICAL_REFRESH_COMPLETION_KIND =\n \"tradeblocks.market-data.canonical-refresh-completion\" as const;\nexport const CANONICAL_REFRESH_COMPLETION_VERSION = 2 as const;\n\nexport interface CanonicalRefreshPlanV2 {\n asOf: string;\n spotTickers: readonly string[];\n enrichedTickers: readonly string[];\n includeEnrichedContext: boolean;\n chainUnderlyings: readonly string[];\n quoteUnderlyings: readonly string[];\n openInterestUnderlyings: readonly string[];\n provider?: \"massive\" | \"thetadata\";\n}\n\nexport interface CanonicalRefreshReceiptV1 extends DatasetPartitionIdentity {\n receipt: CanonicalJsonAddress;\n}\n\nexport interface CanonicalRefreshOperationV1 {\n kind: \"spot\" | \"chain\" | \"quotes\" | \"open-interest\";\n target: string;\n status: \"ok\";\n rowsWritten: number;\n}\n\nexport interface CanonicalRefreshQuoteGroupV1 {\n underlying: string;\n root: string;\n right: \"call\" | \"put\";\n date: string;\n completedContracts: number;\n totalContracts: number;\n}\n\nexport interface CanonicalRefreshCompletionV2 {\n kind: typeof CANONICAL_REFRESH_COMPLETION_KIND;\n version: typeof CANONICAL_REFRESH_COMPLETION_VERSION;\n attemptId: string;\n closure: CanonicalJsonAddress;\n plan: CanonicalRefreshPlanV2;\n operations: readonly CanonicalRefreshOperationV1[];\n quoteGroups: readonly CanonicalRefreshQuoteGroupV1[];\n receipts: readonly CanonicalRefreshReceiptV1[];\n}\n\ninterface BoundedRefreshResult {\n perOperation: RefreshResult[\"perOperation\"];\n quoteGroups: readonly CanonicalRefreshQuoteGroupV1[];\n}\n\ninterface CanonicalProvenanceRefreshOptions {\n closure: CanonicalJsonAddress;\n attemptId: string;\n predecessor?: { manifest: CanonicalJsonAddress; aggregateRoot: Sha256Address };\n}\n\ntype ProvenanceRefreshInput = RefreshOptions & {\n provenance: CanonicalProvenanceRefreshOptions;\n};\n\nfunction normalizeAuthority(\n input: CanonicalProvenanceRefreshOptions,\n): CanonicalProvenanceRefreshOptions {\n parseCanonicalJsonAddress(input.closure);\n const attemptId = input.attemptId.normalize(\"NFC\").trim();\n if (attemptId.length === 0) throw new TypeError(\"Canonical refresh attemptId must not be empty\");\n const predecessor = input.predecessor\n ? {\n manifest: input.predecessor.manifest,\n aggregateRoot: input.predecessor.aggregateRoot,\n }\n : undefined;\n if (predecessor) {\n parseCanonicalJsonAddress(predecessor.manifest);\n parseSha256Address(predecessor.aggregateRoot);\n }\n return Object.freeze({\n closure: input.closure,\n attemptId,\n ...(predecessor ? { predecessor: Object.freeze(predecessor) } : {}),\n });\n}\n\nfunction compareCodePoints(left: string, right: string): number {\n const leftPoints = Array.from(left, (character) => character.codePointAt(0) as number);\n const rightPoints = Array.from(right, (character) => character.codePointAt(0) as number);\n const length = Math.min(leftPoints.length, rightPoints.length);\n for (let index = 0; index < length; index += 1) {\n if (leftPoints[index] !== rightPoints[index]) return leftPoints[index] - rightPoints[index];\n }\n return leftPoints.length - rightPoints.length;\n}\n\nfunction normalizedSymbols(values: readonly string[] | undefined, label: string): string[] {\n const normalized = (values ?? []).map((value, index) => {\n if (typeof value !== \"string\") throw new TypeError(`${label}[${index}] must be a string`);\n const symbol = value.normalize(\"NFC\").trim().toUpperCase();\n if (!/^[A-Z][A-Z0-9._-]*$/.test(symbol)) {\n throw new TypeError(`${label}[${index}] is not a canonical market symbol`);\n }\n return symbol;\n });\n return [...new Set(normalized)].sort(compareCodePoints);\n}\n\nfunction normalizePlan(input: RefreshOptions, deps: MarketIngestorDeps): CanonicalRefreshPlanV2 {\n if (!isXnysSessionDate(input.asOf)) {\n throw new Error(`Canonical refresh cutoff is not a supported XNYS session: ${input.asOf}`);\n }\n if ((input.quoteTickers?.length ?? 0) > 0) {\n throw new Error(\n \"Canonical refresh refuses quoteTickers because per-ticker writes overwrite a shared partition\",\n );\n }\n const rawQuoteUnderlyings = normalizedSymbols(input.quoteUnderlyings, \"quoteUnderlyings\");\n const quoteUnderlyings = normalizedSymbols(\n rawQuoteUnderlyings.map((underlying) => deps.stores.quote.tickers.resolve(underlying)),\n \"resolved quoteUnderlyings\",\n );\n const rawOiUnderlyings = normalizedSymbols(\n input.openInterestUnderlyings,\n \"openInterestUnderlyings\",\n );\n const openInterestUnderlyings = normalizedSymbols(\n rawOiUnderlyings.map((underlying) => deps.stores.quote.tickers.resolve(underlying)),\n \"resolved openInterestUnderlyings\",\n );\n if (\n (quoteUnderlyings.length > 0 || openInterestUnderlyings.length > 0) &&\n input.provider !== \"thetadata\"\n ) {\n throw new Error(\"Canonical option refresh requires the explicit ThetaData terminal protocol\");\n }\n const plan: CanonicalRefreshPlanV2 = {\n asOf: input.asOf,\n spotTickers: normalizedSymbols(input.spotTickers, \"spotTickers\"),\n enrichedTickers: [],\n includeEnrichedContext: false,\n chainUnderlyings: normalizedSymbols(input.chainUnderlyings, \"chainUnderlyings\"),\n quoteUnderlyings,\n openInterestUnderlyings,\n ...(input.provider ? { provider: input.provider } : {}),\n };\n return Object.freeze({\n ...plan,\n spotTickers: Object.freeze(plan.spotTickers),\n enrichedTickers: Object.freeze(plan.enrichedTickers),\n chainUnderlyings: Object.freeze(plan.chainUnderlyings),\n quoteUnderlyings: Object.freeze(plan.quoteUnderlyings),\n openInterestUnderlyings: Object.freeze(plan.openInterestUnderlyings),\n });\n}\n\nfunction expectedInventory(plan: CanonicalRefreshPlanV2): DatasetPartitionIdentity[] {\n const session = plan.asOf;\n return [\n ...plan.spotTickers.map((ticker) => ({\n dataset: \"spot\",\n partition: { ticker, date: session },\n })),\n ...plan.enrichedTickers.map((ticker) => ({\n dataset: \"enriched\",\n partition: { ticker, date: session },\n })),\n ...(plan.includeEnrichedContext\n ? [{ dataset: \"enriched_context\", partition: { date: session } }]\n : []),\n ...plan.chainUnderlyings.map((underlying) => ({\n dataset: \"option_chain\",\n partition: { underlying, date: session },\n })),\n ...plan.quoteUnderlyings.map((underlying) => ({\n dataset: \"option_quote_minutes\",\n partition: { underlying, date: session },\n })),\n ...plan.openInterestUnderlyings.map((underlying) => ({\n dataset: \"option_oi_daily\",\n partition: { underlying, date: session },\n })),\n ];\n}\n\nfunction validateDerivedPlanInputs(plan: CanonicalRefreshPlanV2): void {\n if (plan.enrichedTickers.some((ticker) => !plan.spotTickers.includes(ticker))) {\n throw new Error(\"Canonical enriched cutoff requires same-session spot refresh for its ticker\");\n }\n if (plan.includeEnrichedContext) {\n const requiredContextSpot = [\"SPX\", \"VIX\", \"VIX9D\", \"VIX3M\"];\n if (requiredContextSpot.some((ticker) => !plan.spotTickers.includes(ticker))) {\n throw new Error(\n \"Canonical enriched context requires same-session SPX/VIX/VIX9D/VIX3M spot refresh\",\n );\n }\n }\n}\n\nasync function closureTailInventory(\n partitions: FilePartitionCommitStore,\n closureAddress: CanonicalJsonAddress,\n completeThrough: string,\n): Promise<DatasetPartitionIdentity[]> {\n const closure = await verifyInputClosure(partitions.objects, closureAddress);\n const registry = await verifyInputResolverRegistry(partitions.objects, closure.value.registry);\n const identities: DatasetPartitionIdentity[] = [];\n for (const observation of closure.value.observations) {\n if (observation.kind === \"missing-probe\" && observation.session === completeThrough) {\n throw new Error(\"A cutoff missing-probe cannot satisfy refresh completion authority\");\n }\n if (observation.kind !== \"exact\" && observation.kind !== \"range\") continue;\n const reachesCutoff =\n observation.kind === \"exact\"\n ? observation.session === completeThrough\n : observation.fromSession <= completeThrough &&\n observation.throughSession >= completeThrough;\n if (!reachesCutoff) continue;\n const resolverClass = registry.value.classes.find(\n (entry) => entry.dataClass === observation.dataClass,\n );\n if (resolverClass?.kind === \"materialized\") continue;\n if (!resolverClass || resolverClass.kind !== \"partitioned\") {\n throw new Error(\"Cutoff closure tail is not a canonical partitioned input class\");\n }\n const identity: DatasetPartitionIdentity = {\n dataset: resolverClass.dataset,\n partition:\n observation.kind === \"exact\"\n ? observation.selector\n : {\n ...observation.selectorPrefix,\n [resolverClass.sessionKey]: completeThrough,\n },\n };\n validatePartitionIdentity(identity);\n identities.push(identity);\n }\n identities.sort((left, right) => compareCodePoints(identityKey(left), identityKey(right)));\n if (identities.length === 0) {\n throw new Error(\"Canonical refresh closure has no partitioned cutoff-tail inventory\");\n }\n if (new Set(identities.map(identityKey)).size !== identities.length) {\n throw new Error(\"Canonical refresh closure repeats a cutoff-tail partition\");\n }\n return identities;\n}\n\nasync function bindPlanToClosure(\n partitions: FilePartitionCommitStore,\n closure: CanonicalJsonAddress,\n base: CanonicalRefreshPlanV2,\n): Promise<CanonicalRefreshPlanV2> {\n const inventory = await closureTailInventory(partitions, closure, base.asOf);\n const enrichedTickers = inventory\n .filter((identity) => identity.dataset === \"enriched\")\n .map((identity) => identity.partition.ticker)\n .sort(compareCodePoints);\n const includeEnrichedContext = inventory.some(\n (identity) => identity.dataset === \"enriched_context\",\n );\n const rawInventory = inventory.filter(\n (identity) => identity.dataset !== \"enriched\" && identity.dataset !== \"enriched_context\",\n );\n if (\n canonicalJson(rawInventory.map(identityKey)) !==\n canonicalJson(expectedInventory(base).map(identityKey).sort(compareCodePoints))\n ) {\n throw new Error(\"Canonical refresh request does not equal the closure raw cutoff inventory\");\n }\n if (inventory.length === 0) throw new Error(\"Canonical refresh inventory must not be empty\");\n const plan = Object.freeze({\n ...base,\n enrichedTickers: Object.freeze(enrichedTickers),\n includeEnrichedContext,\n });\n validateDerivedPlanInputs(plan);\n return plan;\n}\n\nfunction identityKey(identity: DatasetPartitionIdentity): string {\n return canonicalJson({ dataset: identity.dataset, partition: identity.partition });\n}\n\nfunction requireTerminalResult(result: IngestResult, label: string): IngestResult {\n if (result.status !== \"ok\" || result.rowsWritten <= 0 || (result.skipped?.length ?? 0) > 0) {\n throw new Error(\n `Canonical refresh operation ${label} was not terminal: ${canonicalJson({\n status: result.status,\n rowsWritten: result.rowsWritten,\n skipped: result.skipped?.length ?? 0,\n error: result.error ?? \"\",\n })}`,\n );\n }\n return result;\n}\n\nasync function runBoundedRefresh(\n ingestor: MarketIngestor,\n plan: CanonicalRefreshPlanV2,\n onProgress: BulkProgressReporter | undefined,\n): Promise<BoundedRefreshResult> {\n const spot: IngestResult[] = [];\n for (const ticker of plan.spotTickers) {\n spot.push(\n requireTerminalResult(\n await ingestor.ingestBars({\n tickers: [ticker],\n from: plan.asOf,\n to: plan.asOf,\n timespan: \"1m\",\n skipEnrichment: true,\n ...(plan.provider ? { provider: plan.provider } : {}),\n }),\n `spot ${ticker}`,\n ),\n );\n }\n const chain: IngestResult[] = [];\n for (const underlying of plan.chainUnderlyings) {\n chain.push(\n requireTerminalResult(\n await ingestor.ingestChain({\n underlyings: [underlying],\n from: plan.asOf,\n to: plan.asOf,\n ...(plan.provider ? { provider: plan.provider } : {}),\n }),\n `chain ${underlying}`,\n ),\n );\n }\n const quotes: IngestResult[] = [];\n const quoteGroups: CanonicalRefreshQuoteGroupV1[] = [];\n for (const underlying of plan.quoteUnderlyings) {\n const observed = new Map<string, CanonicalRefreshQuoteGroupV1>();\n const poisoned = new Set<string>();\n const collectProgress = async (event: BulkProgressEvent) => {\n if (event.kind === \"group\" && event.phase === \"complete\") {\n const key = `${event.root.toUpperCase()}:${event.right}`;\n if (\n event.underlying.toUpperCase() === underlying &&\n event.date === plan.asOf &&\n event.status === \"ok\" &&\n Number.isSafeInteger(event.completedContracts) &&\n Number.isSafeInteger(event.totalContracts) &&\n (event.completedContracts as number) >= 0 &&\n event.completedContracts === event.totalContracts\n ) {\n if (!poisoned.has(key)) {\n observed.set(key, {\n underlying,\n root: event.root.toUpperCase(),\n right: event.right,\n date: plan.asOf,\n completedContracts: event.completedContracts as number,\n totalContracts: event.totalContracts as number,\n });\n }\n } else {\n poisoned.add(key);\n observed.delete(key);\n }\n }\n await onProgress?.(event);\n };\n quotes.push(\n requireTerminalResult(\n await ingestor.ingestQuotes({\n underlyings: [underlying],\n from: plan.asOf,\n to: plan.asOf,\n ...(plan.provider ? { provider: plan.provider } : {}),\n onProgress: collectProgress,\n }),\n `quotes ${underlying}`,\n ),\n );\n const expected = bulkQuoteRootsForUnderlying(underlying)\n .flatMap((root) => [`${root}:call`, `${root}:put`])\n .sort(compareCodePoints);\n const completed = [...observed.keys()].sort(compareCodePoints);\n if (\n canonicalJson(completed) !== canonicalJson(expected) ||\n expected.some((key) => poisoned.has(key))\n ) {\n throw new Error(\n `Canonical quote refresh did not complete every root/right group: ${canonicalJson({ expected, completed })}`,\n );\n }\n quoteGroups.push(...observed.values());\n }\n const openInterest: IngestResult[] = [];\n for (const underlying of plan.openInterestUnderlyings) {\n openInterest.push(\n requireTerminalResult(\n await ingestor.ingestOpenInterest({\n underlyings: [underlying],\n from: plan.asOf,\n to: plan.asOf,\n ...(plan.provider ? { provider: plan.provider } : {}),\n }),\n `open interest ${underlying}`,\n ),\n );\n }\n quoteGroups.sort((left, right) =>\n compareCodePoints(\n `${left.underlying}:${left.root}:${left.right}`,\n `${right.underlying}:${right.root}:${right.right}`,\n ),\n );\n return {\n perOperation: { spot, chain, quotes, openInterest, vixContext: null },\n quoteGroups,\n };\n}\n\nfunction operationKey(operation: Pick<CanonicalRefreshOperationV1, \"kind\" | \"target\">): string {\n return `${operation.kind}:${operation.target}`;\n}\n\nfunction terminalOperations(\n plan: CanonicalRefreshPlanV2,\n value: BoundedRefreshResult[\"perOperation\"],\n): CanonicalRefreshOperationV1[] {\n if (\n value.spot.length !== plan.spotTickers.length ||\n value.chain.length !== plan.chainUnderlyings.length ||\n value.quotes.length !== plan.quoteUnderlyings.length ||\n value.openInterest.length !== plan.openInterestUnderlyings.length ||\n value.vixContext !== null\n ) {\n throw new Error(\"Canonical refresh terminal operation evidence disagrees with its plan\");\n }\n const operations: CanonicalRefreshOperationV1[] = [\n ...plan.spotTickers.map((target, index) => ({\n kind: \"spot\" as const,\n target,\n status: \"ok\" as const,\n rowsWritten: value.spot[index].rowsWritten,\n })),\n ...plan.chainUnderlyings.map((target, index) => ({\n kind: \"chain\" as const,\n target,\n status: \"ok\" as const,\n rowsWritten: value.chain[index].rowsWritten,\n })),\n ...plan.quoteUnderlyings.map((target, index) => ({\n kind: \"quotes\" as const,\n target,\n status: \"ok\" as const,\n rowsWritten: value.quotes[index].rowsWritten,\n })),\n ...plan.openInterestUnderlyings.map((target, index) => ({\n kind: \"open-interest\" as const,\n target,\n status: \"ok\" as const,\n rowsWritten: value.openInterest[index].rowsWritten,\n })),\n ];\n operations.sort((left, right) => compareCodePoints(operationKey(left), operationKey(right)));\n return operations;\n}\n\nfunction expectedOperationKeys(plan: CanonicalRefreshPlanV2): string[] {\n return [\n ...plan.spotTickers.map((target) => operationKey({ kind: \"spot\", target })),\n ...plan.chainUnderlyings.map((target) => operationKey({ kind: \"chain\", target })),\n ...plan.quoteUnderlyings.map((target) => operationKey({ kind: \"quotes\", target })),\n ...plan.openInterestUnderlyings.map((target) =>\n operationKey({ kind: \"open-interest\", target }),\n ),\n ].sort(compareCodePoints);\n}\n\nfunction operationIdentity(\n operation: CanonicalRefreshOperationV1,\n asOf: string,\n): DatasetPartitionIdentity {\n switch (operation.kind) {\n case \"spot\":\n return { dataset: \"spot\", partition: { ticker: operation.target, date: asOf } };\n case \"chain\":\n return {\n dataset: \"option_chain\",\n partition: { underlying: operation.target, date: asOf },\n };\n case \"quotes\":\n return {\n dataset: \"option_quote_minutes\",\n partition: { underlying: operation.target, date: asOf },\n };\n case \"open-interest\":\n return {\n dataset: \"option_oi_daily\",\n partition: { underlying: operation.target, date: asOf },\n };\n }\n}\n\nfunction validateAttemptInventory(\n plan: CanonicalRefreshPlanV2,\n attempt: PartitionCommitAttemptResult<BoundedRefreshResult>,\n): void {\n const expected = new Map(\n expectedInventory(plan).map((identity) => [identityKey(identity), identity]),\n );\n const observed = new Map(\n attempt.receipts.map((commit) => [identityKey(commit.receipt), commit] as const),\n );\n if (expected.size !== observed.size || [...expected.keys()].some((key) => !observed.has(key))) {\n throw new Error(\n `Canonical refresh receipts do not equal the producer inventory: ${canonicalJson({\n expected: [...expected.keys()].sort(compareCodePoints),\n observed: [...observed.keys()].sort(compareCodePoints),\n })}`,\n );\n }\n}\n\nasync function validateCurrentReceipt(\n partitions: FilePartitionCommitStore,\n plan: CanonicalRefreshPlanV2,\n commit: StoredPartitionCommit,\n): Promise<void> {\n const receipt = commit.receipt;\n const definition = canonicalPartitionDataset(receipt.dataset);\n if (!definition)\n throw new Error(`Canonical refresh receipt has unknown dataset ${receipt.dataset}`);\n const session = receipt.partition[definition.provenance.sessionKey];\n if (\n session !== plan.asOf ||\n receipt.schemaRevision !== definition.schemaRevision ||\n receipt.relativePath !== canonicalPartitionRelativePath(receipt) ||\n receipt.coverage.kind !== \"date-range\" ||\n receipt.coverage.from !== plan.asOf ||\n receipt.coverage.through !== plan.asOf ||\n receipt.file.rows <= 0 ||\n receipt.quality.inputRows !== receipt.quality.writtenRows ||\n receipt.quality.writtenRows !== receipt.file.rows ||\n receipt.quality.droppedRows !== 0\n ) {\n throw new Error(`Canonical refresh receipt is not a complete zero-drop cutoff partition`);\n }\n const inspected = await partitions.inspectPartition(receipt);\n if (inspected.status !== \"match\" || inspected.receipt.address !== commit.address) {\n throw new Error(\"Canonical refresh receipt is not the current exact-byte authority tip\");\n }\n}\n\nfunction receiptValue(commit: StoredPartitionCommit): CanonicalRefreshReceiptV1 {\n return {\n dataset: commit.receipt.dataset,\n partition: commit.receipt.partition,\n receipt: commit.address,\n };\n}\n\nfunction normalizeCompletion(value: unknown): CanonicalRefreshCompletionV2 {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n throw new Error(\"Canonical refresh completion must be an object\");\n }\n const record = value as Record<string, unknown>;\n const keys = Object.keys(record).sort(compareCodePoints);\n if (\n canonicalJson(keys) !==\n canonicalJson([\n \"attemptId\",\n \"closure\",\n \"kind\",\n \"operations\",\n \"plan\",\n \"quoteGroups\",\n \"receipts\",\n \"version\",\n ])\n ) {\n throw new Error(\"Canonical refresh completion has unknown or missing fields\");\n }\n if (\n record.kind !== CANONICAL_REFRESH_COMPLETION_KIND ||\n record.version !== CANONICAL_REFRESH_COMPLETION_VERSION\n ) {\n throw new Error(\"Canonical refresh completion identity is invalid\");\n }\n if (typeof record.attemptId !== \"string\" || record.attemptId.trim().length === 0) {\n throw new Error(\"Canonical refresh completion attemptId is invalid\");\n }\n const attemptId = record.attemptId.normalize(\"NFC\").trim();\n if (typeof record.closure !== \"string\") {\n throw new Error(\"Canonical refresh completion closure is invalid\");\n }\n parseCanonicalJsonAddress(record.closure);\n if (record.plan === null || typeof record.plan !== \"object\" || Array.isArray(record.plan)) {\n throw new Error(\"Canonical refresh completion plan must be an object\");\n }\n const planRecord = record.plan as Record<string, unknown>;\n const planKeys = Object.keys(planRecord).sort(compareCodePoints);\n const expectedPlanKeys = [\n \"asOf\",\n \"chainUnderlyings\",\n \"enrichedTickers\",\n \"includeEnrichedContext\",\n \"openInterestUnderlyings\",\n \"quoteUnderlyings\",\n \"spotTickers\",\n ...(Object.hasOwn(planRecord, \"provider\") ? [\"provider\"] : []),\n ].sort(compareCodePoints);\n if (canonicalJson(planKeys) !== canonicalJson(expectedPlanKeys)) {\n throw new Error(\"Canonical refresh completion plan has unknown or missing fields\");\n }\n const plan: CanonicalRefreshPlanV2 = {\n asOf: String(planRecord.asOf),\n spotTickers: normalizedSymbols(planRecord.spotTickers as string[], \"plan.spotTickers\"),\n enrichedTickers: normalizedSymbols(\n planRecord.enrichedTickers as string[],\n \"plan.enrichedTickers\",\n ),\n includeEnrichedContext:\n typeof planRecord.includeEnrichedContext === \"boolean\"\n ? planRecord.includeEnrichedContext\n : (() => {\n throw new Error(\"Canonical refresh completion enriched context intent is invalid\");\n })(),\n chainUnderlyings: normalizedSymbols(\n planRecord.chainUnderlyings as string[],\n \"plan.chainUnderlyings\",\n ),\n quoteUnderlyings: normalizedSymbols(\n planRecord.quoteUnderlyings as string[],\n \"plan.quoteUnderlyings\",\n ),\n openInterestUnderlyings: normalizedSymbols(\n planRecord.openInterestUnderlyings as string[],\n \"plan.openInterestUnderlyings\",\n ),\n ...(planRecord.provider === undefined\n ? {}\n : planRecord.provider === \"massive\" || planRecord.provider === \"thetadata\"\n ? { provider: planRecord.provider }\n : (() => {\n throw new Error(\"Canonical refresh completion provider is invalid\");\n })()),\n };\n validateDerivedPlanInputs(plan);\n if (!isXnysSessionDate(plan.asOf) || expectedInventory(plan).length === 0) {\n throw new Error(\"Canonical refresh completion plan is empty or outside the calendar\");\n }\n if (!Array.isArray(record.operations) || record.operations.length === 0) {\n throw new Error(\"Canonical refresh completion operations must be a non-empty array\");\n }\n const operations = record.operations.map((entry, index) => {\n if (entry === null || typeof entry !== \"object\" || Array.isArray(entry)) {\n throw new Error(`Canonical refresh completion operations[${index}] must be an object`);\n }\n const operation = entry as Record<string, unknown>;\n if (\n canonicalJson(Object.keys(operation).sort(compareCodePoints)) !==\n canonicalJson([\"kind\", \"rowsWritten\", \"status\", \"target\"])\n ) {\n throw new Error(`Canonical refresh completion operations[${index}] has invalid fields`);\n }\n if (\n operation.kind !== \"spot\" &&\n operation.kind !== \"chain\" &&\n operation.kind !== \"quotes\" &&\n operation.kind !== \"open-interest\"\n ) {\n throw new Error(`Canonical refresh completion operations[${index}] kind is invalid`);\n }\n const target = normalizedSymbols(\n [operation.target as string],\n `operations[${index}].target`,\n )[0];\n if (\n operation.status !== \"ok\" ||\n !Number.isSafeInteger(operation.rowsWritten) ||\n (operation.rowsWritten as number) <= 0\n ) {\n throw new Error(`Canonical refresh completion operations[${index}] is not terminal`);\n }\n return {\n kind: operation.kind as CanonicalRefreshOperationV1[\"kind\"],\n target,\n status: \"ok\" as const,\n rowsWritten: operation.rowsWritten as number,\n };\n });\n operations.sort((left, right) => compareCodePoints(operationKey(left), operationKey(right)));\n if (canonicalJson(operations.map(operationKey)) !== canonicalJson(expectedOperationKeys(plan))) {\n throw new Error(\"Canonical refresh completion operations disagree with its plan\");\n }\n if (!Array.isArray(record.quoteGroups)) {\n throw new Error(\"Canonical refresh completion quoteGroups must be an array\");\n }\n const quoteGroups = record.quoteGroups.map((entry, index) => {\n if (entry === null || typeof entry !== \"object\" || Array.isArray(entry)) {\n throw new Error(`Canonical refresh completion quoteGroups[${index}] must be an object`);\n }\n const group = entry as Record<string, unknown>;\n if (\n canonicalJson(Object.keys(group).sort(compareCodePoints)) !==\n canonicalJson([\"completedContracts\", \"date\", \"right\", \"root\", \"totalContracts\", \"underlying\"])\n ) {\n throw new Error(`Canonical refresh completion quoteGroups[${index}] has invalid fields`);\n }\n const underlying = normalizedSymbols(\n [group.underlying as string],\n `quoteGroups[${index}].underlying`,\n )[0];\n const root = normalizedSymbols([group.root as string], `quoteGroups[${index}].root`)[0];\n if (\n (group.right !== \"call\" && group.right !== \"put\") ||\n group.date !== plan.asOf ||\n !Number.isSafeInteger(group.completedContracts) ||\n !Number.isSafeInteger(group.totalContracts) ||\n (group.completedContracts as number) < 0 ||\n group.completedContracts !== group.totalContracts\n ) {\n throw new Error(`Canonical refresh completion quoteGroups[${index}] is not terminal`);\n }\n return {\n underlying,\n root,\n right: group.right as CanonicalRefreshQuoteGroupV1[\"right\"],\n date: plan.asOf,\n completedContracts: group.completedContracts as number,\n totalContracts: group.totalContracts as number,\n };\n });\n quoteGroups.sort((left, right) =>\n compareCodePoints(\n `${left.underlying}:${left.root}:${left.right}`,\n `${right.underlying}:${right.root}:${right.right}`,\n ),\n );\n const expectedQuoteGroups = plan.quoteUnderlyings\n .flatMap((underlying) =>\n bulkQuoteRootsForUnderlying(underlying).flatMap((root) => [\n `${underlying}:${root}:call`,\n `${underlying}:${root}:put`,\n ]),\n )\n .sort(compareCodePoints);\n if (\n canonicalJson(\n quoteGroups.map((group) => `${group.underlying}:${group.root}:${group.right}`),\n ) !== canonicalJson(expectedQuoteGroups)\n ) {\n throw new Error(\"Canonical refresh completion quoteGroups disagree with its plan\");\n }\n if (!Array.isArray(record.receipts) || record.receipts.length === 0) {\n throw new Error(\"Canonical refresh completion receipts must be a non-empty array\");\n }\n const receipts = record.receipts.map((entry, index) => {\n if (entry === null || typeof entry !== \"object\" || Array.isArray(entry)) {\n throw new Error(`Canonical refresh completion receipts[${index}] must be an object`);\n }\n const receipt = entry as Record<string, unknown>;\n if (\n canonicalJson(Object.keys(receipt).sort(compareCodePoints)) !==\n canonicalJson([\"dataset\", \"partition\", \"receipt\"])\n ) {\n throw new Error(`Canonical refresh completion receipts[${index}] has invalid fields`);\n }\n const normalized: CanonicalRefreshReceiptV1 = {\n dataset: String(receipt.dataset),\n partition: receipt.partition as Record<string, string>,\n receipt: receipt.receipt as CanonicalJsonAddress,\n };\n validatePartitionIdentity(normalized);\n parseCanonicalJsonAddress(normalized.receipt);\n return normalized;\n });\n receipts.sort((left, right) => compareCodePoints(identityKey(left), identityKey(right)));\n const normalized = {\n kind: CANONICAL_REFRESH_COMPLETION_KIND,\n version: CANONICAL_REFRESH_COMPLETION_VERSION,\n attemptId,\n closure: record.closure as CanonicalJsonAddress,\n plan,\n operations,\n quoteGroups,\n receipts,\n };\n if (!canonicalJsonBytes(normalized).equals(canonicalJsonBytes(value))) {\n throw new Error(\"Canonical refresh completion is not normalized\");\n }\n return normalized;\n}\n\nexport async function verifyCanonicalRefreshCompletion(\n partitions: FilePartitionCommitStore,\n completionAddress: CanonicalJsonAddress,\n): Promise<PutContentObjectResult<CanonicalRefreshCompletionV2>> {\n parseCanonicalJsonAddress(completionAddress);\n await verifyRefreshCompletionAuthority(partitions, completionAddress);\n const stored = await partitions.objects.get<unknown>(completionAddress);\n const completion = normalizeCompletion(stored);\n const closureInventory = await closureTailInventory(\n partitions,\n completion.closure,\n completion.plan.asOf,\n );\n const expected = new Set(expectedInventory(completion.plan).map(identityKey));\n if (\n canonicalJson([...expected].sort(compareCodePoints)) !==\n canonicalJson(closureInventory.map(identityKey))\n ) {\n throw new Error(\"Canonical refresh plan does not equal the closure cutoff-tail inventory\");\n }\n const observed = new Set<string>();\n const receiptRows = new Map<string, number>();\n for (const reference of completion.receipts) {\n const key = identityKey(reference);\n if (observed.has(key)) throw new Error(\"Canonical refresh completion has duplicate receipts\");\n observed.add(key);\n const commit = await partitions.readCommit(reference.receipt);\n if (identityKey(commit.receipt) !== key) {\n throw new Error(\"Canonical refresh receipt reference disagrees with its stored receipt\");\n }\n await validateCurrentReceipt(partitions, completion.plan, commit);\n receiptRows.set(key, commit.receipt.file.rows);\n }\n if (expected.size !== observed.size || [...expected].some((key) => !observed.has(key))) {\n throw new Error(\"Canonical refresh completion does not cover its producer inventory\");\n }\n for (const operation of completion.operations) {\n const rows = receiptRows.get(identityKey(operationIdentity(operation, completion.plan.asOf)));\n if (rows !== operation.rowsWritten) {\n throw new Error(\"Canonical refresh terminal rows disagree with the exact-byte receipt\");\n }\n }\n return {\n address: completionAddress,\n bytes: canonicalJsonBytes(completion).byteLength,\n value: completion,\n path: partitions.objects.objectPath(completionAddress),\n created: false,\n };\n}\n\nasync function publishCompletion(\n partitions: FilePartitionCommitStore,\n closure: CanonicalJsonAddress,\n plan: CanonicalRefreshPlanV2,\n attempt: PartitionCommitAttemptResult<BoundedRefreshResult>,\n): Promise<PutContentObjectResult<CanonicalRefreshCompletionV2>> {\n validateAttemptInventory(plan, attempt);\n for (const commit of attempt.receipts) {\n await validateCurrentReceipt(partitions, plan, commit);\n }\n const completion = await partitions.objects.put<CanonicalRefreshCompletionV2>({\n kind: CANONICAL_REFRESH_COMPLETION_KIND,\n version: CANONICAL_REFRESH_COMPLETION_VERSION,\n attemptId: attempt.attemptId,\n closure,\n plan,\n operations: terminalOperations(plan, attempt.value.perOperation),\n quoteGroups: attempt.value.quoteGroups,\n receipts: attempt.receipts.map(receiptValue),\n });\n await publishRefreshCompletionAuthority(partitions, completion.address);\n await verifyCanonicalRefreshCompletion(partitions, completion.address);\n return completion;\n}\n\n/** Producer-owned bounded refresh + completion + cutoff publication path. */\nexport async function runCanonicalProvenanceRefresh(\n ingestor: MarketIngestor,\n deps: MarketIngestorDeps,\n input: ProvenanceRefreshInput,\n): Promise<RefreshResult> {\n // Snapshot semantic caller fields before the first await. The progress\n // callback is operational only and is deliberately excluded from identity.\n const authority = normalizeAuthority(input.provenance);\n const basePlan = normalizePlan(input, deps);\n const onProgress = input.onProgress;\n const computeVixContext = input.computeVixContext ?? true;\n const marketRoot = path.join(path.resolve(deps.dataRoot), \"market\");\n const partitions = new FilePartitionCommitStore(marketRoot);\n const plan = await bindPlanToClosure(partitions, authority.closure, basePlan);\n if (plan.includeEnrichedContext && !computeVixContext) {\n throw new Error(\"Canonical closure requires enriched context but refresh disabled it\");\n }\n let vixContext: IngestResult | null = null;\n const attempt = await runPartitionCommitAttempt(\n { attemptId: authority.attemptId, recorder: partitions },\n async () => {\n const value = await runBoundedRefresh(ingestor, plan, onProgress);\n for (const ticker of plan.enrichedTickers) {\n await deps.stores.enriched.compute(ticker, plan.asOf, plan.asOf, {\n persistWatermark: false,\n });\n }\n if (plan.includeEnrichedContext) {\n await deps.stores.enriched.computeContext(plan.asOf, plan.asOf, {\n persistWatermark: false,\n });\n vixContext = {\n status: \"ok\",\n rowsWritten: 0,\n dateRange: { from: plan.asOf, to: plan.asOf },\n };\n }\n return value;\n },\n );\n const completion = await publishCompletion(partitions, authority.closure, plan, attempt);\n const watermarkTickers = new Set(plan.enrichedTickers);\n for (const ticker of [...watermarkTickers].sort(compareCodePoints)) {\n const current = await getEnrichedThrough(ticker, deps.dataRoot);\n await upsertEnrichedThrough(\n ticker,\n current && current > plan.asOf ? current : plan.asOf,\n deps.dataRoot,\n );\n }\n\n const cutoff = await finalizeCanonicalMarketDataCutoff(partitions, {\n closure: authority.closure,\n completeThrough: plan.asOf,\n refreshCompletion: completion.address,\n ...(authority.predecessor ? { predecessor: authority.predecessor } : {}),\n });\n await verifyCanonicalMarketDataCutoff(partitions, cutoff.address);\n const coverage = Object.fromEntries(\n plan.spotTickers.map((ticker) => [\n ticker,\n { totalDates: 1, dateRange: { from: plan.asOf, to: plan.asOf } },\n ]),\n );\n return {\n status: \"ok\",\n perOperation: { ...attempt.value.perOperation, vixContext },\n coverage,\n errors: [],\n provenance: {\n attemptId: attempt.attemptId,\n completion: completion.address,\n receipts: completion.value.receipts.map((receipt) => receipt.receipt),\n cutoff: cutoff.address,\n aggregateRoot: cutoff.value.aggregateRoot,\n },\n };\n}\n","/** Wire-level roots that ThetaData bulk quote ingestion expands an underlying into. */\nexport function bulkQuoteRootsForUnderlying(underlying: string): string[] {\n const upper = underlying.toUpperCase();\n return upper === \"SPX\" ? [\"SPX\", \"SPXW\"] : [upper];\n}\n\n/** Number of final root/right groups per date. */\nexport function countBulkQuoteGroupsPerDate(underlying: string): number {\n return bulkQuoteRootsForUnderlying(underlying).length * 2;\n}\n","/**\n * JSON Adapters for Metadata Stores\n *\n * Provides CRUD operations for five metadata stores backed by JSON files:\n * 1. Strategy profiles — per-block, per-strategy JSON files\n * 2. Sync metadata — per-block .sync-meta.json files\n * 3. Market import metadata — single aggregate file\n * 4. Flat import log — single aggregate file\n * 5. Enrichment watermarks — single aggregate file\n *\n * All adapters use json-store.ts for atomic write-then-rename operations.\n * File paths follow the canonical data-root layout.\n */\n\nimport * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport { z } from \"zod\";\nimport {\n readJsonFile,\n writeJsonFile,\n deleteJsonFile,\n listJsonFiles,\n toFileSlug,\n} from \"./json-store.ts\";\nimport { getDataRoot } from \"./data-root.ts\";\nimport type { StrategyProfile } from \"../models/strategy-profile.ts\";\nimport type { BlockSyncMetadata, MarketImportMetadata } from \"../sync/metadata.ts\";\n\n// =============================================================================\n// 1. Profile Adapter\n// Path: {blocksDir}/{blockId}/profiles/{toFileSlug(strategyName)}.json\n// =============================================================================\n\n/** Profile as stored in JSON (dates as ISO strings) */\ninterface ProfileJson extends Omit<StrategyProfile, \"createdAt\" | \"updatedAt\"> {\n createdAt: string;\n updatedAt: string;\n}\n\n/** Convert StrategyProfile to JSON-safe format */\nfunction profileToJson(profile: StrategyProfile): ProfileJson {\n return {\n ...profile,\n createdAt: profile.createdAt.toISOString(),\n updatedAt: profile.updatedAt.toISOString(),\n };\n}\n\n/** Convert JSON-stored profile back to StrategyProfile with Date objects */\nfunction jsonToProfile(json: ProfileJson): StrategyProfile {\n return {\n ...json,\n createdAt: new Date(json.createdAt),\n updatedAt: new Date(json.updatedAt),\n };\n}\n\n/** Resolve file path for a profile */\nfunction profilePath(blockId: string, strategyName: string, blocksDir: string): string {\n return path.join(blocksDir, blockId, \"profiles\", toFileSlug(strategyName) + \".json\");\n}\n\n/**\n * Create or update a profile JSON file.\n * Preserves existing createdAt on update; always sets new updatedAt.\n *\n * @param profile - Profile data (createdAt/updatedAt are managed automatically)\n * @param blocksDir - Root blocks directory\n * @returns The saved StrategyProfile with Date objects\n */\nexport async function upsertProfileJson(\n profile: Omit<StrategyProfile, \"createdAt\" | \"updatedAt\">,\n blocksDir: string,\n): Promise<StrategyProfile> {\n const filePath = profilePath(profile.blockId, profile.strategyName, blocksDir);\n const now = new Date();\n\n // Preserve existing createdAt\n const existing = await readJsonFile<ProfileJson>(filePath);\n const createdAt = existing ? new Date(existing.createdAt) : now;\n\n const full: StrategyProfile = {\n ...profile,\n createdAt,\n updatedAt: now,\n };\n\n await writeJsonFile(filePath, profileToJson(full));\n return full;\n}\n\n/**\n * Get a profile by blockId and strategy name.\n *\n * @returns StrategyProfile with Date objects, or null if not found\n */\nexport async function getProfileJson(\n blockId: string,\n strategyName: string,\n blocksDir: string,\n): Promise<StrategyProfile | null> {\n const filePath = profilePath(blockId, strategyName, blocksDir);\n const json = await readJsonFile<ProfileJson>(filePath);\n return json ? jsonToProfile(json) : null;\n}\n\n/**\n * List profiles for a block, or all profiles across all blocks.\n *\n * @param blocksDir - Root blocks directory\n * @param blockId - Optional block ID. If omitted, scans all block directories.\n * @returns Array of StrategyProfile with Date objects\n */\nexport async function listProfilesJson(\n blocksDir: string,\n blockId?: string,\n): Promise<StrategyProfile[]> {\n if (blockId) {\n const profileDir = path.join(blocksDir, blockId, \"profiles\");\n const files = await listJsonFiles(profileDir);\n const profiles: StrategyProfile[] = [];\n for (const file of files) {\n const json = await readJsonFile<ProfileJson>(file);\n if (json) profiles.push(jsonToProfile(json));\n }\n return profiles;\n }\n\n // Scan all block directories\n const profiles: StrategyProfile[] = [];\n let entries: import(\"fs\").Dirent[];\n try {\n entries = await fs.readdir(blocksDir, { withFileTypes: true });\n } catch {\n return [];\n }\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const blockProfiles = await listProfilesJson(blocksDir, entry.name);\n profiles.push(...blockProfiles);\n }\n return profiles;\n}\n\n/**\n * Delete a profile JSON file.\n *\n * @returns true if deleted, false if not found\n */\nexport async function deleteProfileJson(\n blockId: string,\n strategyName: string,\n blocksDir: string,\n): Promise<boolean> {\n const filePath = profilePath(blockId, strategyName, blocksDir);\n return deleteJsonFile(filePath);\n}\n\n// =============================================================================\n// 2. Sync Metadata Adapter\n// Path: {blocksDir}/{blockId}/.sync-meta.json\n// =============================================================================\n\n/** Sync metadata as stored in JSON (synced_at as ISO string) */\ninterface SyncMetadataJson extends Omit<BlockSyncMetadata, \"synced_at\"> {\n synced_at: string;\n}\n\n/** Convert BlockSyncMetadata to JSON-safe format */\nfunction syncMetaToJson(meta: BlockSyncMetadata): SyncMetadataJson {\n return {\n ...meta,\n synced_at: meta.synced_at.toISOString(),\n };\n}\n\n/** Convert JSON-stored sync metadata back to BlockSyncMetadata with Date */\nfunction jsonToSyncMeta(json: SyncMetadataJson): BlockSyncMetadata {\n return {\n ...json,\n synced_at: new Date(json.synced_at),\n };\n}\n\n/** Resolve file path for sync metadata */\nfunction syncMetaPath(blockId: string, blocksDir: string): string {\n return path.join(blocksDir, blockId, \".sync-meta.json\");\n}\n\n/**\n * Get sync metadata for a block.\n *\n * @returns BlockSyncMetadata with synced_at as Date, or null if not found\n */\nexport async function getSyncMetadataJson(\n blockId: string,\n blocksDir: string,\n): Promise<BlockSyncMetadata | null> {\n const filePath = syncMetaPath(blockId, blocksDir);\n const json = await readJsonFile<SyncMetadataJson>(filePath);\n return json ? jsonToSyncMeta(json) : null;\n}\n\n/**\n * Write sync metadata for a block.\n */\nexport async function upsertSyncMetadataJson(\n metadata: BlockSyncMetadata,\n blocksDir: string,\n): Promise<void> {\n const filePath = syncMetaPath(metadata.block_id, blocksDir);\n await writeJsonFile(filePath, syncMetaToJson(metadata));\n}\n\n/**\n * Delete sync metadata for a block.\n *\n * @returns true if deleted, false if not found\n */\nexport async function deleteSyncMetadataJson(blockId: string, blocksDir: string): Promise<boolean> {\n const filePath = syncMetaPath(blockId, blocksDir);\n return deleteJsonFile(filePath);\n}\n\n/**\n * Scan blocksDir for directories containing .sync-meta.json.\n *\n * @returns Array of block IDs that have sync metadata\n */\nexport async function getAllSyncedBlockIdsJson(blocksDir: string): Promise<string[]> {\n let entries: import(\"fs\").Dirent[];\n try {\n entries = await fs.readdir(blocksDir, { withFileTypes: true });\n } catch {\n return [];\n }\n\n const ids: string[] = [];\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const metaPath = syncMetaPath(entry.name, blocksDir);\n try {\n await fs.access(metaPath);\n ids.push(entry.name);\n } catch {\n // No .sync-meta.json in this directory\n }\n }\n return ids;\n}\n\n// =============================================================================\n// 3. Market Import Metadata Adapter\n// Path: {dataDir}/market-meta/sync-metadata.json\n// =============================================================================\n\n/** Market import metadata as stored in JSON (synced_at as ISO string) */\ntype MarketImportMetadataJson = Omit<MarketImportMetadata, \"synced_at\"> & { synced_at: string };\n\n/** Aggregate file shape for market import metadata */\ninterface MarketSyncMetadataFile {\n entries: Record<string, MarketImportMetadataJson>;\n}\n\n/** Build composite key for market import metadata */\nfunction marketMetaKey(source: string, ticker: string, targetTable: string): string {\n return `${source}|${ticker}|${targetTable}`;\n}\n\n/** Resolve file path for market import metadata aggregate file */\nfunction marketMetaFilePath(dataDir: string): string {\n return path.join(getDataRoot(dataDir), \"market-meta\", \"sync-metadata.json\");\n}\n\n/**\n * Get market import metadata for a specific source/ticker/table combination.\n *\n * @returns MarketImportMetadata with synced_at as Date, or null if not found\n */\nexport async function getMarketImportMetadataJson(\n source: string,\n ticker: string,\n targetTable: string,\n dataDir: string,\n): Promise<MarketImportMetadata | null> {\n const filePath = marketMetaFilePath(dataDir);\n const file = await readJsonFile<MarketSyncMetadataFile>(filePath);\n if (!file) return null;\n\n const key = marketMetaKey(source, ticker, targetTable);\n const entry = file.entries[key];\n if (!entry) return null;\n\n return {\n ...entry,\n synced_at: new Date(entry.synced_at),\n };\n}\n\n/**\n * Create or update market import metadata entry.\n * Reads the aggregate file, updates the entry, writes back atomically.\n */\nexport async function upsertMarketImportMetadataJson(\n metadata: MarketImportMetadata,\n dataDir: string,\n): Promise<void> {\n const filePath = marketMetaFilePath(dataDir);\n const file = (await readJsonFile<MarketSyncMetadataFile>(filePath)) ?? { entries: {} };\n\n const key = marketMetaKey(metadata.source, metadata.ticker, metadata.target_table);\n file.entries[key] = {\n ...metadata,\n synced_at: metadata.synced_at.toISOString(),\n };\n\n await writeJsonFile(filePath, file);\n}\n\n// =============================================================================\n// 4. Flat Import Log Adapter\n// Path: {dataDir}/market-meta/flat-import-log.json\n// =============================================================================\n\n/** Single entry in the flat import log */\nexport interface FlatImportLogEntry {\n date: string;\n asset_class: string;\n underlying: string;\n imported_at: string;\n bar_count: number;\n}\n\n/** Aggregate file shape for flat import log */\ninterface FlatImportLogFile {\n entries: FlatImportLogEntry[];\n}\n\n/** Build composite key for deduplication */\nfunction flatLogKey(entry: FlatImportLogEntry): string {\n return `${entry.date}|${entry.asset_class}|${entry.underlying}`;\n}\n\n/** Resolve file path for flat import log */\nfunction flatLogFilePath(dataDir: string): string {\n return path.join(getDataRoot(dataDir), \"market-meta\", \"flat-import-log.json\");\n}\n\n/**\n * Get imported dates from the flat import log, filtered by asset_class, underlying, and date range.\n *\n * @returns Set of imported date strings\n */\nexport async function getFlatImportLogJson(\n assetClass: string,\n underlying: string,\n from: string,\n to: string,\n dataDir: string,\n): Promise<Set<string>> {\n const filePath = flatLogFilePath(dataDir);\n const file = await readJsonFile<FlatImportLogFile>(filePath);\n if (!file) return new Set();\n\n const dates = new Set<string>();\n for (const entry of file.entries) {\n if (\n entry.asset_class === assetClass &&\n entry.underlying === underlying &&\n entry.date >= from &&\n entry.date <= to\n ) {\n dates.add(entry.date);\n }\n }\n return dates;\n}\n\n/**\n * Create or update a flat import log entry.\n * Replaces by composite key (date, asset_class, underlying).\n */\nexport async function upsertFlatImportLogJson(\n entry: FlatImportLogEntry,\n dataDir: string,\n): Promise<void> {\n const filePath = flatLogFilePath(dataDir);\n const file = (await readJsonFile<FlatImportLogFile>(filePath)) ?? { entries: [] };\n\n const key = flatLogKey(entry);\n const idx = file.entries.findIndex((e) => flatLogKey(e) === key);\n if (idx >= 0) {\n file.entries[idx] = entry;\n } else {\n file.entries.push(entry);\n }\n\n await writeJsonFile(filePath, file);\n}\n\n// =============================================================================\n// 5. Enrichment Watermarks Adapter\n// Path: {dataRoot}/market-meta/enrichment-watermarks.json\n//\n// Tracks per-ticker `enriched_through` watermark for the market enricher.\n// Replaces the legacy `market._sync_metadata.enriched_through` SQL\n// reads/writes. Backend-independent — the same JSON file is written\n// whether Parquet mode is true or false.\n//\n// Storage shape:\n// {\n// \"version\": 1,\n// \"watermarks\": {\n// \"SPX\": { \"enriched_through\": \"2026-04-15\" },\n// \"VIX\": { \"enriched_through\": \"2026-04-14\" }\n// }\n// }\n//\n// Each entry is an object (not a bare string) so future additions\n// (`wilder_state`, `synced_at`, `last_source`) do not require a schema bump.\n// =============================================================================\n\nconst TickerEntrySchema = z\n .object({\n // ISO calendar date `YYYY-MM-DD` or null when the ticker has been\n // registered but not yet enriched through any date.\n enriched_through: z\n .string()\n .regex(/^\\d{4}-\\d{2}-\\d{2}$/)\n .nullable(),\n })\n // Passthrough keeps forward compatibility — fields like `wilder_state` added\n // by future phases survive load/upsert round-trips without schema changes.\n .passthrough();\n\nexport const EnrichmentWatermarksSchema = z.object({\n version: z.literal(1),\n // Defense-in-depth ticker whitelist: mirrors the TICKER_RE used by\n // src/market/tickers/schemas.ts and rejects anything not shaped like a ticker.\n watermarks: z.record(z.string().regex(/^[A-Z0-9._-]+$/), TickerEntrySchema),\n});\n\nexport type EnrichmentWatermarks = z.infer<typeof EnrichmentWatermarksSchema>;\n\n/** Resolve file path for the aggregate enrichment-watermarks file. */\nfunction watermarksFilePath(dataDir: string): string {\n return path.join(getDataRoot(dataDir), \"market-meta\", \"enrichment-watermarks.json\");\n}\n\n/**\n * Load the enrichment watermarks file.\n *\n * Missing file resolves to an empty structure — absent means \"nothing\n * enriched yet\", not an error. Malformed JSON or schema violations throw a\n * clear error; we never silently reset to empty, which would lose data\n * invisibly.\n */\nexport async function loadEnrichmentWatermarks(dataDir: string): Promise<EnrichmentWatermarks> {\n const raw = await readJsonFile<unknown>(watermarksFilePath(dataDir));\n if (raw === null) return { version: 1, watermarks: {} };\n const parsed = EnrichmentWatermarksSchema.safeParse(raw);\n if (!parsed.success) {\n throw new Error(`enrichment-watermarks.json is malformed: ${parsed.error.message}`);\n }\n return parsed.data;\n}\n\n/**\n * Return the `enriched_through` date for a ticker, or null if no entry exists.\n *\n * Callers that treat \"missing entry\" and \"entry with null enriched_through\" the\n * same (most common case) can use the value directly; callers that need to\n * distinguish can read the raw file via `loadEnrichmentWatermarks`.\n */\nexport async function getEnrichedThrough(ticker: string, dataDir: string): Promise<string | null> {\n const { watermarks } = await loadEnrichmentWatermarks(dataDir);\n return watermarks[ticker]?.enriched_through ?? null;\n}\n\n/**\n * Upsert a ticker's `enriched_through` date.\n *\n * Preserves other tickers' entries and any passthrough fields (e.g.,\n * `wilder_state`) already stored on the target ticker.\n *\n * Concurrency note: atomic at the FS level (tmp+rename via writeJsonFile);\n * this is NOT read-modify-write atomic at the application level. Serial\n * callers (the current enricher flow) are safe. If concurrent enrichers of\n * different tickers become real, add an async-mutex.\n */\nexport async function upsertEnrichedThrough(\n ticker: string,\n enrichedThrough: string,\n dataDir: string,\n): Promise<void> {\n const current = await loadEnrichmentWatermarks(dataDir);\n current.watermarks[ticker] = {\n ...(current.watermarks[ticker] ?? {}),\n enriched_through: enrichedThrough,\n };\n await writeJsonFile(watermarksFilePath(dataDir), current);\n}\n","import type { Trade } from \"../models/trade.ts\";\nimport type { DailyLogEntry } from \"../models/daily-log.ts\";\nimport type {\n WalkForwardConfig,\n WalkForwardComputation,\n WalkForwardParameterRanges,\n WalkForwardPeriodResult,\n WalkForwardProgressEvent,\n WalkForwardResults,\n WalkForwardSummary,\n WalkForwardWindow,\n PerformanceFloorConfig,\n DiversificationConfig,\n PeriodDiversificationMetrics,\n SkippedWindow,\n} from \"../models/walk-forward.ts\";\nimport { PortfolioStatsCalculator } from \"./portfolio-stats.ts\";\nimport { calculateKellyMetrics } from \"./kelly.ts\";\nimport type { PortfolioStats } from \"../models/portfolio-stats.ts\";\nimport {\n calculateCorrelationMatrix,\n calculateCorrelationAnalytics,\n type CorrelationOptions,\n} from \"./correlation.ts\";\nimport { performTailRiskAnalysis } from \"./tail-risk-analysis.ts\";\nimport type { TailRiskAnalysisOptions } from \"../models/tail-risk.ts\";\nimport { getNetPl } from \"../utils/equity-curve.ts\";\nimport { formatDateKey } from \"./trade-matching.ts\";\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\nconst DEFAULT_MIN_IN_SAMPLE_TRADES = 10;\nconst DEFAULT_MIN_OUT_SAMPLE_TRADES = 3;\nconst DEFAULT_FIXED_FRACTION_PCT = 2;\nconst MAX_PARAMETER_COMBINATIONS = 20000;\nconst YIELD_EVERY = 50;\n\ninterface AnalyzeOptions {\n trades: Trade[];\n /**\n * Daily portfolio logs. Reserved for future use to enable more accurate\n * equity curve calculations during walk-forward periods. Currently unused.\n */\n dailyLogs?: DailyLogEntry[];\n config: WalkForwardConfig;\n signal?: AbortSignal;\n onProgress?: (event: WalkForwardProgressEvent) => void;\n}\n\ninterface ScalingBaseline {\n baseKellyFraction: number;\n avgContracts: number;\n}\n\ninterface CombinationIterator {\n values: Array<Record<string, number>>;\n count: number;\n}\n\nexport class WalkForwardAnalyzer {\n // Cache for trade timestamps to avoid repeated Date parsing\n private tradeTimestampCache = new Map<Trade, number>();\n\n private getTradeTimestamp(trade: Trade): number {\n let ts = this.tradeTimestampCache.get(trade);\n if (ts === undefined) {\n ts = new Date(trade.dateOpened).getTime();\n this.tradeTimestampCache.set(trade, ts);\n }\n return ts;\n }\n\n async analyze(options: AnalyzeOptions): Promise<WalkForwardComputation> {\n this.ensureValidConfig(options.config);\n\n // Clear cache for new analysis\n this.tradeTimestampCache.clear();\n\n const sortedTrades = this.sortTrades(options.trades);\n const calculator = new PortfolioStatsCalculator();\n const startedAt = new Date();\n\n if (sortedTrades.length === 0) {\n const emptyResults = this.buildResults(\n [],\n options.config,\n 0,\n 0,\n sortedTrades.length,\n startedAt,\n );\n return {\n config: options.config,\n results: emptyResults,\n startedAt,\n completedAt: new Date(),\n };\n }\n\n const skippedWindows: SkippedWindow[] = [];\n const windows = this.buildWindows(sortedTrades, options.config, skippedWindows);\n options.onProgress?.({\n phase: \"segmenting\",\n currentPeriod: 0,\n totalPeriods: windows.length,\n message: `Prepared ${windows.length} optimization windows`,\n });\n\n const periods: WalkForwardPeriodResult[] = [];\n let totalParameterTests = 0;\n\n for (let index = 0; index < windows.length; index++) {\n this.throwIfAborted(options.signal);\n\n const window = windows[index];\n const inSampleTrades = this.filterTrades(\n sortedTrades,\n window.inSampleStart,\n window.inSampleEnd,\n );\n const outSampleTrades = this.filterTrades(\n sortedTrades,\n window.outOfSampleStart,\n window.outOfSampleEnd,\n );\n\n const minInSample = options.config.minInSampleTrades ?? DEFAULT_MIN_IN_SAMPLE_TRADES;\n const minOutSample = options.config.minOutOfSampleTrades ?? DEFAULT_MIN_OUT_SAMPLE_TRADES;\n\n if (inSampleTrades.length < minInSample || outSampleTrades.length < minOutSample) {\n const reason =\n inSampleTrades.length < minInSample\n ? (\"insufficient_is_trades\" as const)\n : (\"insufficient_oos_trades\" as const);\n const detail =\n inSampleTrades.length < minInSample\n ? `${inSampleTrades.length} IS trades < min ${minInSample}`\n : `${outSampleTrades.length} OOS trades < min ${minOutSample}`;\n skippedWindows.push({ ...window, reason, detail });\n continue;\n }\n\n const combinationIterator = this.buildCombinationIterator(\n options.config.parameterRanges || {},\n );\n if (combinationIterator.count > MAX_PARAMETER_COMBINATIONS) {\n throw new Error(\n `Walk-forward parameter grid too large (${combinationIterator.count.toLocaleString()} combinations). ` +\n `Reduce ranges or increase step sizes.`,\n );\n }\n\n options.onProgress?.({\n phase: \"optimizing\",\n currentPeriod: index + 1,\n totalPeriods: windows.length,\n totalCombinations: combinationIterator.count,\n testedCombinations: 0,\n window,\n });\n\n const baseline = this.buildScalingBaseline(inSampleTrades);\n const inSampleInitialCapital =\n PortfolioStatsCalculator.calculateInitialCapital(inSampleTrades);\n const outSampleInitialCapital =\n PortfolioStatsCalculator.calculateInitialCapital(outSampleTrades);\n\n let tested = 0;\n let bestCombo: {\n params: Record<string, number>;\n inSampleStats: PortfolioStats;\n score: number;\n } | null = null;\n\n // Check if diversification constraints need to be enforced during optimization\n const diversificationConfig = options.config.diversificationConfig;\n const enforceDiversificationConstraints =\n diversificationConfig?.enableCorrelationConstraint ||\n diversificationConfig?.enableTailRiskConstraint;\n\n for (const params of combinationIterator.values) {\n this.throwIfAborted(options.signal);\n tested++;\n\n const scaledInSampleTrades = this.applyScenario(\n inSampleTrades,\n params,\n baseline,\n inSampleInitialCapital,\n );\n const inSampleStats = calculator.calculatePortfolioStats(scaledInSampleTrades);\n\n if (\n !this.isRiskAcceptable(\n params,\n inSampleStats,\n scaledInSampleTrades,\n options.config.performanceFloor,\n )\n ) {\n continue;\n }\n\n // Check diversification constraints if enabled\n // This rejects parameter combinations where strategies are too correlated\n // or have excessive tail dependence during the in-sample period\n if (enforceDiversificationConstraints && diversificationConfig) {\n const inSampleDivMetrics = this.calculateDiversificationMetrics(\n scaledInSampleTrades,\n diversificationConfig,\n );\n if (\n inSampleDivMetrics &&\n !this.isDiversificationAcceptable(inSampleDivMetrics, diversificationConfig)\n ) {\n continue;\n }\n }\n\n const targetValue = this.getTargetMetricValue(\n inSampleStats,\n options.config.optimizationTarget,\n );\n if (!Number.isFinite(targetValue)) {\n continue;\n }\n\n if (!bestCombo || targetValue > bestCombo.score) {\n bestCombo = {\n params: { ...params },\n inSampleStats,\n score: targetValue,\n };\n }\n\n if (tested % YIELD_EVERY === 0) {\n await this.yieldToEventLoop();\n }\n\n options.onProgress?.({\n phase: \"optimizing\",\n currentPeriod: index + 1,\n totalPeriods: windows.length,\n totalCombinations: combinationIterator.count,\n testedCombinations: tested,\n window,\n });\n }\n\n totalParameterTests += tested;\n\n if (!bestCombo) {\n skippedWindows.push({\n ...window,\n reason: \"no_viable_params\",\n detail: `All ${combinationIterator.count} combo${combinationIterator.count === 1 ? \"\" : \"s\"} rejected`,\n });\n continue;\n }\n\n const scaledOutSampleTrades = this.applyScenario(\n outSampleTrades,\n bestCombo.params,\n baseline,\n outSampleInitialCapital,\n );\n const outSampleStats = calculator.calculatePortfolioStats(scaledOutSampleTrades);\n\n // Calculate diversification metrics for OOS period if enabled\n let diversificationMetrics: PeriodDiversificationMetrics | undefined;\n if (enforceDiversificationConstraints && diversificationConfig) {\n const metrics = this.calculateDiversificationMetrics(\n scaledOutSampleTrades,\n diversificationConfig,\n );\n if (metrics) {\n diversificationMetrics = metrics;\n }\n }\n\n const period: WalkForwardPeriodResult = {\n ...window,\n optimalParameters: bestCombo.params,\n inSampleMetrics: bestCombo.inSampleStats,\n outOfSampleMetrics: outSampleStats,\n targetMetricInSample: bestCombo.score,\n targetMetricOutOfSample: this.getTargetMetricValue(\n outSampleStats,\n options.config.optimizationTarget,\n ),\n diversificationMetrics,\n };\n\n periods.push(period);\n\n options.onProgress?.({\n phase: \"evaluating\",\n currentPeriod: index + 1,\n totalPeriods: windows.length,\n testedCombinations: tested,\n totalCombinations: combinationIterator.count,\n window,\n });\n }\n\n const completedAt = new Date();\n const results = this.buildResults(\n periods,\n options.config,\n windows.length + (skippedWindows[0]?.reason === \"truncated_oos_window\" ? 1 : 0),\n totalParameterTests,\n sortedTrades.length,\n startedAt,\n completedAt,\n skippedWindows,\n );\n\n options.onProgress?.({\n phase: \"completed\",\n currentPeriod: windows.length,\n totalPeriods: windows.length,\n message: \"Walk-forward analysis complete\",\n });\n\n return {\n config: options.config,\n results,\n startedAt,\n completedAt,\n };\n }\n\n private ensureValidConfig(config: WalkForwardConfig): void {\n if (config.inSampleDays <= 0) {\n throw new Error(\"inSampleDays must be greater than zero\");\n }\n if (config.outOfSampleDays <= 0) {\n throw new Error(\"outOfSampleDays must be greater than zero\");\n }\n if (config.stepSizeDays <= 0) {\n throw new Error(\"stepSizeDays must be greater than zero\");\n }\n }\n\n private sortTrades(trades: Trade[]): Trade[] {\n return [...trades].sort((a, b) => {\n const dateA = this.getTradeTimestamp(a);\n const dateB = this.getTradeTimestamp(b);\n if (dateA !== dateB) return dateA - dateB;\n return (a.timeOpened || \"\").localeCompare(b.timeOpened || \"\");\n });\n }\n\n private filterTrades(trades: Trade[], start: Date, end: Date): Trade[] {\n const startMs = start.getTime();\n const endMs = end.getTime();\n return trades.filter((trade) => {\n const tradeDate = this.floorToUTCDate(new Date(trade.dateOpened)).getTime();\n return tradeDate >= startMs && tradeDate <= endMs;\n });\n }\n\n private buildWindows(\n trades: Trade[],\n config: WalkForwardConfig,\n skippedWindows: SkippedWindow[],\n ): WalkForwardWindow[] {\n if (trades.length === 0) return [];\n\n const firstDate = this.floorToUTCDate(new Date(trades[0].dateOpened));\n const lastDate = this.floorToUTCDate(new Date(trades[trades.length - 1].dateOpened));\n const windows: WalkForwardWindow[] = [];\n\n let cursor = firstDate.getTime();\n\n while (cursor < lastDate.getTime()) {\n const inSampleStart = new Date(cursor);\n const inSampleEnd = new Date(cursor + (config.inSampleDays - 1) * DAY_MS);\n const outOfSampleStart = new Date(inSampleEnd.getTime() + DAY_MS);\n const outOfSampleEnd = new Date(\n outOfSampleStart.getTime() + (config.outOfSampleDays - 1) * DAY_MS,\n );\n\n if (outOfSampleEnd > lastDate) {\n if (outOfSampleStart <= lastDate) {\n skippedWindows.push({\n inSampleStart,\n inSampleEnd,\n outOfSampleStart,\n outOfSampleEnd,\n reason: \"truncated_oos_window\",\n detail: `OOS end exceeds last trade date (${formatDateKey(new Date(trades[trades.length - 1].dateOpened))})`,\n });\n }\n break;\n }\n\n windows.push({\n inSampleStart,\n inSampleEnd,\n outOfSampleStart,\n outOfSampleEnd,\n });\n\n cursor += config.stepSizeDays * DAY_MS;\n }\n\n return windows;\n }\n\n private floorToUTCDate(date: Date): Date {\n return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));\n }\n\n private buildCombinationIterator(\n parameterRanges: WalkForwardParameterRanges,\n ): CombinationIterator {\n const entries = Object.entries(parameterRanges || {});\n if (entries.length === 0) {\n return { values: [{}], count: 1 };\n }\n\n const values = entries.map(([key, [min, max, step]]) => ({\n key,\n values: this.buildRangeValues(min, max, step),\n }));\n\n const combinations: Array<Record<string, number>> = [];\n\n const recurse = (index: number, current: Record<string, number>) => {\n if (index === values.length) {\n combinations.push({ ...current });\n return;\n }\n\n const entry = values[index];\n entry.values.forEach((value) => {\n current[entry.key] = value;\n recurse(index + 1, current);\n });\n };\n\n recurse(0, {});\n\n return { values: combinations, count: combinations.length };\n }\n\n private buildRangeValues(min: number, max: number, step: number): number[] {\n if (max < min) {\n throw new Error(`Invalid parameter range: max (${max}) must be >= min (${min}).`);\n }\n if (step <= 0) {\n throw new Error(`Invalid parameter step size (${step}). Step must be positive.`);\n }\n\n const values: number[] = [];\n const totalSteps = Math.floor((max - min) / step);\n for (let i = 0; i <= totalSteps; i++) {\n const value = min + i * step;\n values.push(Number(value.toFixed(6)));\n }\n\n if (!values.includes(Number(max.toFixed(6)))) {\n values.push(Number(max.toFixed(6)));\n }\n\n return values;\n }\n\n private buildScalingBaseline(trades: Trade[]): ScalingBaseline {\n const kellyMetrics = calculateKellyMetrics(trades);\n const avgContracts =\n trades.length > 0\n ? trades.reduce((sum, trade) => sum + Math.abs(trade.numContracts || 0), 0) / trades.length\n : 1;\n\n return {\n baseKellyFraction: kellyMetrics.fraction || 0,\n avgContracts: avgContracts > 0 ? avgContracts : 1,\n };\n }\n\n private applyScenario(\n trades: Trade[],\n params: Record<string, number>,\n baseline: ScalingBaseline,\n initialCapitalOverride?: number,\n ): Trade[] {\n if (trades.length === 0) return [];\n\n const initialCapital =\n typeof initialCapitalOverride === \"number\"\n ? initialCapitalOverride\n : PortfolioStatsCalculator.calculateInitialCapital(trades);\n\n const positionMultiplier = this.calculatePositionMultiplier(params, baseline);\n const strategyWeights = this.buildStrategyWeights(params);\n const hasStrategyWeights = Object.keys(strategyWeights).length > 0;\n\n // trades are already sorted from filterTrades() which preserves sortedTrades order\n let runningEquity = initialCapital;\n const scaledTrades: Trade[] = [];\n\n for (const trade of trades) {\n const strategyWeight = strategyWeights[this.normalizeStrategyKey(trade.strategy)] ?? 1;\n\n // Skip trades from strategies with zero weight (excluded from this combination)\n // This prevents zero-P/L trades from inflating trade counts and diluting metrics\n if (hasStrategyWeights && strategyWeight === 0) {\n continue;\n }\n\n const scale = positionMultiplier * strategyWeight;\n const scaledPl = trade.pl * scale;\n const scaledOpeningCommissions = trade.openingCommissionsFees * Math.abs(scale);\n const scaledClosingCommissions = trade.closingCommissionsFees * Math.abs(scale);\n const scaledNetPl = getNetPl({\n pl: scaledPl,\n plBasis: trade.plBasis,\n openingCommissionsFees: scaledOpeningCommissions,\n closingCommissionsFees: scaledClosingCommissions,\n });\n\n runningEquity += scaledNetPl;\n\n // Only include fields used by PortfolioStatsCalculator to reduce object copy overhead\n scaledTrades.push({\n pl: scaledPl,\n plBasis: trade.plBasis,\n dateOpened: trade.dateOpened,\n timeOpened: trade.timeOpened,\n dateClosed: trade.dateClosed,\n timeClosed: trade.timeClosed,\n fundsAtClose: runningEquity,\n openingCommissionsFees: scaledOpeningCommissions,\n closingCommissionsFees: scaledClosingCommissions,\n strategy: trade.strategy,\n } as Trade);\n }\n\n return scaledTrades;\n }\n\n private calculatePositionMultiplier(\n params: Record<string, number>,\n baseline: ScalingBaseline,\n ): number {\n let multiplier = 1;\n\n if (typeof params.kellyMultiplier === \"number\" && params.kellyMultiplier > 0) {\n multiplier *= params.kellyMultiplier;\n }\n\n if (typeof params.fixedFractionPct === \"number\" && params.fixedFractionPct > 0) {\n multiplier *= params.fixedFractionPct / DEFAULT_FIXED_FRACTION_PCT;\n }\n\n if (typeof params.fixedContracts === \"number\" && params.fixedContracts > 0) {\n const baseContracts = baseline.avgContracts > 0 ? baseline.avgContracts : 1;\n multiplier *= params.fixedContracts / baseContracts;\n }\n\n return Math.max(multiplier, 0);\n }\n\n private buildStrategyWeights(params: Record<string, number>): Record<string, number> {\n const weights: Record<string, number> = {};\n Object.entries(params).forEach(([key, value]) => {\n if (key.startsWith(\"strategy:\")) {\n const strategyName = key.slice(\"strategy:\".length);\n weights[this.normalizeStrategyKey(strategyName)] = Math.max(0, value);\n }\n });\n return weights;\n }\n\n private normalizeStrategyKey(strategy?: string): string {\n return (strategy || \"Unknown\").toLowerCase();\n }\n\n private isRiskAcceptable(\n params: Record<string, number>,\n stats: PortfolioStats,\n scaledTrades: Trade[],\n performanceFloor?: PerformanceFloorConfig,\n ): boolean {\n // Parameter-based risk constraints\n if (typeof params.maxDrawdownPct === \"number\" && stats.maxDrawdown > params.maxDrawdownPct) {\n return false;\n }\n\n if (typeof params.consecutiveLossLimit === \"number\") {\n const maxLosses = this.calculateMaxConsecutiveLosses(scaledTrades);\n if (maxLosses > params.consecutiveLossLimit) {\n return false;\n }\n }\n\n if (typeof params.maxDailyLossPct === \"number\") {\n const initialCapital = PortfolioStatsCalculator.calculateInitialCapital(scaledTrades);\n const maxDailyLoss = this.calculateMaxDailyLossPct(scaledTrades, initialCapital);\n if (maxDailyLoss > params.maxDailyLossPct) {\n return false;\n }\n }\n\n // Performance floor checks (Phase 2)\n if (performanceFloor) {\n if (performanceFloor.enableMinSharpe && performanceFloor.minSharpeRatio > 0) {\n const sharpe = stats.sharpeRatio ?? Number.NEGATIVE_INFINITY;\n if (sharpe < performanceFloor.minSharpeRatio) {\n return false;\n }\n }\n\n if (performanceFloor.enableMinProfitFactor && performanceFloor.minProfitFactor > 0) {\n const pf = stats.profitFactor ?? 0;\n if (pf < performanceFloor.minProfitFactor) {\n return false;\n }\n }\n\n if (performanceFloor.enablePositiveNetPl) {\n const netPl = stats.netPl ?? 0;\n if (netPl <= 0) {\n return false;\n }\n }\n }\n\n return true;\n }\n\n /**\n * Calculate diversification metrics for a set of trades\n * Returns null if there aren't enough strategies for meaningful analysis\n */\n private calculateDiversificationMetrics(\n trades: Trade[],\n config: DiversificationConfig,\n ): PeriodDiversificationMetrics | null {\n // Need at least 2 strategies for correlation/diversification analysis\n const strategies = new Set(trades.map((t) => t.strategy).filter(Boolean));\n if (strategies.size < 2) {\n return null;\n }\n\n // Build correlation options from config\n const correlationOptions: CorrelationOptions = {\n method: config.correlationMethod,\n normalization: config.normalization,\n dateBasis: config.dateBasis,\n alignment: \"shared\",\n timePeriod: \"daily\",\n };\n\n // Calculate correlation matrix\n const correlationMatrix = calculateCorrelationMatrix(trades, correlationOptions);\n const correlationAnalytics = calculateCorrelationAnalytics(correlationMatrix);\n\n // Calculate tail risk if enabled\n let tailRiskResult = null;\n if (config.enableTailRiskConstraint) {\n const tailRiskOptions: TailRiskAnalysisOptions = {\n tailThreshold: config.tailThreshold,\n normalization: config.normalization,\n dateBasis: config.dateBasis,\n };\n tailRiskResult = performTailRiskAnalysis(trades, tailRiskOptions);\n }\n\n // Handle NaN values for strongest correlation (occurs when no valid pairs)\n const maxCorrelation = Number.isNaN(correlationAnalytics.strongest.value)\n ? 0\n : correlationAnalytics.strongest.value;\n const maxCorrelationPair = correlationAnalytics.strongest.pair[0]\n ? correlationAnalytics.strongest.pair\n : ([\"\", \"\"] as [string, string]);\n\n // Calculate total pairs for this period\n const numStrategies = correlationMatrix.strategies.length;\n const totalPairs = (numStrategies * (numStrategies - 1)) / 2;\n\n return {\n avgCorrelation: Number.isNaN(correlationAnalytics.averageCorrelation)\n ? 0\n : correlationAnalytics.averageCorrelation,\n maxCorrelation,\n maxCorrelationPair,\n avgTailDependence: tailRiskResult?.analytics.averageJointTailRisk ?? 0,\n maxTailDependence: tailRiskResult?.analytics.highestJointTailRisk.value ?? 0,\n maxTailDependencePair: (tailRiskResult?.analytics.highestJointTailRisk.pair ?? [\"\", \"\"]) as [\n string,\n string,\n ],\n effectiveFactors: tailRiskResult?.effectiveFactors ?? correlationMatrix.strategies.length,\n highRiskPairsPct: tailRiskResult?.analytics.highRiskPairsPct ?? 0,\n // Track insufficient tail data for UI display\n insufficientTailDataPairs: tailRiskResult?.insufficientDataPairs ?? totalPairs,\n totalPairs,\n };\n }\n\n /**\n * Check if diversification constraints are met\n */\n private isDiversificationAcceptable(\n metrics: PeriodDiversificationMetrics,\n config: DiversificationConfig,\n ): boolean {\n // Check correlation constraint\n if (config.enableCorrelationConstraint) {\n if (metrics.maxCorrelation > config.maxCorrelationThreshold) {\n return false;\n }\n }\n\n // Check tail risk constraint\n if (config.enableTailRiskConstraint) {\n if (metrics.maxTailDependence > config.maxTailDependenceThreshold) {\n return false;\n }\n }\n\n return true;\n }\n\n private calculateMaxConsecutiveLosses(trades: Trade[]): number {\n let maxLosses = 0;\n let currentLosses = 0;\n\n // trades are already sorted from applyScenario()\n trades.forEach((trade) => {\n if (trade.pl < 0) {\n currentLosses++;\n maxLosses = Math.max(maxLosses, currentLosses);\n } else {\n currentLosses = 0;\n }\n });\n\n return maxLosses;\n }\n\n private calculateMaxDailyLossPct(trades: Trade[], initialCapital: number): number {\n if (initialCapital === 0) return 0;\n\n const lossesByDay = new Map<string, number>();\n\n trades.forEach((trade) => {\n const dateKey = this.normalizeDateKey(trade.dateClosed || trade.dateOpened);\n lossesByDay.set(dateKey, (lossesByDay.get(dateKey) || 0) + trade.pl);\n });\n\n let maxLossPct = 0;\n\n lossesByDay.forEach((pl) => {\n if (pl < 0) {\n const lossPct = (Math.abs(pl) / initialCapital) * 100;\n maxLossPct = Math.max(maxLossPct, lossPct);\n }\n });\n\n return maxLossPct;\n }\n\n private normalizeDateKey(date: Date | string): string {\n return formatDateKey(new Date(date));\n }\n\n private getTargetMetricValue(\n stats: PortfolioStats,\n target: WalkForwardConfig[\"optimizationTarget\"],\n ): number {\n switch (target) {\n case \"profitFactor\":\n return stats.profitFactor ?? Number.NEGATIVE_INFINITY;\n case \"sharpeRatio\":\n return stats.sharpeRatio ?? Number.NEGATIVE_INFINITY;\n case \"sortinoRatio\":\n return stats.sortinoRatio ?? Number.NEGATIVE_INFINITY;\n case \"calmarRatio\":\n return stats.calmarRatio ?? Number.NEGATIVE_INFINITY;\n case \"cagr\":\n return stats.cagr ?? Number.NEGATIVE_INFINITY;\n case \"avgDailyPl\":\n return stats.avgDailyPl ?? Number.NEGATIVE_INFINITY;\n case \"winRate\":\n return stats.winRate ?? Number.NEGATIVE_INFINITY;\n // Diversification targets are not yet supported for optimization\n // They require computing correlation/tail risk for EACH parameter combination\n // which is expensive. For now, they're used as constraints, not targets.\n case \"minAvgCorrelation\":\n case \"minTailRisk\":\n case \"maxEffectiveFactors\":\n return Number.NEGATIVE_INFINITY;\n case \"netPl\":\n default:\n return stats.netPl ?? Number.NEGATIVE_INFINITY;\n }\n }\n\n private async yieldToEventLoop(): Promise<void> {\n await new Promise((resolve) => setTimeout(resolve, 0));\n }\n\n private throwIfAborted(signal?: AbortSignal): void {\n if (signal?.aborted) {\n throw new Error(\"Walk-forward analysis aborted\");\n }\n }\n\n private buildResults(\n periods: WalkForwardPeriodResult[],\n config: WalkForwardConfig,\n totalPeriods: number,\n totalParameterTests: number,\n analyzedTrades: number,\n startedAt: Date,\n completedAt: Date = new Date(),\n skippedWindows: SkippedWindow[] = [],\n ): WalkForwardResults {\n const summary = this.calculateSummary(periods);\n const stats = {\n totalPeriods,\n evaluatedPeriods: periods.length,\n skippedPeriods: skippedWindows.length,\n totalParameterTests,\n analyzedTrades,\n durationMs: completedAt.getTime() - startedAt.getTime(),\n consistencyScore: this.calculateConsistencyScore(periods),\n averagePerformanceDelta: this.calculateAveragePerformanceDelta(periods),\n };\n\n const robustnessScore = this.calculateRobustnessScore(summary, stats.consistencyScore);\n\n return {\n periods,\n skippedWindows,\n summary: { ...summary, robustnessScore },\n stats,\n };\n }\n\n /**\n * Calculates summary metrics for walk-forward analysis results.\n *\n * The `degradationFactor` (efficiency ratio) compares out-of-sample to in-sample performance.\n * This is equivalent to Walk Forward Efficiency (WFE) from Pardo's methodology.\n *\n * **Why we don't annualize:** Unlike raw return comparisons, we compare the same target metric\n * (e.g., Sharpe Ratio to Sharpe Ratio, or Net P&L to Net P&L) across IS and OOS periods.\n * Ratio metrics like Sharpe already normalize for time. Annualization would be appropriate\n * for comparing raw dollar returns across different period lengths, but our optimization\n * targets are typically normalized metrics. The Pardo annualization formula applies to\n * raw profit comparisons, not ratio-based target metrics.\n *\n * Formula: `degradationFactor = avgOutOfSamplePerformance / avgInSamplePerformance`\n * - 1.0 = OOS matches IS perfectly (rare)\n * - 0.8 = OOS retains 80% of IS performance (good)\n * - 0.5 = OOS retains 50% of IS performance (concerning)\n *\n * @see Pardo, Robert. \"The Evaluation and Optimization of Trading Strategies\" (2008)\n */\n private calculateSummary(periods: WalkForwardPeriodResult[]): WalkForwardSummary {\n if (periods.length === 0) {\n return {\n avgInSamplePerformance: 0,\n avgOutOfSamplePerformance: 0,\n degradationFactor: 0,\n parameterStability: 0,\n robustnessScore: 0,\n };\n }\n\n const inSampleValues = periods\n .map((p) => p.targetMetricInSample)\n .filter((value) => Number.isFinite(value));\n const outSampleValues = periods\n .map((p) => p.targetMetricOutOfSample)\n .filter((value) => Number.isFinite(value));\n\n const avgInSample =\n inSampleValues.length > 0\n ? inSampleValues.reduce((sum, value) => sum + value, 0) / inSampleValues.length\n : 0;\n const avgOutSample =\n outSampleValues.length > 0\n ? outSampleValues.reduce((sum, value) => sum + value, 0) / outSampleValues.length\n : 0;\n\n const degradationFactor = avgInSample !== 0 ? avgOutSample / avgInSample : 0;\n const parameterStability = this.calculateParameterStability(periods);\n\n const summary: WalkForwardSummary = {\n avgInSamplePerformance: avgInSample,\n avgOutOfSamplePerformance: avgOutSample,\n degradationFactor,\n parameterStability,\n robustnessScore: 0,\n };\n\n // Aggregate diversification metrics across periods\n const periodsWithDiversification = periods.filter((p) => p.diversificationMetrics);\n if (periodsWithDiversification.length > 0) {\n summary.avgCorrelationAcrossPeriods =\n periodsWithDiversification.reduce(\n (sum, p) => sum + (p.diversificationMetrics?.avgCorrelation ?? 0),\n 0,\n ) / periodsWithDiversification.length;\n\n summary.avgTailDependenceAcrossPeriods =\n periodsWithDiversification.reduce(\n (sum, p) => sum + (p.diversificationMetrics?.avgTailDependence ?? 0),\n 0,\n ) / periodsWithDiversification.length;\n\n summary.avgEffectiveFactors =\n periodsWithDiversification.reduce(\n (sum, p) => sum + (p.diversificationMetrics?.effectiveFactors ?? 0),\n 0,\n ) / periodsWithDiversification.length;\n }\n\n return summary;\n }\n\n /**\n * Calculates parameter stability across walk-forward periods using coefficient of variation.\n *\n * For each optimized parameter, we calculate how much the optimal value varied\n * across periods. Lower variance = higher stability = more robust parameters.\n *\n * **Statistical approach:**\n * - Uses sample variance (N-1 denominator) rather than population variance (N)\n * - Sample variance is preferred for small samples (N<30) per standard statistical practice\n * - The coefficient of variation (CV = stdDev/mean) normalizes across different parameter scales\n * - CV is inverted to produce a 0-1 stability score (1 = perfectly stable, 0 = highly variable)\n *\n * **Interpretation:**\n * - CV < 0.3 (30%): Parameter is stable across periods\n * - CV >= 0.3: Parameter shows meaningful variation (potential over-optimization risk)\n *\n * @returns Stability score between 0 and 1, where 1 indicates perfectly stable parameters\n */\n private calculateParameterStability(periods: WalkForwardPeriodResult[]): number {\n if (periods.length <= 1) return 1;\n\n const parameterKeys = new Set<string>();\n periods.forEach((period) => {\n Object.keys(period.optimalParameters).forEach((key) => parameterKeys.add(key));\n });\n\n if (parameterKeys.size === 0) return 1;\n\n const stabilityScores: number[] = [];\n\n parameterKeys.forEach((key) => {\n const values = periods\n .map((period) => period.optimalParameters[key])\n .filter((value): value is number => typeof value === \"number\");\n\n if (values.length <= 1) {\n stabilityScores.push(1);\n return;\n }\n\n const mean = values.reduce((sum, value) => sum + value, 0) / values.length;\n // Use sample variance (N-1) for small sample accuracy\n // Population variance (N) underestimates true variability for small samples\n const variance =\n values.reduce((sum, value) => sum + Math.pow(value - mean, 2), 0) / (values.length - 1);\n const stdDev = Math.sqrt(variance);\n\n // Normalize by mean to avoid requiring parameter ranges here\n const normalizedStd = mean !== 0 ? Math.min(Math.abs(stdDev / mean), 1) : Math.min(stdDev, 1);\n stabilityScores.push(1 - normalizedStd);\n });\n\n const avgStability =\n stabilityScores.reduce((sum, value) => sum + value, 0) / stabilityScores.length;\n return Math.min(Math.max(avgStability, 0), 1);\n }\n\n private calculateConsistencyScore(periods: WalkForwardPeriodResult[]): number {\n if (periods.length === 0) return 0;\n const profitable = periods.filter((period) => period.targetMetricOutOfSample >= 0);\n return profitable.length / periods.length;\n }\n\n private calculateAveragePerformanceDelta(periods: WalkForwardPeriodResult[]): number {\n if (periods.length === 0) return 0;\n const deltas = periods.map(\n (period) => period.targetMetricOutOfSample - period.targetMetricInSample,\n );\n return deltas.reduce((sum, delta) => sum + delta, 0) / deltas.length;\n }\n\n /**\n * Calculates a composite robustness score combining efficiency, stability, and consistency.\n *\n * **IMPORTANT:** This is a TradeBlocks-specific composite metric, NOT an industry-standard formula.\n * Individual platforms (MultiCharts, TradeStation, AmiBroker) use configurable weights and\n * thresholds rather than a single composite score. This metric provides a quick overview\n * but users should examine individual components for detailed analysis.\n *\n * **Components (equally weighted):**\n * 1. **Efficiency Score** (normalized degradation factor): How well OOS matched IS performance\n * - Degradation factor of 1.0 (100% retention) = efficiency score of 0.5\n * - Degradation factor of 2.0+ = efficiency score of 1.0 (capped)\n * - Based on Pardo's Walk Forward Efficiency concept\n *\n * 2. **Stability Score** (parameter stability): How consistent optimal parameters were\n * - Uses coefficient of variation (CV) per standard statistical practice\n * - Lower CV = higher stability\n *\n * 3. **Consistency Score**: Percentage of periods with non-negative OOS performance\n * - Similar to MultiCharts \"% Profitable Runs\" metric\n * - 70%+ considered good per MultiCharts robustness criteria\n *\n * Formula: `robustnessScore = (efficiencyScore + stabilityScore + consistencyScore) / 3`\n *\n * @returns Score between 0 and 1, where higher indicates more robust strategy\n */\n private calculateRobustnessScore(summary: WalkForwardSummary, consistencyScore: number): number {\n const efficiencyScore = this.normalize(summary.degradationFactor, 0, 2);\n const stabilityScore = Math.min(Math.max(summary.parameterStability, 0), 1);\n const consistency = Math.min(Math.max(consistencyScore, 0), 1);\n\n const score = (efficiencyScore + stabilityScore + consistency) / 3;\n return Math.min(Math.max(score, 0), 1);\n }\n\n private normalize(value: number, min: number, max: number): number {\n if (max === min) return 0;\n const clamped = Math.max(Math.min(value, max), min);\n return (clamped - min) / (max - min);\n }\n}\n","/**\n * Bounded full-day XNYS session calendar used by the market-data provenance\n * authority. Early closes remain sessions: this calendar answers only whether\n * a complete daily partition is expected for a date.\n *\n * The revision changes whenever supported bounds or closure semantics change.\n */\nexport const XNYS_SESSION_CALENDAR_REVISION = \"xnys-full-day-2022-2030-v1\" as const;\nexport const XNYS_SESSION_CALENDAR_SUPPORTED_FROM = \"2022-01-01\" as const;\nexport const XNYS_SESSION_CALENDAR_SUPPORTED_THROUGH = \"2030-12-31\" as const;\n\nconst ISO_DATE_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\nconst MS_PER_DAY = 24 * 60 * 60 * 1_000;\n\n/** Non-recurring full-day XNYS closures inside this calendar revision. */\nconst SPECIAL_CLOSURES = new Set([\"2025-01-09\"]);\n\nfunction isoDate(date: Date): string {\n return date.toISOString().slice(0, 10);\n}\n\nfunction utcDate(year: number, monthIndex: number, day: number): Date {\n return new Date(Date.UTC(year, monthIndex, day));\n}\n\nfunction parseSupportedDate(value: string, label: string): Date {\n if (!ISO_DATE_RE.test(value)) {\n throw new TypeError(\n `${label} must be an ISO calendar date (YYYY-MM-DD): ${JSON.stringify(value)}`,\n );\n }\n const parsed = new Date(`${value}T00:00:00.000Z`);\n if (!Number.isFinite(parsed.getTime()) || isoDate(parsed) !== value) {\n throw new TypeError(`${label} is not a real calendar date: ${JSON.stringify(value)}`);\n }\n if (\n value < XNYS_SESSION_CALENDAR_SUPPORTED_FROM ||\n value > XNYS_SESSION_CALENDAR_SUPPORTED_THROUGH\n ) {\n throw new RangeError(\n `${label} ${JSON.stringify(value)} is outside XNYS calendar revision ${XNYS_SESSION_CALENDAR_REVISION} ` +\n `[${XNYS_SESSION_CALENDAR_SUPPORTED_FROM}, ${XNYS_SESSION_CALENDAR_SUPPORTED_THROUGH}]`,\n );\n }\n return parsed;\n}\n\nfunction nthWeekdayOfMonth(\n year: number,\n monthIndex: number,\n weekday: number,\n occurrence: number,\n): Date {\n const first = utcDate(year, monthIndex, 1);\n const offset = (weekday - first.getUTCDay() + 7) % 7;\n return utcDate(year, monthIndex, 1 + offset + (occurrence - 1) * 7);\n}\n\nfunction lastWeekdayOfMonth(year: number, monthIndex: number, weekday: number): Date {\n const last = utcDate(year, monthIndex + 1, 0);\n const offset = (last.getUTCDay() - weekday + 7) % 7;\n return utcDate(year, monthIndex, last.getUTCDate() - offset);\n}\n\n/** Meeus/Jones/Butcher Gregorian Easter calculation. */\nfunction easterSunday(year: number): Date {\n const a = year % 19;\n const b = Math.floor(year / 100);\n const c = year % 100;\n const d = Math.floor(b / 4);\n const e = b % 4;\n const f = Math.floor((b + 8) / 25);\n const g = Math.floor((b - f + 1) / 3);\n const h = (19 * a + b - d - g + 15) % 30;\n const i = Math.floor(c / 4);\n const k = c % 4;\n const l = (32 + 2 * e + 2 * i - h - k) % 7;\n const m = Math.floor((a + 11 * h + 22 * l) / 451);\n const month = Math.floor((h + l - 7 * m + 114) / 31);\n const day = ((h + l - 7 * m + 114) % 31) + 1;\n return utcDate(year, month - 1, day);\n}\n\nfunction addDays(date: Date, days: number): Date {\n return new Date(date.getTime() + days * MS_PER_DAY);\n}\n\nfunction observedFixedHoliday(year: number, monthIndex: number, day: number): Date {\n const holiday = utcDate(year, monthIndex, day);\n if (holiday.getUTCDay() === 6) return addDays(holiday, -1);\n if (holiday.getUTCDay() === 0) return addDays(holiday, 1);\n return holiday;\n}\n\nfunction addNewYearsClosure(closures: Set<string>, holidayYear: number): void {\n const holiday = utcDate(holidayYear, 0, 1);\n if (holiday.getUTCDay() === 6) {\n // XNYS does not observe a Saturday January 1 on the preceding Friday.\n // This exception keeps year-end accounting open (for example 2027-12-31).\n return;\n }\n closures.add(isoDate(holiday.getUTCDay() === 0 ? addDays(holiday, 1) : holiday));\n}\n\nfunction holidayClosures(year: number): ReadonlySet<string> {\n const closures = new Set<string>();\n const add = (date: Date): void => {\n closures.add(isoDate(date));\n };\n\n // Include both holiday years so an observation that crosses into this\n // calendar year cannot escape the year-local closure set.\n addNewYearsClosure(closures, year);\n addNewYearsClosure(closures, year + 1);\n add(nthWeekdayOfMonth(year, 0, 1, 3)); // Martin Luther King Jr. Day\n add(nthWeekdayOfMonth(year, 1, 1, 3)); // Washington's Birthday\n add(addDays(easterSunday(year), -2)); // Good Friday\n add(lastWeekdayOfMonth(year, 4, 1)); // Memorial Day\n add(observedFixedHoliday(year, 5, 19)); // Juneteenth\n add(observedFixedHoliday(year, 6, 4)); // Independence Day\n add(nthWeekdayOfMonth(year, 8, 1, 1)); // Labor Day\n add(nthWeekdayOfMonth(year, 10, 4, 4)); // Thanksgiving Day\n add(observedFixedHoliday(year, 11, 25)); // Christmas Day\n\n for (const date of SPECIAL_CLOSURES) {\n if (date.startsWith(`${year}-`)) closures.add(date);\n }\n return closures;\n}\n\nconst CLOSURES_BY_YEAR = new Map<number, ReadonlySet<string>>();\n\nfunction closuresForYear(year: number): ReadonlySet<string> {\n let closures = CLOSURES_BY_YEAR.get(year);\n if (!closures) {\n closures = holidayClosures(year);\n CLOSURES_BY_YEAR.set(year, closures);\n }\n return closures;\n}\n\n/**\n * Return whether a supported calendar date is a full XNYS market session.\n * Invalid or unsupported dates throw so provenance completeness cannot turn an\n * unknown date into a presumed non-session.\n */\nexport function isXnysSessionDate(value: string): boolean {\n const date = parseSupportedDate(value, \"XNYS session date\");\n const weekday = date.getUTCDay();\n if (weekday === 0 || weekday === 6) return false;\n return !closuresForYear(date.getUTCFullYear()).has(value);\n}\n/** Equity early closes are 13:00 ET; full-day closures are never early sessions. */\nexport function isEarlyCloseSession(value: string): boolean {\n if (!isXnysSessionDate(value)) return false;\n const date = new Date(`${value}T12:00:00Z`);\n const year = date.getUTCFullYear();\n const month = date.getUTCMonth();\n const day = date.getUTCDate();\n if ((month === 6 && day === 3) || (month === 11 && day === 24)) return true;\n return value === isoDate(addDays(nthWeekdayOfMonth(year, 10, 4, 4), 1));\n}\n\n/** Deterministically enumerate XNYS sessions in the inclusive supported range. */\nexport function enumerateXnysSessions(from: string, through: string): readonly string[] {\n const first = parseSupportedDate(from, \"XNYS session range from\");\n const last = parseSupportedDate(through, \"XNYS session range through\");\n if (first.getTime() > last.getTime()) {\n throw new RangeError(\n `XNYS session range from ${JSON.stringify(from)} exceeds through ${JSON.stringify(through)}`,\n );\n }\n\n const sessions: string[] = [];\n for (let cursor = first; cursor.getTime() <= last.getTime(); cursor = addDays(cursor, 1)) {\n const date = isoDate(cursor);\n if (isXnysSessionDate(date)) sessions.push(date);\n }\n return Object.freeze(sessions);\n}\n","import { resolveSofrRateByKey, resolveTreasuryRateByKey } from \"@tradeblocks/lib\";\nimport type { PutContentObjectResult } from \"./content-object-store.ts\";\nimport type { ContentObjectStore } from \"./content-object-store.ts\";\nimport { isXnysSessionDate } from \"./xnys-session-calendar.ts\";\n\nexport const CANONICAL_RATE_SLICE_KIND = \"tradeblocks.market-data.rate-slice\" as const;\nexport const CANONICAL_RATE_SLICE_VERSION = 1 as const;\n\nexport type CanonicalRateDataClass = \"sofr_rates\" | \"treasury_rates\";\nexport type CanonicalRateSeries = \"sofr\" | \"treasury_3m\";\n\nexport interface CanonicalRateSliceV1 {\n kind: typeof CANONICAL_RATE_SLICE_KIND;\n version: typeof CANONICAL_RATE_SLICE_VERSION;\n series: CanonicalRateSeries;\n requestedDate: string;\n effectiveDate: string;\n annualRateBasisPoints: number;\n resolution: \"exact\" | \"prior\" | \"clamped-earliest\";\n}\n\nexport async function publishCanonicalRateSlice(\n objects: ContentObjectStore,\n dataClass: CanonicalRateDataClass,\n requestedDate: string,\n): Promise<PutContentObjectResult<CanonicalRateSliceV1>> {\n if (dataClass !== \"sofr_rates\" && dataClass !== \"treasury_rates\") {\n throw new TypeError(`Unsupported canonical rate data class: ${JSON.stringify(dataClass)}`);\n }\n if (!isXnysSessionDate(requestedDate)) {\n throw new TypeError(\n `Canonical rate slice date is not an XNYS session: ${JSON.stringify(requestedDate)}`,\n );\n }\n const resolved =\n dataClass === \"sofr_rates\"\n ? resolveSofrRateByKey(requestedDate)\n : resolveTreasuryRateByKey(requestedDate);\n if (resolved.resolution === \"clamped-earliest\") {\n throw new Error(\n `Canonical ${dataClass} input starts at ${resolved.effectiveDate}; ` +\n `refusing lookahead-shaped request for earlier session ${requestedDate}`,\n );\n }\n if (resolved.resolution === \"stale-after-latest\") {\n throw new Error(\n `Canonical ${dataClass} input is stale after ${resolved.effectiveDate}; ` +\n `refusing requested session ${requestedDate}`,\n );\n }\n return objects.put({\n kind: CANONICAL_RATE_SLICE_KIND,\n version: CANONICAL_RATE_SLICE_VERSION,\n series: dataClass === \"sofr_rates\" ? \"sofr\" : \"treasury_3m\",\n requestedDate: resolved.requestedDate,\n effectiveDate: resolved.effectiveDate,\n annualRateBasisPoints: resolved.annualRateBasisPoints,\n resolution: resolved.resolution,\n });\n}\n"],"mappings":"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","names":["address","fs","path","stat","address","createHash","randomUUID","fs","path","path","relativePath","stat","createHash","snapshot","randomUUID","ticket","resolve","address","stat","compareCodePoints","address","existsSync","path","path","path","createHash","fs","path","createHash","escapeSqlLiteral","syncDirectory","relativePath","escapeSqlLiteral","existsSync","constants","fs","path","observedKeys","relative","path","z","z","compareCodePoints","compareCodePoints","compareCodePoints","compareCodePoints","normalized","compareCodePoints","relativePath","resolverClass","stat","constants"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/market/provenance/canonical-json.ts","../../../src/market/provenance/content-object-store.ts","../../../src/market/provenance/durable-directory.ts","../../../src/market/provenance/partition-commit-store.ts","../../../src/market/provenance/dataset-registry.ts","../../../src/market/provenance/partition-commit-attempt.ts","../../../src/market/provenance/xnys-calendar-data.ts","../../../src/market/provenance/xnys-session-calendar.ts","../../../src/market/stores/enriched-legacy-migration.ts","../../../src/db/market-datasets.ts","../../../src/db/data-root.ts","../../../src/db/parquet-writer.ts","../../../src/market/tickers/schemas.ts","../../../src/market/provenance/canonical-market-resolver.ts","../../../src/market/provenance/content-manifest.ts","../../../src/market/provenance/refresh-completion.ts","../../../src/utils/providers/thetadata/bulk-roots.ts","../../../src/db/json-adapters.ts","../../../../lib/calculations/walk-forward-analyzer.ts","../../../src/market/provenance/rate-slices.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\n\n/**\n * Canonical JSON version used by the market-data provenance object store.\n *\n * The version defines normalization and numeric semantics. Addresses remain\n * ordinary SHA-256 addresses of the exact encoded bytes.\n */\nexport const CANONICAL_JSON_VERSION = 1 as const;\n\nexport type Sha256Address = `sha256:${string}`;\nexport type CanonicalJsonAddress = Sha256Address;\n\nconst SHA256_ADDRESS_RE = /^sha256:([0-9a-f]{64})$/;\n\nfunction compareCodePoints(left: string, right: string): number {\n const leftPoints = Array.from(left, (char) => char.codePointAt(0) as number);\n const rightPoints = Array.from(right, (char) => char.codePointAt(0) as number);\n const length = Math.min(leftPoints.length, rightPoints.length);\n for (let i = 0; i < length; i++) {\n if (leftPoints[i] !== rightPoints[i]) return leftPoints[i] - rightPoints[i];\n }\n return leftPoints.length - rightPoints.length;\n}\n\nfunction encode(value: unknown, seen: WeakSet<object>): string {\n if (value === null) return \"null\";\n\n switch (typeof value) {\n case \"string\":\n return JSON.stringify(value.normalize(\"NFC\"));\n case \"boolean\":\n return value ? \"true\" : \"false\";\n case \"number\":\n if (!Number.isSafeInteger(value)) {\n throw new TypeError(\"Canonical JSON v1 supports only safe integers\");\n }\n // JSON.stringify already emits ECMAScript's shortest round-trippable\n // representation and normalizes negative zero to zero.\n return JSON.stringify(value);\n case \"undefined\":\n case \"function\":\n case \"symbol\":\n case \"bigint\":\n throw new TypeError(`Canonical JSON does not support ${typeof value}`);\n case \"object\":\n break;\n }\n\n const object = value as object;\n if (seen.has(object)) throw new TypeError(\"Canonical JSON does not support cyclic values\");\n seen.add(object);\n try {\n if (Array.isArray(value)) {\n const elements: string[] = [];\n for (let i = 0; i < value.length; i++) {\n if (!(i in value)) throw new TypeError(\"Canonical JSON does not support sparse arrays\");\n elements.push(encode(value[i], seen));\n }\n return `[${elements.join(\",\")}]`;\n }\n\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) {\n throw new TypeError(\"Canonical JSON accepts only plain objects and arrays\");\n }\n\n const normalizedKeys = new Map<string, string>();\n for (const sourceKey of Object.keys(value as Record<string, unknown>)) {\n const normalizedKey = sourceKey.normalize(\"NFC\");\n const collision = normalizedKeys.get(normalizedKey);\n if (collision !== undefined && collision !== sourceKey) {\n throw new TypeError(\n `Canonical JSON key collision after NFC normalization: ${JSON.stringify(collision)} and ${JSON.stringify(sourceKey)}`,\n );\n }\n normalizedKeys.set(normalizedKey, sourceKey);\n }\n const entries = [...normalizedKeys.entries()]\n .sort(([left], [right]) => compareCodePoints(left, right))\n .map(\n ([normalizedKey, sourceKey]) =>\n `${JSON.stringify(normalizedKey)}:${encode((value as Record<string, unknown>)[sourceKey], seen)}`,\n );\n return `{${entries.join(\",\")}}`;\n } finally {\n seen.delete(object);\n }\n}\n\n/** Encode a JSON value with stable recursive object-key ordering. */\nexport function canonicalJson(value: unknown): string {\n return encode(value, new WeakSet<object>());\n}\n\nexport function canonicalJsonBytes(value: unknown): Buffer {\n return Buffer.from(canonicalJson(value), \"utf8\");\n}\n\n/** Address the exact canonical JSON bytes. */\nexport function addressCanonicalJson(value: unknown): CanonicalJsonAddress {\n return addressBytes(canonicalJsonBytes(value));\n}\n\n/** Address exact binary bytes, such as a completed Parquet file. */\nexport function addressBytes(bytes: Uint8Array): Sha256Address {\n const digest = createHash(\"sha256\").update(bytes).digest(\"hex\");\n return `sha256:${digest}`;\n}\n\nexport function parseCanonicalJsonAddress(address: string): string {\n return parseSha256Address(address);\n}\n\nexport function parseSha256Address(address: string): string {\n const match = SHA256_ADDRESS_RE.exec(address);\n if (!match) throw new TypeError(`Invalid SHA-256 address: ${JSON.stringify(address)}`);\n return match[1];\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport {\n addressBytes,\n canonicalJsonBytes,\n parseCanonicalJsonAddress,\n type CanonicalJsonAddress,\n} from \"./canonical-json.ts\";\nimport { DurableDirectories, syncDirectory } from \"./durable-directory.ts\";\n\nexport interface PutContentObjectResult<T> {\n address: CanonicalJsonAddress;\n value: T;\n path: string;\n bytes: number;\n created: boolean;\n}\n\nexport class ContentObjectCollisionError extends Error {\n readonly address: CanonicalJsonAddress;\n readonly objectPath: string;\n\n constructor(address: CanonicalJsonAddress, objectPath: string) {\n super(`Content object collision or corruption at ${address} (${objectPath})`);\n this.name = \"ContentObjectCollisionError\";\n this.address = address;\n this.objectPath = objectPath;\n }\n}\n\nfunction deepFreeze<T>(value: T): T {\n if (value && typeof value === \"object\" && !Object.isFrozen(value)) {\n for (const child of Object.values(value as Record<string, unknown>)) deepFreeze(child);\n Object.freeze(value);\n }\n return value;\n}\n\n/**\n * Immutable canonical-JSON object store.\n *\n * Temp objects are created with `wx` and installed by a no-replace hard link;\n * an existing address is never replaced. Repeating an identical put is\n * idempotent, while different bytes at the same address are treated as\n * collision/corruption and fail closed.\n */\nexport class ContentObjectStore {\n readonly rootDir: string;\n private readonly directories = new DurableDirectories();\n\n constructor(rootDir: string) {\n this.rootDir = rootDir;\n }\n\n objectPath(address: CanonicalJsonAddress): string {\n const digest = parseCanonicalJsonAddress(address);\n return path.join(this.rootDir, \"objects\", \"sha256\", digest.slice(0, 2), `${digest}.json`);\n }\n\n private async syncExistingObject(objectPath: string): Promise<void> {\n const handle = await fs.open(objectPath, \"r\");\n try {\n await handle.sync();\n } finally {\n await handle.close();\n }\n await syncDirectory(path.dirname(objectPath));\n }\n\n async put<T>(value: T): Promise<PutContentObjectResult<T>> {\n // Encode once. Accessors and mutable input objects must not be able to make\n // an address computed by a second traversal disagree with published bytes.\n const bytes = canonicalJsonBytes(value);\n const address = addressBytes(bytes);\n const materialized = deepFreeze(JSON.parse(bytes.toString(\"utf8\")) as T);\n const objectPath = this.objectPath(address);\n const objectDir = path.dirname(objectPath);\n await this.directories.ensure(objectDir);\n const tempPath = path.join(objectDir, `.${path.basename(objectPath)}.tmp-${randomUUID()}`);\n\n let handle: fs.FileHandle | undefined;\n try {\n // Publish only after the full object is durable. link(2) is an atomic\n // no-replace operation: unlike rename(), it fails with EEXIST and can\n // never overwrite an immutable object installed by another writer.\n handle = await fs.open(tempPath, \"wx\", 0o444);\n await handle.writeFile(bytes);\n await handle.sync();\n await handle.close();\n handle = undefined;\n await fs.link(tempPath, objectPath);\n await syncDirectory(objectDir);\n await fs.unlink(tempPath);\n await syncDirectory(objectDir);\n return {\n address,\n value: materialized,\n path: objectPath,\n bytes: bytes.byteLength,\n created: true,\n };\n } catch (error) {\n await handle?.close();\n handle = undefined;\n await fs.unlink(tempPath).catch(() => undefined);\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n const existing = await fs.readFile(objectPath);\n if (!existing.equals(bytes)) throw new ContentObjectCollisionError(address, objectPath);\n // The EEXIST winner may have linked the inode but not yet completed its\n // durability barrier. An idempotent caller supplies that barrier before\n // reporting success.\n await this.syncExistingObject(objectPath);\n return {\n address,\n value: materialized,\n path: objectPath,\n bytes: bytes.byteLength,\n created: false,\n };\n } finally {\n await handle?.close();\n }\n }\n\n async get<T>(address: CanonicalJsonAddress): Promise<T> {\n const objectPath = this.objectPath(address);\n const bytes = await fs.readFile(objectPath);\n // Identity is established from the exact stored bytes before parsing. A\n // parse/reserialize cycle must never be allowed to bless changed bytes.\n const digestAddress = addressBytes(bytes);\n if (digestAddress !== address) throw new ContentObjectCollisionError(address, objectPath);\n const value = JSON.parse(bytes.toString(\"utf8\")) as T;\n if (!canonicalJsonBytes(value).equals(bytes)) {\n throw new ContentObjectCollisionError(address, objectPath);\n }\n return deepFreeze(value);\n }\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\n\n/** fsync a directory so entries created, linked, renamed or removed in it are durable. */\nexport async function syncDirectory(directory: string): Promise<void> {\n const handle = await fs.open(directory, \"r\");\n try {\n await handle.sync();\n } finally {\n await handle.close();\n }\n}\n\ntype DirectoryIdentity = string;\n\n/**\n * Device, inode and birth time name one directory generation. Without a birth\n * time a reused inode would look like the directory already synced, so a\n * filesystem that reports none yields no identity and the directory is never\n * treated as known.\n */\nfunction identityOf(stat: {\n dev: bigint;\n ino: bigint;\n birthtimeNs: bigint;\n}): DirectoryIdentity | undefined {\n if (stat.birthtimeNs === 0n) return undefined;\n return `${stat.dev}:${stat.ino}:${stat.birthtimeNs}`;\n}\n\nasync function syncDirectoryIdentity(directory: string): Promise<DirectoryIdentity | undefined> {\n const handle = await fs.open(directory, \"r\");\n try {\n const identity = identityOf(await handle.stat({ bigint: true }));\n await handle.sync();\n return identity;\n } finally {\n await handle.close();\n }\n}\n\nasync function currentIdentity(directory: string): Promise<DirectoryIdentity | undefined> {\n try {\n return identityOf(await fs.stat(directory, { bigint: true }));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return undefined;\n throw error;\n }\n}\n\n/**\n * Directories one store instance has made durable, keyed by path and pinned to\n * the directory inode that was synced.\n *\n * Invariant: when `ensure(directory)` resolves, `directory` exists, and it and\n * every ancestor up to `/` were each fsynced, with its entry fsynced in its\n * parent, after that ancestor's current inode was created. This instance\n * performs those syncs the first time it meets each directory: on creation, or\n * on first sight of a directory someone else created. A later call skips a\n * directory whose path still resolves to the same device, inode and birth time,\n * because a durable entry stays durable until it is removed or renamed.\n * Removing or recreating a directory gives the path a new identity, so it is\n * synced again, together with its parent entry. Where the filesystem reports\n * no birth time, no identity is recorded and every call syncs the directory\n * and its parent, as before this memo. The store never renames directories it\n * ensures; an external rename of an ancestor is outside this invariant.\n */\nexport class DurableDirectories {\n private readonly known = new Map<string, DirectoryIdentity>();\n\n async ensure(directory: string): Promise<void> {\n const known = this.known.get(directory);\n if (known !== undefined) {\n if ((await currentIdentity(directory)) === known) return;\n this.known.delete(directory);\n }\n\n const parent = path.dirname(directory);\n if (parent !== directory) await this.ensure(parent);\n try {\n await fs.mkdir(directory);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n }\n // Sync the directory before anything is published into it, and its parent\n // so its own entry is durable. A directory another writer just created may\n // not have finished either sync, so an existing directory gets both too.\n const identity = await syncDirectoryIdentity(directory);\n if (parent !== directory) await syncDirectory(parent);\n if (identity !== undefined) this.known.set(directory, identity);\n }\n}\n","import { createHash, randomUUID } from \"node:crypto\";\nimport type { DuckDBConnection } from \"@duckdb/node-api\";\nimport { constants, readFileSync } from \"node:fs\";\nimport * as fs from \"node:fs/promises\";\nimport { hostname } from \"node:os\";\nimport * as path from \"node:path\";\nimport {\n addressBytes,\n addressCanonicalJson,\n canonicalJsonBytes,\n parseCanonicalJsonAddress,\n parseSha256Address,\n type CanonicalJsonAddress,\n type Sha256Address,\n} from \"./canonical-json.ts\";\nimport { ContentObjectCollisionError, ContentObjectStore } from \"./content-object-store.ts\";\nimport { DurableDirectories, syncDirectory } from \"./durable-directory.ts\";\nimport {\n canonicalPartitionDataset,\n canonicalPartitionRelativePath,\n isRealMarketSessionDate,\n validatePartitionIdentity,\n} from \"./dataset-registry.ts\";\n\nexport const PARTITION_COMMIT_RECEIPT_KIND = \"tradeblocks.market-data.partition-commit\" as const;\nexport const PARTITION_COMMIT_RECEIPT_VERSION = 1 as const;\nexport const PARTITION_COMMIT_EVENT_KIND =\n \"tradeblocks.market-data.partition-commit-event\" as const;\nexport const PARTITION_COMMIT_EVENT_VERSION = 1 as const;\nexport const PARTITION_HEAD_KIND = \"tradeblocks.market-data.partition-head\" as const;\nexport const PARTITION_HEAD_VERSION = 1 as const;\n\nexport type PartitionCommitClassification = \"append\" | \"repair\";\n\nexport type LogicalCoverage =\n { kind: \"date-range\"; from: string; through: string } | { kind: \"empty\" };\n\nexport interface PartitionQualityCounts {\n inputRows: number;\n writtenRows: number;\n droppedRows: number;\n}\n\nexport interface ExactFileFingerprint {\n address: Sha256Address;\n bytes: number;\n rows: number;\n}\n\nexport interface PartitionIdentity {\n dataset: string;\n partition: Record<string, string>;\n}\n\nexport interface PartitionCommitReceiptV1 extends PartitionIdentity {\n kind: typeof PARTITION_COMMIT_RECEIPT_KIND;\n version: typeof PARTITION_COMMIT_RECEIPT_VERSION;\n schemaRevision: number;\n relativePath: string;\n coverage: LogicalCoverage;\n quality: PartitionQualityCounts;\n file: ExactFileFingerprint;\n classification: PartitionCommitClassification;\n parent?: CanonicalJsonAddress;\n}\n\nexport interface PartitionCommitEventV1 extends PartitionIdentity {\n kind: typeof PARTITION_COMMIT_EVENT_KIND;\n version: typeof PARTITION_COMMIT_EVENT_VERSION;\n receipt: CanonicalJsonAddress;\n previous?: CanonicalJsonAddress;\n}\n\nexport interface StoredPartitionCommit {\n address: CanonicalJsonAddress;\n receipt: PartitionCommitReceiptV1;\n created: boolean;\n}\n\nexport interface RecordPartitionCommitInput extends PartitionIdentity {\n schemaRevision: number;\n relativePath: string;\n coverage: LogicalCoverage;\n quality: PartitionQualityCounts;\n file: ExactFileFingerprint;\n}\n\nexport interface PublishPartitionFileInput extends RecordPartitionCommitInput {\n /** Completed sibling file that has not yet been installed. */\n preparedPath: string;\n /** Caller expectation; the store derives and verifies this from relativePath. */\n expectedTargetPath: string;\n}\n\n/**\n * Package-internal capability used only to bring validated historical\n * canonical-layout bytes under authority. It is deliberately a symbol so the\n * exported store does not expose a general string-named \"bless this file\"\n * operation. The migration caller must first validate its legacy source and\n * XNYS session; the store independently revalidates canonical schema,\n * partition identity, coverage, inode, and exact bytes.\n */\nexport const INTERNAL_HISTORICAL_PARTITION_ADOPTION = Symbol(\n \"tradeblocks.internal.historical-partition-adoption\",\n);\n\nexport interface PartitionCommitRecorder {\n publishFileCommit(input: PublishPartitionFileInput): Promise<StoredPartitionCommit>;\n readCommit(address: CanonicalJsonAddress): Promise<StoredPartitionCommit>;\n}\n\nexport interface FilePartitionCommitStoreOptions {\n /** A provably dead local claim is recoverable after this age. Defaults to 30 seconds. */\n staleLockMs?: number;\n /** Maximum time to wait for an earlier or ambiguous claim. Defaults to 5 seconds. */\n lockWaitMs?: number;\n}\n\ninterface PartitionLockOwner {\n kind: \"tradeblocks.market-data.partition-lock-owner\";\n version: 1;\n token: string;\n pid: number;\n hostname: string;\n bootId: string;\n createdAtMs: number;\n}\n\ninterface PartitionLockTicket {\n kind: \"tradeblocks.market-data.partition-lock-ticket\";\n version: 1;\n token: string;\n number: number;\n}\n\ninterface PartitionHeadV1 extends PartitionIdentity {\n kind: typeof PARTITION_HEAD_KIND;\n version: typeof PARTITION_HEAD_VERSION;\n receipt: CanonicalJsonAddress;\n event: CanonicalJsonAddress;\n}\n\ninterface AuthorityTip {\n eventAddress: CanonicalJsonAddress;\n commit: StoredPartitionCommit;\n}\n\ntype PartitionCommitTestFaultPoint =\n | \"after-claim-open\"\n | \"after-event-before-head\"\n | \"historical-after-snapshot\"\n | \"before-release-claim\";\nconst partitionCommitTestFaults = new WeakMap<\n FilePartitionCommitStore,\n (point: PartitionCommitTestFaultPoint) => void | Promise<void>\n>();\n\n/** @internal Test-only deterministic crash-boundary injection; not in the public barrel. */\nexport function setPartitionCommitTestFault(\n store: FilePartitionCommitStore,\n fault?: (point: PartitionCommitTestFaultPoint) => void | Promise<void>,\n): void {\n if (fault) partitionCommitTestFaults.set(store, fault);\n else partitionCommitTestFaults.delete(store);\n}\n\nfunction attachPartitionLockCleanupError(primary: unknown, cleanup: unknown): unknown {\n if (primary instanceof Error) {\n try {\n Object.defineProperty(primary, \"cleanupError\", {\n value: cleanup,\n enumerable: false,\n configurable: true,\n });\n return primary;\n } catch {\n // A frozen/custom Error cannot carry the attachment; preserve both\n // failures without discarding the operation error.\n }\n }\n return new AggregateError(\n [primary, cleanup],\n \"Partition operation failed and its lock claim could not be released\",\n { cause: primary },\n );\n}\n\nexport type PartitionInspection =\n | { status: \"absent\" }\n | { status: \"orphan\"; observed: Omit<ExactFileFingerprint, \"rows\"> }\n | { status: \"missing\"; receipt: StoredPartitionCommit }\n | {\n status: \"mismatch\";\n receipt: StoredPartitionCommit;\n observed: Omit<ExactFileFingerprint, \"rows\">;\n }\n | { status: \"match\"; receipt: StoredPartitionCommit };\n\n/** A canonical partition path does not name the regular file inode being verified. */\nexport class PartitionFileIntegrityError extends Error {\n readonly filePath: string;\n\n constructor(filePath: string, reason: string, cause?: unknown) {\n super(`Invalid partition file (${reason}): ${filePath}`, {\n ...(cause === undefined ? {} : { cause }),\n });\n this.name = \"PartitionFileIntegrityError\";\n this.filePath = filePath;\n }\n}\n\nconst TOKEN_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;\nconst CURRENT_HOSTNAME = hostname();\nconst CURRENT_BOOT_ID = (() => {\n try {\n const value = readFileSync(\"/proc/sys/kernel/random/boot_id\", \"utf8\").trim();\n return value.length > 0 ? value : \"unavailable\";\n } catch {\n return \"unavailable\";\n }\n})();\n\nfunction validateIdentity(identity: PartitionIdentity): void {\n validatePartitionIdentity(identity);\n}\n\nfunction canonicalRelativePath(identity: PartitionIdentity): string {\n return canonicalPartitionRelativePath(identity);\n}\n\nfunction validateRelativePath(relativePath: string): void {\n if (\n relativePath.length === 0 ||\n relativePath.includes(\"\\\\\") ||\n path.posix.isAbsolute(relativePath) ||\n relativePath.split(\"/\").some((part) => part === \"..\" || part === \".\" || part === \"\")\n ) {\n throw new TypeError(`Invalid provenance relative path: ${JSON.stringify(relativePath)}`);\n }\n}\n\nfunction validateRegistryPath(identity: PartitionIdentity, relativePath: string): void {\n validateRelativePath(relativePath);\n const expected = canonicalRelativePath(identity);\n if (relativePath !== expected) {\n throw new TypeError(\n `Provenance path does not match the registered partition: ${JSON.stringify({ expected, observed: relativePath })}`,\n );\n }\n}\n\nfunction validateFingerprint(file: ExactFileFingerprint): void {\n parseSha256Address(file.address);\n if (!Number.isSafeInteger(file.bytes) || file.bytes < 0) {\n throw new TypeError(`Invalid provenance byte count: ${file.bytes}`);\n }\n if (!Number.isSafeInteger(file.rows) || file.rows < 0) {\n throw new TypeError(`Invalid provenance row count: ${file.rows}`);\n }\n}\n\nfunction validateCoverage(coverage: LogicalCoverage, rows: number): void {\n if (coverage.kind === \"empty\") {\n if (rows !== 0) throw new TypeError(\"Non-empty partition cannot have empty logical coverage\");\n return;\n }\n if (!isRealMarketSessionDate(coverage.from) || !isRealMarketSessionDate(coverage.through)) {\n throw new TypeError(`Invalid logical date coverage: ${JSON.stringify(coverage)}`);\n }\n if (coverage.from > coverage.through) {\n throw new TypeError(`Logical coverage starts after it ends: ${JSON.stringify(coverage)}`);\n }\n if (rows === 0) throw new TypeError(\"Empty partition cannot have non-empty logical coverage\");\n}\n\nfunction validateQuality(quality: PartitionQualityCounts, file: ExactFileFingerprint): void {\n for (const [name, count] of Object.entries(quality)) {\n if (!Number.isSafeInteger(count) || count < 0) {\n throw new TypeError(`Invalid provenance ${name}: ${count}`);\n }\n }\n if (quality.writtenRows !== file.rows) {\n throw new TypeError(\n `Provenance writtenRows ${quality.writtenRows} does not match file rows ${file.rows}`,\n );\n }\n if (quality.inputRows !== quality.writtenRows + quality.droppedRows) {\n throw new TypeError(\"Provenance inputRows must equal writtenRows + droppedRows\");\n }\n}\n\nfunction validateInput(input: RecordPartitionCommitInput): void {\n validateIdentity(input);\n if (!Number.isSafeInteger(input.schemaRevision) || input.schemaRevision < 1) {\n throw new TypeError(`Invalid schema revision: ${input.schemaRevision}`);\n }\n validateRegistryPath(input, input.relativePath);\n validateFingerprint(input.file);\n validateCoverage(input.coverage, input.file.rows);\n validateQuality(input.quality, input.file);\n const date = input.partition[canonicalPartitionDataset(input.dataset)!.provenance.sessionKey];\n if (\n input.coverage.kind === \"date-range\" &&\n (input.coverage.from !== date || input.coverage.through !== date)\n ) {\n throw new TypeError(\n `Partition logical coverage must equal its registered date: ${JSON.stringify({ date, coverage: input.coverage })}`,\n );\n }\n}\n\nconst CANONICAL_PARQUET_SCHEMAS: Readonly<\n Record<string, readonly (readonly [name: string, type: string])[]>\n> = Object.freeze({\n spot: [\n [\"ticker\", \"VARCHAR\"],\n [\"date\", \"VARCHAR\"],\n [\"time\", \"VARCHAR\"],\n [\"open\", \"DOUBLE\"],\n [\"high\", \"DOUBLE\"],\n [\"low\", \"DOUBLE\"],\n [\"close\", \"DOUBLE\"],\n [\"bid\", \"DOUBLE\"],\n [\"ask\", \"DOUBLE\"],\n ],\n enriched: [\n [\"ticker\", \"VARCHAR\"],\n [\"date\", \"VARCHAR\"],\n [\"Prior_Close\", \"DOUBLE\"],\n [\"Gap_Pct\", \"DOUBLE\"],\n [\"ATR_Pct\", \"DOUBLE\"],\n [\"RSI_14\", \"DOUBLE\"],\n [\"Price_vs_EMA21_Pct\", \"DOUBLE\"],\n [\"Price_vs_SMA50_Pct\", \"DOUBLE\"],\n [\"Realized_Vol_5D\", \"DOUBLE\"],\n [\"Realized_Vol_20D\", \"DOUBLE\"],\n [\"Return_5D\", \"DOUBLE\"],\n [\"Return_20D\", \"DOUBLE\"],\n [\"Intraday_Range_Pct\", \"DOUBLE\"],\n [\"Intraday_Return_Pct\", \"DOUBLE\"],\n [\"Close_Position_In_Range\", \"DOUBLE\"],\n [\"Gap_Filled\", \"INTEGER\"],\n [\"Consecutive_Days\", \"INTEGER\"],\n [\"Prev_Return_Pct\", \"DOUBLE\"],\n [\"Prior_Range_vs_ATR\", \"DOUBLE\"],\n [\"High_Time\", \"DOUBLE\"],\n [\"Low_Time\", \"DOUBLE\"],\n [\"High_Before_Low\", \"INTEGER\"],\n [\"Reversal_Type\", \"INTEGER\"],\n [\"Opening_Drive_Strength\", \"DOUBLE\"],\n [\"Intraday_Realized_Vol\", \"DOUBLE\"],\n [\"Day_of_Week\", \"INTEGER\"],\n [\"Month\", \"INTEGER\"],\n [\"Is_Opex\", \"INTEGER\"],\n [\"ivr\", \"DOUBLE\"],\n [\"ivp\", \"DOUBLE\"],\n ],\n enriched_context: [\n [\"date\", \"VARCHAR\"],\n [\"Vol_Regime\", \"INTEGER\"],\n [\"Term_Structure_State\", \"INTEGER\"],\n [\"Trend_Direction\", \"VARCHAR\"],\n [\"VIX_Spike_Pct\", \"DOUBLE\"],\n [\"VIX_Gap_Pct\", \"DOUBLE\"],\n ],\n option_chain: [\n [\"underlying\", \"VARCHAR\"],\n [\"date\", \"VARCHAR\"],\n [\"ticker\", \"VARCHAR\"],\n [\"contract_type\", \"VARCHAR\"],\n [\"strike\", \"DOUBLE\"],\n [\"expiration\", \"VARCHAR\"],\n [\"dte\", \"INTEGER\"],\n [\"exercise_style\", \"VARCHAR\"],\n ],\n option_quote_minutes: [\n [\"underlying\", \"VARCHAR\"],\n [\"date\", \"VARCHAR\"],\n [\"ticker\", \"VARCHAR\"],\n [\"time\", \"VARCHAR\"],\n [\"bid\", \"DOUBLE\"],\n [\"ask\", \"DOUBLE\"],\n [\"mid\", \"DOUBLE\"],\n [\"last_updated_ns\", \"BIGINT\"],\n [\"source\", \"VARCHAR\"],\n [\"delta\", \"FLOAT\"],\n [\"gamma\", \"FLOAT\"],\n [\"theta\", \"FLOAT\"],\n [\"vega\", \"FLOAT\"],\n [\"iv\", \"FLOAT\"],\n [\"greeks_source\", \"VARCHAR\"],\n [\"greeks_revision\", \"INTEGER\"],\n [\"rate_type\", \"VARCHAR\"],\n [\"rate_value\", \"DOUBLE\"],\n [\"gamma_source\", \"VARCHAR\"],\n ],\n option_oi_daily: [\n [\"underlying\", \"VARCHAR\"],\n [\"date\", \"VARCHAR\"],\n [\"ticker\", \"VARCHAR\"],\n [\"expiration\", \"VARCHAR\"],\n [\"strike\", \"DOUBLE\"],\n [\"right\", \"VARCHAR\"],\n [\"open_interest\", \"BIGINT\"],\n [\"source\", \"VARCHAR\"],\n ],\n});\n\nfunction escapeSqlLiteral(value: string): string {\n return value.replaceAll(\"'\", \"''\");\n}\n\nfunction canonicalDuckDbType(value: unknown): string {\n const normalized = String(value).toUpperCase();\n return normalized === \"REAL\" ? \"FLOAT\" : normalized;\n}\n\n/**\n * @internal Single canonical Parquet schema declaration check. Every consumer\n * (adoption inspection, prepared-file gate inside a commit attempt) verifies\n * through this assertion so the expected schema exists in exactly one place.\n */\nexport async function assertCanonicalParquetSchema(\n conn: DuckDBConnection,\n filePath: string,\n dataset: string,\n): Promise<void> {\n const expectedSchema = CANONICAL_PARQUET_SCHEMAS[dataset];\n if (!expectedSchema) throw new TypeError(`No canonical Parquet schema for ${dataset}`);\n const source = `read_parquet('${escapeSqlLiteral(filePath)}', hive_partitioning=false)`;\n const described = await conn.runAndReadAll(`DESCRIBE SELECT * FROM ${source}`);\n const schema = described\n .getRows()\n .map((row) => [String(row[0]), canonicalDuckDbType(row[1])] as const);\n if (canonicalJsonBytes(schema).compare(canonicalJsonBytes(expectedSchema)) !== 0) {\n throw new Error(\n `Canonical Parquet schema does not match revision 1: ${JSON.stringify({ dataset, observed: schema, expected: expectedSchema })}`,\n );\n }\n}\n\nasync function inspectCanonicalParquet(\n conn: DuckDBConnection,\n filePath: string,\n identity: PartitionIdentity,\n): Promise<{ rows: number; coverage: LogicalCoverage }> {\n await assertCanonicalParquetSchema(conn, filePath, identity.dataset);\n const source = `read_parquet('${escapeSqlLiteral(filePath)}', hive_partitioning=false)`;\n const definition = canonicalPartitionDataset(identity.dataset) as NonNullable<\n ReturnType<typeof canonicalPartitionDataset>\n >;\n const sessionColumn = definition.provenance.sessionKey;\n const predicates = Object.entries(identity.partition)\n .map(\n ([key, value]) =>\n `COUNT(*) FILTER (WHERE \"${key}\" IS NULL OR CAST(\"${key}\" AS VARCHAR) <> '${escapeSqlLiteral(value)}')::BIGINT`,\n )\n .join(\", \");\n const inspected = await conn.runAndReadAll(\n `SELECT COUNT(*)::BIGINT,\n COUNT(\"${sessionColumn}\")::BIGINT,\n MIN(CAST(\"${sessionColumn}\" AS VARCHAR)),\n MAX(CAST(\"${sessionColumn}\" AS VARCHAR)),\n ${predicates}\n FROM ${source}`,\n );\n const row = inspected.getRows()[0];\n const rows = Number(row[0]);\n const coveredRows = Number(row[1]);\n if (!Number.isSafeInteger(rows) || rows <= 0 || coveredRows !== rows) {\n throw new Error(\"Existing canonical Parquet must contain non-null rows for its session\");\n }\n for (const mismatches of row.slice(4)) {\n if (Number(mismatches) !== 0) {\n throw new Error(\"Existing canonical Parquet rows disagree with the registered partition\");\n }\n }\n const from = String(row[2]);\n const through = String(row[3]);\n const expectedSession = identity.partition[sessionColumn];\n if (from !== expectedSession || through !== expectedSession) {\n throw new Error(\"Existing canonical Parquet coverage disagrees with its partition session\");\n }\n return { rows, coverage: { kind: \"date-range\", from, through } };\n}\n\nfunction validateReceipt(receipt: PartitionCommitReceiptV1, identity: PartitionIdentity): void {\n if (\n receipt.kind !== PARTITION_COMMIT_RECEIPT_KIND ||\n receipt.version !== PARTITION_COMMIT_RECEIPT_VERSION ||\n receipt.dataset !== identity.dataset ||\n addressCanonicalJson(receipt.partition) !== addressCanonicalJson(identity.partition)\n ) {\n throw new Error(\"Partition receipt does not match its identity\");\n }\n validateInput(receipt);\n if (receipt.classification !== \"append\" && receipt.classification !== \"repair\") {\n throw new Error(`Invalid partition receipt classification: ${String(receipt.classification)}`);\n }\n if (receipt.classification === \"append\" && receipt.parent !== undefined) {\n throw new Error(\"Append receipt must not have a parent\");\n }\n if (receipt.classification === \"repair\" && receipt.parent === undefined) {\n throw new Error(\"Repair receipt must have a parent\");\n }\n if (receipt.parent !== undefined) parseCanonicalJsonAddress(receipt.parent);\n}\n\nfunction identityAddress(identity: PartitionIdentity): CanonicalJsonAddress {\n return addressCanonicalJson({\n kind: \"tradeblocks.market-data.partition-identity\",\n version: 1,\n dataset: identity.dataset,\n partition: identity.partition,\n });\n}\n\ninterface OpenRegularFile {\n handle: fs.FileHandle;\n stat: Awaited<ReturnType<fs.FileHandle[\"stat\"]>>;\n}\n\nfunction sameInode(\n left: Awaited<ReturnType<fs.FileHandle[\"stat\"]>>,\n right: Awaited<ReturnType<fs.FileHandle[\"stat\"]>>,\n): boolean {\n return left.dev === right.dev && left.ino === right.ino;\n}\n\nasync function openRegularFileNoFollow(filePath: string): Promise<OpenRegularFile> {\n let handle: fs.FileHandle;\n try {\n handle = await fs.open(\n filePath,\n constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK,\n );\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ELOOP\") {\n throw new PartitionFileIntegrityError(filePath, \"symbolic links are not allowed\", error);\n }\n throw error;\n }\n try {\n const stat = await handle.stat();\n if (!stat.isFile()) {\n throw new PartitionFileIntegrityError(filePath, \"expected a regular file\");\n }\n if (stat.nlink !== 1) {\n throw new PartitionFileIntegrityError(filePath, \"expected an unshared regular file inode\");\n }\n return { handle, stat };\n } catch (error) {\n await handle.close();\n throw error;\n }\n}\n\nasync function exactOpenFileAddress(\n handle: fs.FileHandle,\n): Promise<Omit<ExactFileFingerprint, \"rows\">> {\n const hash = createHash(\"sha256\");\n let bytes = 0;\n const buffer = Buffer.allocUnsafe(1024 * 1024);\n while (true) {\n const read = await handle.read(buffer, 0, buffer.byteLength, bytes);\n if (read.bytesRead === 0) break;\n hash.update(buffer.subarray(0, read.bytesRead));\n bytes += read.bytesRead;\n }\n return { address: `sha256:${hash.digest(\"hex\")}`, bytes };\n}\n\nasync function requireNamedRegularInode(\n filePath: string,\n expected: Awaited<ReturnType<fs.FileHandle[\"stat\"]>>,\n): Promise<void> {\n let named: Awaited<ReturnType<typeof fs.lstat>>;\n try {\n named = await fs.lstat(filePath);\n } catch (error) {\n throw new PartitionFileIntegrityError(\n filePath,\n \"verified inode is no longer named here\",\n error,\n );\n }\n if (!named.isFile()) {\n throw new PartitionFileIntegrityError(filePath, \"canonical entry is not a regular file\");\n }\n if (named.nlink !== 1 || expected.nlink !== 1) {\n throw new PartitionFileIntegrityError(filePath, \"canonical inode has multiple hard links\");\n }\n if (!sameInode(expected, named)) {\n throw new PartitionFileIntegrityError(filePath, \"canonical entry changed during verification\");\n }\n}\n\nasync function exactFileAddress(filePath: string): Promise<Omit<ExactFileFingerprint, \"rows\">> {\n const opened = await openRegularFileNoFollow(filePath);\n try {\n const fingerprint = await exactOpenFileAddress(opened.handle);\n const after = await opened.handle.stat();\n if (!after.isFile() || after.nlink !== 1 || !sameInode(opened.stat, after)) {\n throw new PartitionFileIntegrityError(filePath, \"open inode changed during verification\");\n }\n await requireNamedRegularInode(filePath, opened.stat);\n return fingerprint;\n } finally {\n await opened.handle.close();\n }\n}\n\nasync function snapshotOpenFile(\n source: fs.FileHandle,\n snapshotPath: string,\n): Promise<Omit<ExactFileFingerprint, \"rows\">> {\n const snapshot = await fs.open(snapshotPath, \"wx\", 0o400);\n const hash = createHash(\"sha256\");\n let bytes = 0;\n const buffer = Buffer.allocUnsafe(1024 * 1024);\n try {\n while (true) {\n const read = await source.read(buffer, 0, buffer.byteLength, bytes);\n if (read.bytesRead === 0) break;\n hash.update(buffer.subarray(0, read.bytesRead));\n let written = 0;\n while (written < read.bytesRead) {\n const result = await snapshot.write(\n buffer,\n written,\n read.bytesRead - written,\n bytes + written,\n );\n if (result.bytesWritten === 0) throw new Error(\"Unable to write inspection snapshot\");\n written += result.bytesWritten;\n }\n bytes += read.bytesRead;\n }\n await snapshot.sync();\n } finally {\n await snapshot.close();\n }\n return { address: `sha256:${hash.digest(\"hex\")}`, bytes };\n}\n\nfunction sameCommitContent(\n previous: PartitionCommitReceiptV1,\n input: RecordPartitionCommitInput,\n): boolean {\n return (\n previous.schemaRevision === input.schemaRevision &&\n previous.relativePath === input.relativePath &&\n addressCanonicalJson(previous.coverage) === addressCanonicalJson(input.coverage) &&\n addressCanonicalJson(previous.quality) === addressCanonicalJson(input.quality) &&\n previous.file.address === input.file.address &&\n previous.file.bytes === input.file.bytes &&\n previous.file.rows === input.file.rows\n );\n}\n\nfunction captureIdentity(identity: PartitionIdentity): PartitionIdentity {\n const captured = JSON.parse(\n canonicalJsonBytes({ dataset: identity.dataset, partition: identity.partition }).toString(\n \"utf8\",\n ),\n ) as PartitionIdentity;\n validateIdentity(captured);\n return Object.freeze({ ...captured, partition: Object.freeze(captured.partition) });\n}\n\nfunction captureInput(input: RecordPartitionCommitInput): RecordPartitionCommitInput {\n const captured = JSON.parse(\n canonicalJsonBytes({\n dataset: input.dataset,\n partition: input.partition,\n schemaRevision: input.schemaRevision,\n relativePath: input.relativePath,\n coverage: input.coverage,\n quality: input.quality,\n file: input.file,\n }).toString(\"utf8\"),\n ) as RecordPartitionCommitInput;\n validateInput(captured);\n Object.freeze(captured.partition);\n Object.freeze(captured.coverage);\n Object.freeze(captured.quality);\n Object.freeze(captured.file);\n return Object.freeze(captured);\n}\n\n/**\n * Durable partition receipt store rooted at the canonical market directory.\n * Data targets are derived from the registered identity and receipt path;\n * callers cannot redirect inspection or publication to arbitrary files.\n */\nexport class FilePartitionCommitStore implements PartitionCommitRecorder {\n readonly marketRootDir: string;\n readonly objects: ContentObjectStore;\n readonly provenanceRootDir: string;\n private readonly staleLockMs: number;\n private readonly lockWaitMs: number;\n private readonly directories = new DurableDirectories();\n\n constructor(marketRootDir: string, options: FilePartitionCommitStoreOptions = {}) {\n this.marketRootDir = marketRootDir;\n this.provenanceRootDir = path.join(marketRootDir, \".provenance\");\n this.objects = new ContentObjectStore(this.provenanceRootDir);\n this.staleLockMs = options.staleLockMs ?? 30_000;\n this.lockWaitMs = options.lockWaitMs ?? 5_000;\n }\n\n private identityDigest(identity: PartitionIdentity): string {\n return parseCanonicalJsonAddress(identityAddress(identity));\n }\n\n private headPath(identity: PartitionIdentity): string {\n const digest = this.identityDigest(identity);\n return path.join(this.provenanceRootDir, \"heads\", digest.slice(0, 2), `${digest}.json`);\n }\n\n private eventIndexDir(identity: PartitionIdentity): string {\n const digest = this.identityDigest(identity);\n return path.join(this.provenanceRootDir, \"events\", digest.slice(0, 2), digest);\n }\n\n private lockRoot(identity: PartitionIdentity): string {\n const digest = this.identityDigest(identity);\n return path.join(this.provenanceRootDir, \"locks\", digest.slice(0, 2), digest);\n }\n\n private targetPath(relativePath: string): string {\n validateRelativePath(relativePath);\n return path.join(this.marketRootDir, ...relativePath.split(\"/\"));\n }\n\n private async validateMarketRoot(): Promise<string> {\n const root = path.resolve(this.marketRootDir);\n const rootStat = await fs.lstat(root);\n if (!rootStat.isDirectory() || rootStat.isSymbolicLink()) {\n throw new PartitionFileIntegrityError(root, \"market root must be a real directory\");\n }\n return fs.realpath(root);\n }\n\n private async validatedTargetPath(\n relativePath: string,\n expectedRealRoot: string,\n ): Promise<string> {\n validateRelativePath(relativePath);\n const root = path.resolve(this.marketRootDir);\n const realRoot = await this.validateMarketRoot();\n if (realRoot !== expectedRealRoot) {\n throw new PartitionFileIntegrityError(root, \"market root changed during publication\");\n }\n const components = relativePath.split(\"/\");\n let current = root;\n for (const component of components.slice(0, -1)) {\n current = path.join(current, component);\n const stat = await fs.lstat(current);\n if (!stat.isDirectory() || stat.isSymbolicLink()) {\n throw new PartitionFileIntegrityError(\n current,\n \"target path components must be real directories\",\n );\n }\n }\n const realParent = await fs.realpath(current);\n const containment = path.relative(realRoot, realParent);\n if (\n containment === \"..\" ||\n containment.startsWith(`..${path.sep}`) ||\n path.isAbsolute(containment)\n ) {\n throw new PartitionFileIntegrityError(\n current,\n \"target parent escapes the configured market root\",\n );\n }\n return path.join(current, components.at(-1) as string);\n }\n\n private async quarantineClaim(claimedPath: string): Promise<void> {\n try {\n await fs.lstat(claimedPath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return;\n throw error;\n }\n const quarantineDir = path.join(this.provenanceRootDir, \"rejected-prepared\");\n await this.directories.ensure(quarantineDir);\n const quarantinePath = path.join(quarantineDir, randomUUID());\n await fs.rename(claimedPath, quarantinePath);\n await syncDirectory(path.dirname(claimedPath));\n await syncDirectory(quarantineDir);\n }\n\n private async restoreOrQuarantineClaim(claimedPath: string, preparedPath: string): Promise<void> {\n let restored = false;\n let claimedRemoved = false;\n try {\n // link(2) is no-replace at the destination and preserves a symlink as a\n // symlink. It safely restores regular files, hard links, and symlinks;\n // directories fall through to quarantine without recursive deletion.\n await fs.link(claimedPath, preparedPath);\n restored = true;\n await fs.unlink(claimedPath);\n claimedRemoved = true;\n await syncDirectory(path.dirname(preparedPath));\n return;\n } catch (error) {\n if (claimedRemoved) throw error;\n if (restored) await fs.unlink(preparedPath).catch(() => undefined);\n await this.quarantineClaim(claimedPath);\n }\n }\n\n private isProcessAlive(pid: number): boolean {\n if (!Number.isSafeInteger(pid) || pid <= 0) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return (error as NodeJS.ErrnoException).code === \"EPERM\";\n }\n }\n\n private async readCanonicalFile<T>(filePath: string): Promise<T | null> {\n try {\n const bytes = await fs.readFile(filePath);\n const value = JSON.parse(bytes.toString(\"utf8\")) as T;\n if (!canonicalJsonBytes(value).equals(bytes)) return null;\n return value;\n } catch {\n return null;\n }\n }\n\n private validOwner(owner: PartitionLockOwner | null, token: string): owner is PartitionLockOwner {\n return Boolean(\n owner &&\n owner.kind === \"tradeblocks.market-data.partition-lock-owner\" &&\n owner.version === 1 &&\n owner.token === token &&\n TOKEN_RE.test(owner.token) &&\n Number.isSafeInteger(owner.pid) &&\n owner.pid > 0 &&\n typeof owner.hostname === \"string\" &&\n owner.hostname.length > 0 &&\n typeof owner.bootId === \"string\" &&\n owner.bootId.length > 0 &&\n Number.isSafeInteger(owner.createdAtMs) &&\n owner.createdAtMs >= 0,\n );\n }\n\n private validTicket(\n ticket: PartitionLockTicket | null,\n token: string,\n ): ticket is PartitionLockTicket {\n return Boolean(\n ticket &&\n ticket.kind === \"tradeblocks.market-data.partition-lock-ticket\" &&\n ticket.version === 1 &&\n ticket.token === token &&\n Number.isSafeInteger(ticket.number) &&\n ticket.number >= 1,\n );\n }\n\n private ownerProvablyDead(owner: PartitionLockOwner): boolean {\n // A different host is intrinsically ambiguous; never steal it. A different\n // boot generation on this host is conclusive evidence that the process is\n // gone. Otherwise use the local PID liveness probe.\n if (owner.hostname !== CURRENT_HOSTNAME) return false;\n if (\n owner.bootId !== \"unavailable\" &&\n CURRENT_BOOT_ID !== \"unavailable\" &&\n owner.bootId !== CURRENT_BOOT_ID\n ) {\n return true;\n }\n return !this.isProcessAlive(owner.pid);\n }\n\n private async recoverClaim(claimsDir: string, token: string): Promise<boolean> {\n if (!TOKEN_RE.test(token)) return false;\n const claimPath = path.join(claimsDir, token);\n let claimStat: Awaited<ReturnType<typeof fs.stat>>;\n try {\n claimStat = await fs.stat(claimPath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return true;\n throw error;\n }\n const owner = await this.readCanonicalFile<PartitionLockOwner>(\n path.join(claimPath, \"owner.json\"),\n );\n const validOwner = this.validOwner(owner, token);\n // A malformed owner is ambiguous, even when old. Only a complete claim\n // with conclusive same-host generation/process evidence is recoverable.\n if (!validOwner) return false;\n const createdAtMs = owner.createdAtMs;\n if (Date.now() - createdAtMs < this.staleLockMs) return false;\n if (!this.ownerProvablyDead(owner)) return false;\n\n // Claim paths are unique generations and never reused. Recovery therefore\n // moves only the exact observed token path, never a constant path that a\n // replacement owner could have acquired (the usual stale-lock ABA race).\n const quarantineDir = path.join(path.dirname(claimsDir), \"quarantine\");\n await this.directories.ensure(quarantineDir);\n const quarantinePath = path.join(\n quarantineDir,\n `${token}-${claimStat.ino}-${Math.floor(claimStat.birthtimeMs)}`,\n );\n try {\n await fs.rename(claimPath, quarantinePath);\n await syncDirectory(claimsDir);\n await syncDirectory(quarantineDir);\n return true;\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\" || code === \"EEXIST\" || code === \"ENOTEMPTY\") return false;\n throw error;\n }\n }\n\n private async publishClaim(claimsDir: string, token: string): Promise<string> {\n const owner: PartitionLockOwner = {\n kind: \"tradeblocks.market-data.partition-lock-owner\",\n version: 1,\n token,\n pid: process.pid,\n hostname: CURRENT_HOSTNAME,\n bootId: CURRENT_BOOT_ID,\n createdAtMs: Date.now(),\n };\n const publishingPath = path.join(claimsDir, `.publishing-${token}`);\n const claimPath = path.join(claimsDir, token);\n await fs.mkdir(publishingPath);\n try {\n const ownerHandle = await fs.open(path.join(publishingPath, \"owner.json\"), \"wx\", 0o444);\n try {\n await ownerHandle.writeFile(canonicalJsonBytes(owner));\n await ownerHandle.sync();\n } finally {\n await ownerHandle.close();\n }\n await syncDirectory(publishingPath);\n await fs.rename(publishingPath, claimPath);\n await syncDirectory(claimsDir);\n return claimPath;\n } catch (error) {\n await fs.rm(publishingPath, { recursive: true, force: true });\n throw error;\n }\n }\n\n private async assignTicket(claimsDir: string, claimPath: string, token: string): Promise<number> {\n let maximum = 0;\n for (const entry of await fs.readdir(claimsDir, { withFileTypes: true })) {\n if (!entry.isDirectory() || !TOKEN_RE.test(entry.name)) continue;\n const ticket = await this.readCanonicalFile<PartitionLockTicket>(\n path.join(claimsDir, entry.name, \"ticket.json\"),\n );\n if (this.validTicket(ticket, entry.name)) maximum = Math.max(maximum, ticket.number);\n }\n if (!Number.isSafeInteger(maximum + 1)) throw new Error(\"Partition lock ticket overflow\");\n const ticket: PartitionLockTicket = {\n kind: \"tradeblocks.market-data.partition-lock-ticket\",\n version: 1,\n token,\n number: maximum + 1,\n };\n const handle = await fs.open(path.join(claimPath, \"ticket.json\"), \"wx\", 0o444);\n try {\n await handle.writeFile(canonicalJsonBytes(ticket));\n await handle.sync();\n } finally {\n await handle.close();\n }\n await syncDirectory(claimPath);\n return ticket.number;\n }\n\n private async releaseClaim(claimsDir: string, claimPath: string, token: string): Promise<void> {\n await partitionCommitTestFaults.get(this)?.(\"before-release-claim\");\n const owner = await this.readCanonicalFile<PartitionLockOwner>(\n path.join(claimPath, \"owner.json\"),\n );\n if (!this.validOwner(owner, token) || owner.pid !== process.pid) {\n throw new Error(\n `Refusing to release a partition claim owned by another writer: ${claimPath}`,\n );\n }\n const releasedDir = path.join(path.dirname(claimsDir), \"released\");\n await this.directories.ensure(releasedDir);\n const releasedPath = path.join(releasedDir, token);\n await fs.rename(claimPath, releasedPath);\n await syncDirectory(claimsDir);\n await syncDirectory(releasedDir);\n await fs.rm(releasedPath, { recursive: true });\n await syncDirectory(releasedDir);\n }\n\n private async withPartitionLock<T>(\n identity: PartitionIdentity,\n operation: () => Promise<T>,\n ): Promise<T> {\n validateIdentity(identity);\n const lockRoot = this.lockRoot(identity);\n const claimsDir = path.join(lockRoot, \"claims\");\n await this.directories.ensure(claimsDir);\n const token = randomUUID();\n const claimPath = await this.publishClaim(claimsDir, token);\n let ownTicket: number;\n try {\n ownTicket = await this.assignTicket(claimsDir, claimPath, token);\n } catch (error) {\n try {\n await this.releaseClaim(claimsDir, claimPath, token);\n } catch (cleanupError) {\n throw attachPartitionLockCleanupError(error, cleanupError);\n }\n throw error;\n }\n const deadline = Date.now() + this.lockWaitMs;\n let acquired = false;\n\n let operationFailed = false;\n let operationError: unknown;\n try {\n while (Date.now() <= deadline) {\n let blocked = false;\n const entries = await fs.readdir(claimsDir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory() || entry.name === token) continue;\n if (!TOKEN_RE.test(entry.name)) {\n if (!entry.name.startsWith(\".publishing-\")) blocked = true;\n continue;\n }\n const otherPath = path.join(claimsDir, entry.name);\n const owner = await this.readCanonicalFile<PartitionLockOwner>(\n path.join(otherPath, \"owner.json\"),\n );\n if (!this.validOwner(owner, entry.name)) {\n blocked = true;\n continue;\n }\n const ticket = await this.readCanonicalFile<PartitionLockTicket>(\n path.join(otherPath, \"ticket.json\"),\n );\n if (!this.validTicket(ticket, entry.name)) {\n // A missing ticket is a valid interrupted-intent state and may be\n // recovered only with a valid, provably dead owner. Malformed\n // ticket bytes are ambiguous and permanently fail closed.\n try {\n await fs.stat(path.join(otherPath, \"ticket.json\"));\n blocked = true;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n if (!(await this.recoverClaim(claimsDir, entry.name))) blocked = true;\n }\n continue;\n }\n if (ticket.number < ownTicket || (ticket.number === ownTicket && entry.name < token)) {\n if (!(await this.recoverClaim(claimsDir, entry.name))) blocked = true;\n }\n }\n if (!blocked) {\n acquired = true;\n break;\n }\n await new Promise((resolve) => setTimeout(resolve, 10));\n }\n if (!acquired) throw new Error(`Timed out acquiring partition lock: ${lockRoot}`);\n return await operation();\n } catch (error) {\n operationFailed = true;\n operationError = error;\n throw error;\n } finally {\n try {\n await this.releaseClaim(claimsDir, claimPath, token);\n } catch (cleanupError) {\n if (operationFailed) {\n throw attachPartitionLockCleanupError(operationError, cleanupError);\n }\n throw cleanupError;\n }\n }\n }\n\n private async readIndexedEvent(\n identity: PartitionIdentity,\n eventPath: string,\n address: CanonicalJsonAddress,\n ): Promise<{ event: PartitionCommitEventV1; commit: StoredPartitionCommit }> {\n const bytes = await fs.readFile(eventPath);\n if (addressBytes(bytes) !== address) {\n throw new ContentObjectCollisionError(address, eventPath);\n }\n const event = JSON.parse(bytes.toString(\"utf8\")) as PartitionCommitEventV1;\n if (!canonicalJsonBytes(event).equals(bytes)) {\n throw new ContentObjectCollisionError(address, eventPath);\n }\n if (\n event.kind !== PARTITION_COMMIT_EVENT_KIND ||\n event.version !== PARTITION_COMMIT_EVENT_VERSION ||\n event.dataset !== identity.dataset ||\n addressCanonicalJson(event.partition) !== addressCanonicalJson(identity.partition)\n ) {\n throw new Error(`Invalid partition commit event at ${eventPath}`);\n }\n parseCanonicalJsonAddress(event.receipt);\n if (event.previous !== undefined) parseCanonicalJsonAddress(event.previous);\n const commit = await this.readCommit(event.receipt);\n validateReceipt(commit.receipt, identity);\n return { event, commit };\n }\n\n private async readAuthorityTip(identity: PartitionIdentity): Promise<AuthorityTip | null> {\n const indexDir = this.eventIndexDir(identity);\n let entries: string[];\n try {\n entries = await fs.readdir(indexDir);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw error;\n }\n const events = new Map<\n CanonicalJsonAddress,\n { event: PartitionCommitEventV1; commit: StoredPartitionCommit }\n >();\n for (const entry of entries) {\n const match = /^([0-9a-f]{64})\\.json$/.exec(entry);\n if (!match) throw new Error(`Unexpected partition event index entry: ${entry}`);\n const address = `sha256:${match[1]}` as CanonicalJsonAddress;\n events.set(\n address,\n await this.readIndexedEvent(identity, path.join(indexDir, entry), address),\n );\n }\n if (events.size === 0) return null;\n\n const roots = [...events.entries()].filter(([, value]) => value.event.previous === undefined);\n if (roots.length !== 1) throw new Error(\"Partition event authority must have exactly one root\");\n let [currentAddress, current] = roots[0];\n if (current.commit.receipt.classification !== \"append\") {\n throw new Error(\"Partition event root must reference an append receipt\");\n }\n const visited = new Set<CanonicalJsonAddress>();\n while (true) {\n if (visited.has(currentAddress))\n throw new Error(\"Partition event authority contains a cycle\");\n visited.add(currentAddress);\n const children = [...events.entries()].filter(\n ([, value]) => value.event.previous === currentAddress,\n );\n if (children.length === 0) break;\n if (children.length !== 1)\n throw new Error(\"Partition event authority contains ambiguous tips\");\n const [childAddress, child] = children[0];\n if (\n child.commit.receipt.classification !== \"repair\" ||\n child.commit.receipt.parent !== current.commit.address\n ) {\n throw new Error(\"Partition event authority receipt ancestry is inconsistent\");\n }\n currentAddress = childAddress;\n current = child;\n }\n if (visited.size !== events.size) {\n throw new Error(\"Partition event authority contains a disconnected or missing-parent event\");\n }\n return { eventAddress: currentAddress, commit: current.commit };\n }\n\n private async readProjectedHead(identity: PartitionIdentity): Promise<PartitionHeadV1 | null> {\n const headPath = this.headPath(identity);\n let bytes: Buffer;\n try {\n bytes = await fs.readFile(headPath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw error;\n }\n\n try {\n const head = JSON.parse(bytes.toString(\"utf8\")) as PartitionHeadV1;\n if (!canonicalJsonBytes(head).equals(bytes)) return null;\n if (\n head.kind !== PARTITION_HEAD_KIND ||\n head.version !== PARTITION_HEAD_VERSION ||\n head.dataset !== identity.dataset ||\n addressCanonicalJson(head.partition) !== addressCanonicalJson(identity.partition)\n ) {\n return null;\n }\n parseCanonicalJsonAddress(head.receipt);\n parseCanonicalJsonAddress(head.event);\n return head;\n } catch {\n return null;\n }\n }\n\n private async writeHead(identity: PartitionIdentity, tip: AuthorityTip): Promise<void> {\n const headPath = this.headPath(identity);\n await this.directories.ensure(path.dirname(headPath));\n const tempPath = `${headPath}.tmp-${randomUUID()}`;\n const head: PartitionHeadV1 = {\n kind: PARTITION_HEAD_KIND,\n version: PARTITION_HEAD_VERSION,\n dataset: identity.dataset,\n partition: identity.partition,\n receipt: tip.commit.address,\n event: tip.eventAddress,\n };\n let handle: fs.FileHandle | undefined;\n try {\n handle = await fs.open(tempPath, \"wx\", 0o644);\n await handle.writeFile(canonicalJsonBytes(head));\n await handle.sync();\n await handle.close();\n handle = undefined;\n await fs.rename(tempPath, headPath);\n await syncDirectory(path.dirname(headPath));\n } catch (error) {\n await handle?.close();\n await fs.unlink(tempPath).catch(() => undefined);\n throw error;\n }\n }\n\n private async authorityWithRebuiltHead(\n identity: PartitionIdentity,\n ): Promise<AuthorityTip | null> {\n const tip = await this.readAuthorityTip(identity);\n const head = await this.readProjectedHead(identity);\n if (!tip) {\n if (head) throw new Error(\"Partition head exists without immutable event authority\");\n return null;\n }\n if (head?.receipt !== tip.commit.address || head.event !== tip.eventAddress) {\n await this.writeHead(identity, tip);\n }\n return tip;\n }\n\n private async appendEvent(\n identity: PartitionIdentity,\n receipt: CanonicalJsonAddress,\n previous?: CanonicalJsonAddress,\n ): Promise<CanonicalJsonAddress> {\n const event: PartitionCommitEventV1 = {\n kind: PARTITION_COMMIT_EVENT_KIND,\n version: PARTITION_COMMIT_EVENT_VERSION,\n dataset: identity.dataset,\n partition: identity.partition,\n receipt,\n ...(previous ? { previous } : {}),\n };\n const stored = await this.objects.put(event);\n const indexDir = this.eventIndexDir(identity);\n await this.directories.ensure(indexDir);\n const digest = parseCanonicalJsonAddress(stored.address);\n const eventPath = path.join(indexDir, `${digest}.json`);\n try {\n await fs.link(stored.path, eventPath);\n await syncDirectory(indexDir);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n const existing = await fs.readFile(eventPath);\n if (\n addressBytes(existing) !== stored.address ||\n !existing.equals(canonicalJsonBytes(event))\n ) {\n throw new ContentObjectCollisionError(stored.address, eventPath);\n }\n const handle = await fs.open(eventPath, \"r\");\n try {\n await handle.sync();\n } finally {\n await handle.close();\n }\n await syncDirectory(indexDir);\n }\n return stored.address;\n }\n\n async readCommit(address: CanonicalJsonAddress): Promise<StoredPartitionCommit> {\n parseCanonicalJsonAddress(address);\n const receipt = await this.objects.get<PartitionCommitReceiptV1>(address);\n validateReceipt(receipt, receipt);\n return Object.freeze({ address, receipt, created: false });\n }\n\n /**\n * Adopt an existing canonical Parquet partition after producer-owned schema,\n * identity, coverage, row-count, and exact-byte inspection.\n */\n async [INTERNAL_HISTORICAL_PARTITION_ADOPTION](\n conn: DuckDBConnection,\n identity: PartitionIdentity,\n ): Promise<StoredPartitionCommit> {\n const captured = captureIdentity(identity);\n const definition = canonicalPartitionDataset(captured.dataset) as NonNullable<\n ReturnType<typeof canonicalPartitionDataset>\n >;\n const relativePath = canonicalRelativePath(captured);\n const targetPath = path.resolve(this.targetPath(relativePath));\n return this.withPartitionLock(captured, async () => {\n const realMarketRoot = await this.validateMarketRoot();\n const validatedTargetPath = await this.validatedTargetPath(relativePath, realMarketRoot);\n if (validatedTargetPath !== targetPath) {\n throw new PartitionFileIntegrityError(\n validatedTargetPath,\n \"validated target differs from the registered path\",\n );\n }\n const opened = await openRegularFileNoFollow(targetPath);\n const snapshotRoot = path.join(this.provenanceRootDir, \"inspection-snapshots\");\n await this.directories.ensure(snapshotRoot);\n const snapshotDir = await fs.mkdtemp(path.join(snapshotRoot, \"adopt-\"));\n const snapshotPath = path.join(snapshotDir, \"partition.parquet\");\n try {\n const snapshotFingerprint = await snapshotOpenFile(opened.handle, snapshotPath);\n const snapshotObserved = await exactFileAddress(snapshotPath);\n if (\n snapshotObserved.address !== snapshotFingerprint.address ||\n snapshotObserved.bytes !== snapshotFingerprint.bytes\n ) {\n throw new PartitionFileIntegrityError(\n snapshotPath,\n \"inspection snapshot bytes disagree with the pinned canonical inode\",\n );\n }\n await partitionCommitTestFaults.get(this)?.(\"historical-after-snapshot\");\n const inspected = await inspectCanonicalParquet(conn, snapshotPath, captured);\n const snapshotAfter = await exactFileAddress(snapshotPath);\n if (\n snapshotAfter.address !== snapshotFingerprint.address ||\n snapshotAfter.bytes !== snapshotFingerprint.bytes\n ) {\n throw new PartitionFileIntegrityError(\n snapshotPath,\n \"inspection snapshot changed during semantic inspection\",\n );\n }\n const canonicalAfter = await exactOpenFileAddress(opened.handle);\n const afterStat = await opened.handle.stat();\n if (\n !afterStat.isFile() ||\n afterStat.nlink !== 1 ||\n !sameInode(opened.stat, afterStat) ||\n canonicalAfter.address !== snapshotFingerprint.address ||\n canonicalAfter.bytes !== snapshotFingerprint.bytes\n ) {\n throw new PartitionFileIntegrityError(\n targetPath,\n \"canonical inode changed during historical semantic inspection\",\n );\n }\n await requireNamedRegularInode(targetPath, opened.stat);\n return this.adoptExistingFileCommit(\n {\n dataset: captured.dataset,\n partition: captured.partition,\n schemaRevision: definition.schemaRevision,\n relativePath,\n coverage: inspected.coverage,\n quality: { inputRows: inspected.rows, writtenRows: inspected.rows, droppedRows: 0 },\n file: { ...snapshotFingerprint, rows: inspected.rows },\n },\n true,\n );\n } finally {\n await opened.handle.close();\n await fs.rm(snapshotDir, { recursive: true });\n }\n });\n }\n\n /**\n * Establish immutable authority for a canonical file that predates receipt\n * publication. This never replaces the data file: it pins and hashes the\n * existing regular inode under the partition lock, then appends authority\n * only when the caller-supplied rows/coverage/fingerprint agree exactly.\n */\n private async adoptExistingFileCommit(\n input: RecordPartitionCommitInput,\n lockHeld = false,\n ): Promise<StoredPartitionCommit> {\n const captured = captureInput(input);\n const targetPath = path.resolve(this.targetPath(captured.relativePath));\n const realMarketRoot = await this.validateMarketRoot();\n const adopt = async () => {\n const validatedTargetPath = await this.validatedTargetPath(\n captured.relativePath,\n realMarketRoot,\n );\n if (validatedTargetPath !== targetPath) {\n throw new PartitionFileIntegrityError(\n validatedTargetPath,\n \"validated target differs from the registered path\",\n );\n }\n const opened = await openRegularFileNoFollow(targetPath);\n const handle = opened.handle;\n const pinnedStat = opened.stat;\n try {\n if (\n (await this.validatedTargetPath(captured.relativePath, realMarketRoot)) !== targetPath\n ) {\n throw new PartitionFileIntegrityError(\n targetPath,\n \"target parent changed before existing-file adoption\",\n );\n }\n const observed = await exactOpenFileAddress(handle);\n const afterHash = await handle.stat();\n if (!afterHash.isFile() || afterHash.nlink !== 1 || !sameInode(pinnedStat, afterHash)) {\n throw new PartitionFileIntegrityError(targetPath, \"existing inode changed while hashing\");\n }\n await requireNamedRegularInode(targetPath, pinnedStat);\n if (observed.address !== captured.file.address || observed.bytes !== captured.file.bytes) {\n throw new Error(\"Existing partition bytes do not match the supplied fingerprint\");\n }\n const previous = await this.authorityWithRebuiltHead(captured);\n if (previous && sameCommitContent(previous.commit.receipt, captured)) {\n return previous.commit;\n }\n const receipt: PartitionCommitReceiptV1 = {\n kind: PARTITION_COMMIT_RECEIPT_KIND,\n version: PARTITION_COMMIT_RECEIPT_VERSION,\n schemaRevision: captured.schemaRevision,\n dataset: captured.dataset,\n partition: captured.partition,\n relativePath: captured.relativePath,\n coverage: captured.coverage,\n quality: captured.quality,\n file: captured.file,\n classification: previous ? \"repair\" : \"append\",\n ...(previous ? { parent: previous.commit.address } : {}),\n };\n const published = await this.objects.put(receipt);\n const stored = Object.freeze({\n address: published.address,\n receipt: published.value,\n created: published.created,\n });\n // Establish the linearization point immediately before making the\n // receipt discoverable. Out-of-band mutation after this point is an\n // ordinary repair/mismatch that inspectPartition will refuse.\n if (\n (await this.validatedTargetPath(captured.relativePath, realMarketRoot)) !== targetPath\n ) {\n throw new PartitionFileIntegrityError(\n targetPath,\n \"target parent changed before authority publication\",\n );\n }\n await requireNamedRegularInode(targetPath, pinnedStat);\n const beforeEvent = await exactOpenFileAddress(handle);\n if (\n beforeEvent.address !== stored.receipt.file.address ||\n beforeEvent.bytes !== stored.receipt.file.bytes\n ) {\n throw new Error(\"Existing partition changed before authority publication\");\n }\n const eventAddress = await this.appendEvent(\n captured,\n stored.address,\n previous?.eventAddress,\n );\n await this.writeHead(captured, { eventAddress, commit: stored });\n if (\n (await this.validatedTargetPath(captured.relativePath, realMarketRoot)) !== targetPath\n ) {\n throw new PartitionFileIntegrityError(\n targetPath,\n \"target parent changed during authority publication\",\n );\n }\n await requireNamedRegularInode(targetPath, pinnedStat);\n const finalObserved = await exactOpenFileAddress(handle);\n const afterFinalHash = await handle.stat();\n if (\n !afterFinalHash.isFile() ||\n afterFinalHash.nlink !== 1 ||\n !sameInode(pinnedStat, afterFinalHash)\n ) {\n throw new PartitionFileIntegrityError(\n targetPath,\n \"existing inode changed during final verification\",\n );\n }\n await requireNamedRegularInode(targetPath, pinnedStat);\n if (\n finalObserved.address !== stored.receipt.file.address ||\n finalObserved.bytes !== stored.receipt.file.bytes\n ) {\n throw new Error(\"Existing partition changed during authority publication\");\n }\n return stored;\n } finally {\n await handle.close();\n }\n };\n return lockHeld ? adopt() : this.withPartitionLock(captured, adopt);\n }\n\n async publishFileCommit(input: PublishPartitionFileInput): Promise<StoredPartitionCommit> {\n // Snapshot every semantic field before the first await. Callers may retain\n // and mutate their input object; those mutations cannot change the lock,\n // target, receipt, event, or comparison after publication begins.\n const captured = captureInput(input);\n const preparedPath = path.resolve(String(input.preparedPath));\n const expectedTargetPath = path.resolve(String(input.expectedTargetPath));\n const targetPath = path.resolve(this.targetPath(captured.relativePath));\n if (expectedTargetPath !== targetPath) {\n throw new TypeError(\n `Provenance target does not match the store-owned market path: ${JSON.stringify({ expected: targetPath, observed: expectedTargetPath })}`,\n );\n }\n if (preparedPath === targetPath || path.dirname(preparedPath) !== path.dirname(targetPath)) {\n throw new TypeError(\"Prepared partition file must be a distinct sibling of its target\");\n }\n // Reject an aliased or invalid configured root before lock acquisition can\n // create any authority directories through it.\n const realMarketRoot = await this.validateMarketRoot();\n return this.withPartitionLock(captured, async () => {\n const validatedTargetPath = await this.validatedTargetPath(\n captured.relativePath,\n realMarketRoot,\n );\n if (validatedTargetPath !== targetPath) {\n throw new PartitionFileIntegrityError(\n validatedTargetPath,\n \"validated target differs from the registered path\",\n );\n }\n const targetDirectory = path.dirname(targetPath);\n const claimedPath = path.join(targetDirectory, `.provenance-claim-${randomUUID()}`);\n let claimed = false;\n let targetTouched = false;\n let claimedHandle: fs.FileHandle | undefined;\n let claimedStat: Awaited<ReturnType<fs.FileHandle[\"stat\"]>> | undefined;\n try {\n // Move the caller-controlled directory entry out of its known name\n // before following or reading anything. The random sibling is then\n // opened no-follow and pinned by file descriptor through install.\n await fs.rename(preparedPath, claimedPath);\n claimed = true;\n await syncDirectory(targetDirectory);\n const opened = await openRegularFileNoFollow(claimedPath);\n claimedHandle = opened.handle;\n claimedStat = opened.stat;\n await partitionCommitTestFaults.get(this)?.(\"after-claim-open\");\n const prepared = await exactOpenFileAddress(claimedHandle);\n const afterPreparedHash = await claimedHandle.stat();\n if (\n !afterPreparedHash.isFile() ||\n afterPreparedHash.nlink !== 1 ||\n !sameInode(claimedStat, afterPreparedHash)\n ) {\n throw new PartitionFileIntegrityError(claimedPath, \"claimed inode changed while hashing\");\n }\n await requireNamedRegularInode(claimedPath, claimedStat);\n if (prepared.address !== captured.file.address || prepared.bytes !== captured.file.bytes) {\n throw new Error(\"Prepared partition bytes do not match the supplied fingerprint\");\n }\n await claimedHandle.sync();\n await syncDirectory(targetDirectory);\n\n const previous = await this.authorityWithRebuiltHead(captured);\n let stored: StoredPartitionCommit;\n let pendingEvent:\n { receipt: StoredPartitionCommit; previousEvent?: CanonicalJsonAddress } | undefined;\n if (previous && sameCommitContent(previous.commit.receipt, captured)) {\n stored = previous.commit;\n } else {\n const receipt: PartitionCommitReceiptV1 = {\n kind: PARTITION_COMMIT_RECEIPT_KIND,\n version: PARTITION_COMMIT_RECEIPT_VERSION,\n schemaRevision: captured.schemaRevision,\n dataset: captured.dataset,\n partition: captured.partition,\n relativePath: captured.relativePath,\n coverage: captured.coverage,\n quality: captured.quality,\n file: captured.file,\n classification: previous ? \"repair\" : \"append\",\n ...(previous ? { parent: previous.commit.address } : {}),\n };\n // Receipt bytes are immutable and durable before the data file is\n // installed. They are not authoritative/discoverable until the\n // event index is appended after the rename.\n const publishedReceipt = await this.objects.put(receipt);\n stored = {\n address: publishedReceipt.address,\n receipt: publishedReceipt.value,\n created: publishedReceipt.created,\n };\n Object.freeze(stored);\n pendingEvent = { receipt: stored, previousEvent: previous?.eventAddress };\n }\n\n // Revalidate the directory chain and the claimed name immediately\n // before rename. Node has no renameat(2), so the post-rename inode\n // comparison below is the final fail-closed path-swap check.\n if (\n (await this.validatedTargetPath(captured.relativePath, realMarketRoot)) !== targetPath\n ) {\n throw new PartitionFileIntegrityError(targetPath, \"target parent changed before install\");\n }\n const beforeInstall = await claimedHandle.stat();\n if (\n !beforeInstall.isFile() ||\n beforeInstall.nlink !== 1 ||\n !sameInode(claimedStat, beforeInstall)\n ) {\n throw new PartitionFileIntegrityError(\n claimedPath,\n \"claimed inode changed before install\",\n );\n }\n await requireNamedRegularInode(claimedPath, claimedStat);\n await fs.rename(claimedPath, targetPath);\n claimed = false;\n targetTouched = true;\n await syncDirectory(targetDirectory);\n await requireNamedRegularInode(targetPath, claimedStat);\n const afterInstall = await claimedHandle.stat();\n if (\n !afterInstall.isFile() ||\n afterInstall.nlink !== 1 ||\n !sameInode(claimedStat, afterInstall)\n ) {\n throw new PartitionFileIntegrityError(targetPath, \"installed inode changed\");\n }\n const observed = await exactOpenFileAddress(claimedHandle);\n const afterInstalledHash = await claimedHandle.stat();\n if (\n !afterInstalledHash.isFile() ||\n afterInstalledHash.nlink !== 1 ||\n !sameInode(claimedStat, afterInstalledHash)\n ) {\n throw new PartitionFileIntegrityError(\n targetPath,\n \"installed inode changed while hashing\",\n );\n }\n await requireNamedRegularInode(targetPath, claimedStat);\n await claimedHandle.sync();\n if (\n observed.address !== stored.receipt.file.address ||\n observed.bytes !== stored.receipt.file.bytes\n ) {\n throw new Error(\"Installed partition bytes disagree with immutable commit authority\");\n }\n\n if (pendingEvent) {\n const eventAddress = await this.appendEvent(\n captured,\n pendingEvent.receipt.address,\n pendingEvent.previousEvent,\n );\n await partitionCommitTestFaults.get(this)?.(\"after-event-before-head\");\n await this.writeHead(captured, { eventAddress, commit: pendingEvent.receipt });\n }\n const tip = await this.authorityWithRebuiltHead(captured);\n if (!tip || tip.commit.address !== stored.address) {\n throw new Error(\"Installed partition and authoritative head disagree\");\n }\n if (\n (await this.validatedTargetPath(captured.relativePath, realMarketRoot)) !== targetPath\n ) {\n throw new PartitionFileIntegrityError(\n targetPath,\n \"target parent changed before publication completed\",\n );\n }\n const beforeReturn = await claimedHandle.stat();\n if (\n !beforeReturn.isFile() ||\n beforeReturn.nlink !== 1 ||\n !sameInode(claimedStat, beforeReturn)\n ) {\n throw new PartitionFileIntegrityError(\n targetPath,\n \"installed inode changed before publication completed\",\n );\n }\n await requireNamedRegularInode(targetPath, claimedStat);\n const finalObserved = await exactOpenFileAddress(claimedHandle);\n const afterFinalHash = await claimedHandle.stat();\n if (\n !afterFinalHash.isFile() ||\n afterFinalHash.nlink !== 1 ||\n !sameInode(claimedStat, afterFinalHash)\n ) {\n throw new PartitionFileIntegrityError(\n targetPath,\n \"installed inode changed during final verification\",\n );\n }\n await requireNamedRegularInode(targetPath, claimedStat);\n if (\n finalObserved.address !== stored.receipt.file.address ||\n finalObserved.bytes !== stored.receipt.file.bytes\n ) {\n throw new Error(\"Installed partition changed before publication completed\");\n }\n return stored;\n } catch (error) {\n if (targetTouched) {\n throw new PartitionFilePublicationError(targetPath, captured.file, error);\n }\n throw error;\n } finally {\n await claimedHandle?.close();\n if (claimed) await this.restoreOrQuarantineClaim(claimedPath, preparedPath);\n }\n });\n }\n\n async inspectPartition(identity: PartitionIdentity): Promise<PartitionInspection> {\n const captured = captureIdentity(identity);\n const realMarketRoot = await this.validateMarketRoot();\n return this.withPartitionLock(captured, async () => {\n const tip = await this.authorityWithRebuiltHead(captured);\n const relativePath = tip?.commit.receipt.relativePath ?? canonicalRelativePath(captured);\n validateRegistryPath(captured, relativePath);\n let observed: Omit<ExactFileFingerprint, \"rows\">;\n try {\n const targetPath = await this.validatedTargetPath(relativePath, realMarketRoot);\n observed = await exactFileAddress(targetPath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return tip ? { status: \"missing\", receipt: tip.commit } : { status: \"absent\" };\n }\n throw error;\n }\n if (!tip) return { status: \"orphan\", observed };\n if (\n tip.commit.receipt.file.address !== observed.address ||\n tip.commit.receipt.file.bytes !== observed.bytes\n ) {\n return { status: \"mismatch\", receipt: tip.commit, observed };\n }\n return { status: \"match\", receipt: tip.commit };\n });\n }\n}\n\n/** @internal Producer-only capability marker; intentionally omitted from the public barrel. */\nexport async function publishRefreshCompletionAuthority(\n store: FilePartitionCommitStore,\n completion: CanonicalJsonAddress,\n): Promise<void> {\n const digest = parseCanonicalJsonAddress(completion);\n const source = store.objects.objectPath(completion);\n const directory = path.join(store.provenanceRootDir, \"refresh-completions\", digest.slice(0, 2));\n const marker = path.join(directory, `${digest}.json`);\n await fs.mkdir(directory, { recursive: true });\n try {\n await fs.link(source, marker);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n }\n const bytes = await fs.readFile(marker);\n if (addressBytes(bytes) !== completion) {\n throw new ContentObjectCollisionError(completion, marker);\n }\n const handle = await fs.open(marker, \"r\");\n try {\n await handle.sync();\n } finally {\n await handle.close();\n }\n const directoryHandle = await fs.open(directory, \"r\");\n try {\n await directoryHandle.sync();\n } finally {\n await directoryHandle.close();\n }\n}\n\n/** @internal Verifies publication through the producer-only completion rail. */\nexport async function verifyRefreshCompletionAuthority(\n store: FilePartitionCommitStore,\n completion: CanonicalJsonAddress,\n): Promise<void> {\n const digest = parseCanonicalJsonAddress(completion);\n const marker = path.join(\n store.provenanceRootDir,\n \"refresh-completions\",\n digest.slice(0, 2),\n `${digest}.json`,\n );\n const stat = await fs.lstat(marker);\n if (!stat.isFile() || stat.isSymbolicLink()) {\n throw new Error(\"Canonical refresh completion has no producer authority marker\");\n }\n const bytes = await fs.readFile(marker);\n const object = await fs.readFile(store.objects.objectPath(completion));\n if (addressBytes(bytes) !== completion || !bytes.equals(object)) {\n throw new Error(\"Canonical refresh completion authority marker is corrupt\");\n }\n}\n\nexport class PartitionFilePublicationError extends Error {\n readonly targetPath: string;\n readonly file: ExactFileFingerprint;\n\n constructor(targetPath: string, file: ExactFileFingerprint, cause: unknown) {\n super(`Partition file installed without a complete projected commit: ${targetPath}`, { cause });\n this.name = \"PartitionFilePublicationError\";\n this.targetPath = targetPath;\n this.file = file;\n }\n}\n","import * as path from \"node:path\";\n\nexport interface DatasetPartitionIdentity {\n dataset: string;\n partition: Record<string, string>;\n}\n\nexport type DatasetProvenancePosture =\n { kind: \"bounded-session\"; sessionKey: string } | { kind: \"unbounded-unsupported\" };\n\nexport interface MarketDatasetDefinition {\n subdir: string;\n partitionKeys: readonly string[];\n filename: string;\n schemaRevision: number;\n provenance: DatasetProvenancePosture;\n}\n\nexport interface BoundedMarketDatasetDefinition extends MarketDatasetDefinition {\n provenance: { kind: \"bounded-session\"; sessionKey: string };\n}\n\nconst ISO_DATE_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n/**\n * One canonical registry for every market dataset writer and provenance path.\n * Unbounded legacy files remain writable outside attempts but cannot mint\n * partition receipts or cutoff manifests until bounded slices replace them.\n */\nfunction deepFreezeDatasetRegistry<T extends Record<string, MarketDatasetDefinition>>(\n registry: T,\n): T {\n for (const definition of Object.values(registry)) {\n Object.freeze(definition.partitionKeys);\n Object.freeze(definition.provenance);\n Object.freeze(definition);\n }\n return Object.freeze(registry);\n}\n\nexport const MARKET_DATASETS = deepFreezeDatasetRegistry({\n spot: {\n subdir: \"spot\",\n partitionKeys: [\"ticker\", \"date\"],\n filename: \"data.parquet\",\n schemaRevision: 1,\n provenance: { kind: \"bounded-session\", sessionKey: \"date\" },\n },\n enriched: {\n subdir: \"enriched\",\n partitionKeys: [\"ticker\", \"date\"],\n filename: \"data.parquet\",\n schemaRevision: 1,\n provenance: { kind: \"bounded-session\", sessionKey: \"date\" },\n },\n enriched_context: {\n subdir: \"enriched/context\",\n partitionKeys: [\"date\"],\n filename: \"data.parquet\",\n schemaRevision: 1,\n provenance: { kind: \"bounded-session\", sessionKey: \"date\" },\n },\n option_chain: {\n subdir: \"option_chain\",\n partitionKeys: [\"underlying\", \"date\"],\n filename: \"data.parquet\",\n schemaRevision: 1,\n provenance: { kind: \"bounded-session\", sessionKey: \"date\" },\n },\n option_quote_minutes: {\n subdir: \"option_quote_minutes\",\n partitionKeys: [\"underlying\", \"date\"],\n filename: \"data.parquet\",\n schemaRevision: 1,\n provenance: { kind: \"bounded-session\", sessionKey: \"date\" },\n },\n option_oi_daily: {\n subdir: \"option_oi_daily\",\n partitionKeys: [\"underlying\", \"date\"],\n filename: \"data.parquet\",\n schemaRevision: 1,\n provenance: { kind: \"bounded-session\", sessionKey: \"date\" },\n },\n} satisfies Record<string, MarketDatasetDefinition>);\n\nexport type MarketDatasetName = keyof typeof MARKET_DATASETS;\n\nexport function isRealMarketSessionDate(value: string): boolean {\n if (!ISO_DATE_RE.test(value)) return false;\n const parsed = new Date(`${value}T00:00:00.000Z`);\n return Number.isFinite(parsed.getTime()) && parsed.toISOString().slice(0, 10) === value;\n}\n\nexport function marketDatasetDefinition(dataset: string): MarketDatasetDefinition | undefined {\n return Object.hasOwn(MARKET_DATASETS, dataset)\n ? MARKET_DATASETS[dataset as MarketDatasetName]\n : undefined;\n}\n\nexport function canonicalPartitionDataset(\n dataset: string,\n): BoundedMarketDatasetDefinition | undefined {\n const definition = marketDatasetDefinition(dataset);\n return definition?.provenance.kind === \"bounded-session\"\n ? (definition as BoundedMarketDatasetDefinition)\n : undefined;\n}\n\nexport function validatePartitionIdentity(identity: DatasetPartitionIdentity): void {\n const definition = canonicalPartitionDataset(identity.dataset);\n if (!definition) {\n throw new TypeError(`Unregistered provenance dataset: ${JSON.stringify(identity.dataset)}`);\n }\n const expectedKeys = [...definition.partitionKeys].sort();\n const observedKeys = Object.keys(identity.partition).sort();\n if (\n observedKeys.length !== expectedKeys.length ||\n observedKeys.some((key, index) => key !== expectedKeys[index])\n ) {\n throw new TypeError(\n `Invalid provenance partition keys: ${JSON.stringify({ dataset: identity.dataset, observedKeys, expectedKeys })}`,\n );\n }\n for (const [key, value] of Object.entries(identity.partition)) {\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key) || !/^[A-Za-z0-9._-]+$/.test(value)) {\n throw new TypeError(`Invalid provenance partition: ${JSON.stringify({ key, value })}`);\n }\n }\n const session = identity.partition[definition.provenance.sessionKey];\n if (!isRealMarketSessionDate(session)) {\n throw new TypeError(`Invalid provenance partition date: ${JSON.stringify(session)}`);\n }\n}\n\nexport function canonicalPartitionRelativePath(identity: DatasetPartitionIdentity): string {\n validatePartitionIdentity(identity);\n const definition = canonicalPartitionDataset(identity.dataset) as BoundedMarketDatasetDefinition;\n return path.posix.join(\n definition.subdir,\n ...definition.partitionKeys.map((key) => `${key}=${identity.partition[key]}`),\n definition.filename,\n );\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { PartitionCommitRecorder, StoredPartitionCommit } from \"./partition-commit-store.ts\";\nimport type { CanonicalJsonAddress } from \"./canonical-json.ts\";\n\nexport interface PartitionCommitAttemptOptions {\n /** Caller-owned correlation identifier; not part of receipt content identity. */\n attemptId: string;\n recorder: PartitionCommitRecorder;\n}\n\nexport interface PartitionCommitAttemptResult<T> {\n attemptId: string;\n value: T;\n receipts: readonly StoredPartitionCommit[];\n}\n\ninterface ActivePartitionCommitAttempt extends PartitionCommitAttemptOptions {\n receiptAddresses: CanonicalJsonAddress[];\n}\n\nconst attempts = new AsyncLocalStorage<ActivePartitionCommitAttempt>();\n\nfunction compareCodePoints(left: string, right: string): number {\n const leftPoints = Array.from(left, (character) => character.codePointAt(0) as number);\n const rightPoints = Array.from(right, (character) => character.codePointAt(0) as number);\n const length = Math.min(leftPoints.length, rightPoints.length);\n for (let index = 0; index < length; index++) {\n if (leftPoints[index] !== rightPoints[index]) return leftPoints[index] - rightPoints[index];\n }\n return leftPoints.length - rightPoints.length;\n}\n\nfunction commitTuple(commit: StoredPartitionCommit): string[] {\n const partition = Object.entries(commit.receipt.partition)\n .sort(([left], [right]) => compareCodePoints(left, right))\n .flatMap(([key, value]) => [key, value]);\n return [commit.receipt.dataset, ...partition, commit.address];\n}\n\nfunction compareTuple(left: string[], right: string[]): number {\n const length = Math.min(left.length, right.length);\n for (let index = 0; index < length; index++) {\n const compared = compareCodePoints(left[index], right[index]);\n if (compared !== 0) return compared;\n }\n return left.length - right.length;\n}\n\n/**\n * Run an ingest/write operation with exact-byte partition receipt capture.\n *\n * Store APIs remain unchanged: canonical dataset writers discover this async\n * scope, persist receipts through its recorder, and append successful commits\n * to the returned list. Outside a scope, those writers retain legacy behavior\n * and skip the hashing/receipt work entirely.\n */\nexport async function runPartitionCommitAttempt<T>(\n options: PartitionCommitAttemptOptions,\n operation: () => Promise<T>,\n): Promise<PartitionCommitAttemptResult<T>> {\n if (options.attemptId.trim().length === 0) {\n throw new TypeError(\"Partition commit attemptId must not be empty\");\n }\n const active: ActivePartitionCommitAttempt = { ...options, receiptAddresses: [] };\n const value = await attempts.run(active, operation);\n const receipts = await Promise.all(\n [...new Set(active.receiptAddresses)].map((address) => active.recorder.readCommit(address)),\n );\n receipts.sort((left, right) => compareTuple(commitTuple(left), commitTuple(right)));\n return {\n attemptId: active.attemptId,\n value,\n receipts: Object.freeze(receipts),\n };\n}\n\n/** @internal Package-internal canonical writer hook; omitted from the public barrel. */\nexport function activePartitionCommitAttempt():\n Pick<ActivePartitionCommitAttempt, \"attemptId\" | \"recorder\"> | undefined {\n return attempts.getStore();\n}\n\n/** @internal Package-internal hook; captures only successfully projected commits. */\nexport function capturePartitionCommitReceipt(receipt: StoredPartitionCommit): void {\n const active = attempts.getStore();\n if (!active) return;\n active.receiptAddresses.push(receipt.address);\n}\n","// Generated by tools/generate-replay-calendar.mjs from the bounded lib XNYS calendar.\nexport const XNYS_SESSION_CALENDAR_REVISION = \"xnys-full-day-2022-2030-v1\" as const;\nexport const XNYS_SESSION_CALENDAR_SUPPORTED_FROM = \"2022-01-01\" as const;\nexport const XNYS_SESSION_CALENDAR_SUPPORTED_THROUGH = \"2030-12-31\" as const;\nexport const CLOSED_DATES: ReadonlySet<string> = new Set([\n \"2022-01-17\",\n \"2022-02-21\",\n \"2022-04-15\",\n \"2022-05-30\",\n \"2022-06-20\",\n \"2022-07-04\",\n \"2022-09-05\",\n \"2022-11-24\",\n \"2022-12-26\",\n \"2023-01-02\",\n \"2023-01-16\",\n \"2023-02-20\",\n \"2023-04-07\",\n \"2023-05-29\",\n \"2023-06-19\",\n \"2023-07-04\",\n \"2023-09-04\",\n \"2023-11-23\",\n \"2023-12-25\",\n \"2024-01-01\",\n \"2024-01-15\",\n \"2024-02-19\",\n \"2024-03-29\",\n \"2024-05-27\",\n \"2024-06-19\",\n \"2024-07-04\",\n \"2024-09-02\",\n \"2024-11-28\",\n \"2024-12-25\",\n \"2025-01-01\",\n \"2025-01-09\",\n \"2025-01-20\",\n \"2025-02-17\",\n \"2025-04-18\",\n \"2025-05-26\",\n \"2025-06-19\",\n \"2025-07-04\",\n \"2025-09-01\",\n \"2025-11-27\",\n \"2025-12-25\",\n \"2026-01-01\",\n \"2026-01-19\",\n \"2026-02-16\",\n \"2026-04-03\",\n \"2026-05-25\",\n \"2026-06-19\",\n \"2026-07-03\",\n \"2026-09-07\",\n \"2026-11-26\",\n \"2026-12-25\",\n \"2027-01-01\",\n \"2027-01-18\",\n \"2027-02-15\",\n \"2027-03-26\",\n \"2027-05-31\",\n \"2027-06-18\",\n \"2027-07-05\",\n \"2027-09-06\",\n \"2027-11-25\",\n \"2027-12-24\",\n \"2028-01-17\",\n \"2028-02-21\",\n \"2028-04-14\",\n \"2028-05-29\",\n \"2028-06-19\",\n \"2028-07-04\",\n \"2028-09-04\",\n \"2028-11-23\",\n \"2028-12-25\",\n \"2029-01-01\",\n \"2029-01-15\",\n \"2029-02-19\",\n \"2029-03-30\",\n \"2029-05-28\",\n \"2029-06-19\",\n \"2029-07-04\",\n \"2029-09-03\",\n \"2029-11-22\",\n \"2029-12-25\",\n \"2030-01-01\",\n \"2030-01-21\",\n \"2030-02-18\",\n \"2030-04-19\",\n \"2030-05-27\",\n \"2030-06-19\",\n \"2030-07-04\",\n \"2030-09-02\",\n \"2030-11-28\",\n \"2030-12-25\",\n]);\nexport const EARLY_CLOSE_DATES: ReadonlySet<string> = new Set([\n \"2022-11-25\",\n \"2023-07-03\",\n \"2023-11-24\",\n \"2024-07-03\",\n \"2024-11-29\",\n \"2024-12-24\",\n \"2025-07-03\",\n \"2025-11-28\",\n \"2025-12-24\",\n \"2026-11-27\",\n \"2026-12-24\",\n \"2027-11-26\",\n \"2028-07-03\",\n \"2028-11-24\",\n \"2029-07-03\",\n \"2029-11-23\",\n \"2029-12-24\",\n \"2030-07-03\",\n \"2030-11-29\",\n \"2030-12-24\",\n]);\n","import {\n CLOSED_DATES,\n EARLY_CLOSE_DATES,\n XNYS_SESSION_CALENDAR_REVISION,\n XNYS_SESSION_CALENDAR_SUPPORTED_FROM,\n XNYS_SESSION_CALENDAR_SUPPORTED_THROUGH,\n} from \"./xnys-calendar-data.ts\";\n\nexport {\n XNYS_SESSION_CALENDAR_REVISION,\n XNYS_SESSION_CALENDAR_SUPPORTED_FROM,\n XNYS_SESSION_CALENDAR_SUPPORTED_THROUGH,\n};\n\n// The published MCP package cannot import the private library at runtime.\n// Membership snapshots are generated from that library's sole calendar authority.\nfunction supportedDate(value: string, label: string): Date {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(value)) {\n throw new TypeError(\n `${label} must be an ISO calendar date (YYYY-MM-DD): ${JSON.stringify(value)}`,\n );\n }\n const date = new Date(`${value}T00:00:00.000Z`);\n if (!Number.isFinite(date.getTime()) || date.toISOString().slice(0, 10) !== value) {\n throw new TypeError(`${label} is not a real calendar date: ${JSON.stringify(value)}`);\n }\n if (\n value < XNYS_SESSION_CALENDAR_SUPPORTED_FROM ||\n value > XNYS_SESSION_CALENDAR_SUPPORTED_THROUGH\n ) {\n throw new RangeError(\n `${label} ${JSON.stringify(value)} is outside XNYS calendar revision ${XNYS_SESSION_CALENDAR_REVISION} ` +\n `[${XNYS_SESSION_CALENDAR_SUPPORTED_FROM}, ${XNYS_SESSION_CALENDAR_SUPPORTED_THROUGH}]`,\n );\n }\n return date;\n}\n\nexport function isXnysSessionDate(value: string): boolean {\n const date = supportedDate(value, \"XNYS session date\");\n const weekday = date.getUTCDay();\n return weekday !== 0 && weekday !== 6 && !CLOSED_DATES.has(value);\n}\n\nexport function isEarlyCloseSession(value: string): boolean {\n return isXnysSessionDate(value) && EARLY_CLOSE_DATES.has(value);\n}\n\nexport function enumerateXnysSessions(from: string, through: string): readonly string[] {\n const first = supportedDate(from, \"XNYS session range from\");\n const last = supportedDate(through, \"XNYS session range through\");\n if (first.getTime() > last.getTime()) {\n throw new RangeError(\n `XNYS session range from ${JSON.stringify(from)} exceeds through ${JSON.stringify(through)}`,\n );\n }\n const sessions: string[] = [];\n for (\n let cursor = first;\n cursor.getTime() <= last.getTime();\n cursor.setUTCDate(cursor.getUTCDate() + 1)\n ) {\n const date = cursor.toISOString().slice(0, 10);\n if (isXnysSessionDate(date)) sessions.push(date);\n }\n return Object.freeze(sessions);\n}\n","import type { DuckDBConnection } from \"@duckdb/node-api\";\nimport { existsSync, readdirSync } from \"node:fs\";\nimport * as path from \"node:path\";\nimport {\n resolveMarketDir,\n writeEnrichedContextPartition,\n writeEnrichedTickerPartition,\n} from \"../../db/market-datasets.ts\";\nimport {\n activePartitionCommitAttempt,\n capturePartitionCommitReceipt,\n} from \"../provenance/partition-commit-attempt.ts\";\nimport { isRealMarketSessionDate } from \"../provenance/dataset-registry.ts\";\nimport {\n INTERNAL_HISTORICAL_PARTITION_ADOPTION,\n type PartitionIdentity,\n type StoredPartitionCommit,\n} from \"../provenance/partition-commit-store.ts\";\nimport { isXnysSessionDate } from \"../provenance/xnys-session-calendar.ts\";\nimport { TICKER_RE } from \"../tickers/schemas.ts\";\n\nfunction escapeSqlLiteral(value: string): string {\n return value.replace(/'/g, \"''\");\n}\n\nexport class LegacyEnrichedMigrationError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"LegacyEnrichedMigrationError\";\n }\n}\n\nasync function legacyDates(conn: DuckDBConnection, filePath: string): Promise<string[]> {\n const escaped = escapeSqlLiteral(filePath);\n const reader = await conn.runAndReadAll(\n `SELECT CAST(date AS VARCHAR) AS logical_date, count(*) AS row_count\n FROM read_parquet('${escaped}', hive_partitioning=false)\n GROUP BY logical_date\n ORDER BY logical_date`,\n );\n const dates: string[] = [];\n for (const [rawDate, rawCount] of reader.getRows()) {\n const date = String(rawDate);\n const count = Number(rawCount);\n if (!isRealMarketSessionDate(date) || count !== 1) {\n throw new LegacyEnrichedMigrationError(\n `Legacy enriched file cannot be split safely: ${JSON.stringify({ filePath, date, rows: count })}`,\n );\n }\n try {\n if (isXnysSessionDate(date)) dates.push(date);\n } catch (error) {\n // Whole-file reads predate the bounded provenance calendar. Preserve\n // valid historical/future rows for ordinary reads, but keep known\n // in-horizon closures excluded.\n if (error instanceof RangeError) {\n dates.push(date);\n continue;\n }\n throw new LegacyEnrichedMigrationError(\n `Legacy enriched file has an invalid session date: ${JSON.stringify({ filePath, date })}`,\n { cause: error },\n );\n }\n }\n return dates;\n}\n\nfunction migrationEligibleSessionDate(date: string): boolean {\n try {\n return isXnysSessionDate(date);\n } catch (error) {\n if (error instanceof RangeError) return false;\n throw error;\n }\n}\n\nexport interface LegacyEnrichedSource {\n filePath: string;\n dates: string[];\n}\n\nexport interface LegacyMigrationBounds {\n from?: string;\n to?: string;\n}\n\nfunction insideBounds(date: string, bounds?: LegacyMigrationBounds): boolean {\n return (!bounds?.from || date >= bounds.from) && (!bounds?.to || date <= bounds.to);\n}\n\nexport async function inspectLegacyEnrichedTicker(\n conn: DuckDBConnection,\n dataDir: string,\n ticker: string,\n): Promise<LegacyEnrichedSource | null> {\n if (!TICKER_RE.test(ticker)) {\n throw new LegacyEnrichedMigrationError(\n `Legacy enriched ticker is not safe to read or migrate: ${JSON.stringify(ticker)}`,\n );\n }\n const tickerDir = path.join(resolveMarketDir(dataDir), \"enriched\", `ticker=${ticker}`);\n const legacyPath = path.join(tickerDir, \"data.parquet\");\n if (!existsSync(legacyPath)) return null;\n const escapedLegacy = escapeSqlLiteral(legacyPath);\n const observedTickers = await conn.runAndReadAll(\n `SELECT DISTINCT CAST(ticker AS VARCHAR)\n FROM read_parquet('${escapedLegacy}', hive_partitioning=false)\n ORDER BY 1`,\n );\n const values = observedTickers.getRows().map((row) => String(row[0]));\n if (values.length !== 1 || values[0] !== ticker) {\n throw new LegacyEnrichedMigrationError(\n `Legacy enriched ticker identity disagrees with its path: ${JSON.stringify({ ticker, observed: values })}`,\n );\n }\n return { filePath: legacyPath, dates: await legacyDates(conn, legacyPath) };\n}\n\nasync function establishExistingAuthority(\n conn: DuckDBConnection,\n dataset: string,\n partition: Record<string, string>,\n): Promise<void> {\n const attempt = activePartitionCommitAttempt();\n if (!attempt) return;\n const internalRecorder = attempt.recorder as typeof attempt.recorder & {\n [INTERNAL_HISTORICAL_PARTITION_ADOPTION]?: (\n connection: DuckDBConnection,\n identity: PartitionIdentity,\n ) => Promise<StoredPartitionCommit>;\n };\n const adopt = internalRecorder[INTERNAL_HISTORICAL_PARTITION_ADOPTION];\n if (!adopt) {\n throw new LegacyEnrichedMigrationError(\n `Active migration recorder cannot adopt existing ${dataset} partition authority`,\n );\n }\n const stored = await adopt.call(internalRecorder, conn, { dataset, partition });\n capturePartitionCommitReceipt(stored);\n}\n\n/**\n * Split a 3.3.x `enriched/ticker=X/data.parquet` file into missing bounded\n * session slices. Existing slices are never replaced: the bounded layout is\n * authoritative when old and new files coexist.\n */\nexport async function migrateLegacyEnrichedTicker(\n conn: DuckDBConnection,\n dataDir: string,\n ticker: string,\n bounds?: LegacyMigrationBounds,\n): Promise<void> {\n const tickerDir = path.join(resolveMarketDir(dataDir), \"enriched\", `ticker=${ticker}`);\n\n try {\n const legacy = await inspectLegacyEnrichedTicker(conn, dataDir, ticker);\n if (!legacy) return;\n const escapedLegacy = escapeSqlLiteral(legacy.filePath);\n for (const date of legacy.dates.filter(\n (candidate) => insideBounds(candidate, bounds) && migrationEligibleSessionDate(candidate),\n )) {\n const targetPath = path.join(tickerDir, `date=${date}`, \"data.parquet\");\n if (existsSync(targetPath)) {\n await establishExistingAuthority(conn, \"enriched\", { ticker, date });\n continue;\n }\n await writeEnrichedTickerPartition(conn, {\n dataDir,\n ticker,\n date,\n selectQuery:\n `SELECT * FROM read_parquet('${escapedLegacy}', hive_partitioning=false) ` +\n `WHERE ticker = '${escapeSqlLiteral(ticker)}' AND CAST(date AS VARCHAR) = '${date}'`,\n quality: { kind: \"writer-input-complete\" },\n });\n }\n } catch (error) {\n if (error instanceof LegacyEnrichedMigrationError) throw error;\n const detail = error instanceof Error ? `: ${error.message}` : \"\";\n throw new LegacyEnrichedMigrationError(\n `Failed to migrate legacy enriched ticker file for ${ticker}${detail}`,\n { cause: error },\n );\n }\n}\n\nfunction completeContextRow(row: unknown[]): boolean {\n const [, volRegime, termStructure, trendDirection, vixSpikePct, vixGapPct] = row;\n return (\n Number.isInteger(volRegime) &&\n Number(volRegime) >= 1 &&\n Number(volRegime) <= 6 &&\n Number.isInteger(termStructure) &&\n [-1, 0, 1].includes(Number(termStructure)) &&\n typeof trendDirection === \"string\" &&\n [\"up\", \"down\", \"flat\"].includes(trendDirection) &&\n typeof vixSpikePct === \"number\" &&\n Number.isFinite(vixSpikePct) &&\n typeof vixGapPct === \"number\" &&\n Number.isFinite(vixGapPct)\n );\n}\n\nexport async function inspectLegacyEnrichedContext(\n conn: DuckDBConnection,\n dataDir: string,\n): Promise<LegacyEnrichedSource | null> {\n const legacyPath = path.join(resolveMarketDir(dataDir), \"enriched\", \"context\", \"data.parquet\");\n if (!existsSync(legacyPath)) return null;\n const escapedLegacy = escapeSqlLiteral(legacyPath);\n const completeDates: string[] = [];\n for (const date of await legacyDates(conn, legacyPath)) {\n const selected = await conn.runAndReadAll(\n `SELECT date, Vol_Regime, Term_Structure_State, Trend_Direction,\n VIX_Spike_Pct, VIX_Gap_Pct\n FROM read_parquet('${escapedLegacy}', hive_partitioning=false)\n WHERE CAST(date AS VARCHAR) = '${date}'`,\n );\n const rows = selected.getRows();\n if (rows.length === 1 && completeContextRow(rows[0])) completeDates.push(date);\n }\n return { filePath: legacyPath, dates: completeDates };\n}\n\n/**\n * Split the 3.3.x `enriched/context/data.parquet` file into complete bounded\n * sessions. Partial context rows remain in the legacy file but are omitted\n * from canonical authority rather than being represented as complete inputs.\n */\nexport async function migrateLegacyEnrichedContext(\n conn: DuckDBConnection,\n dataDir: string,\n bounds?: LegacyMigrationBounds,\n): Promise<void> {\n const contextDir = path.join(resolveMarketDir(dataDir), \"enriched\", \"context\");\n const legacyPath = path.join(contextDir, \"data.parquet\");\n if (!existsSync(legacyPath)) return;\n\n try {\n const legacy = await inspectLegacyEnrichedContext(conn, dataDir);\n if (!legacy) return;\n const escapedLegacy = escapeSqlLiteral(legacy.filePath);\n for (const date of legacy.dates.filter(\n (candidate) => insideBounds(candidate, bounds) && migrationEligibleSessionDate(candidate),\n )) {\n const targetPath = path.join(contextDir, `date=${date}`, \"data.parquet\");\n if (existsSync(targetPath)) {\n await establishExistingAuthority(conn, \"enriched_context\", { date });\n continue;\n }\n await writeEnrichedContextPartition(conn, {\n dataDir,\n date,\n selectQuery:\n `SELECT * FROM read_parquet('${escapedLegacy}', hive_partitioning=false) ` +\n `WHERE CAST(date AS VARCHAR) = '${date}'`,\n quality: { kind: \"writer-input-complete\" },\n });\n }\n } catch (error) {\n if (error instanceof LegacyEnrichedMigrationError) throw error;\n const detail = error instanceof Error ? `: ${error.message}` : \"\";\n throw new LegacyEnrichedMigrationError(\n `Failed to migrate legacy enriched context file: ${legacyPath}${detail}`,\n { cause: error },\n );\n }\n}\n\n/** Migrate every legacy per-ticker file plus the shared context file. */\nexport async function migrateAllLegacyEnrichedFiles(\n conn: DuckDBConnection,\n dataDir: string,\n bounds?: LegacyMigrationBounds,\n): Promise<void> {\n const enrichedDir = path.join(resolveMarketDir(dataDir), \"enriched\");\n if (existsSync(enrichedDir)) {\n let entries: string[];\n try {\n entries = readdirSync(enrichedDir);\n } catch (error) {\n throw new LegacyEnrichedMigrationError(\n `Cannot enumerate legacy enriched data: ${enrichedDir}`,\n { cause: error },\n );\n }\n for (const entry of entries.sort()) {\n if (!entry.startsWith(\"ticker=\")) continue;\n const ticker = entry.slice(\"ticker=\".length);\n if (existsSync(path.join(enrichedDir, entry, \"data.parquet\"))) {\n await migrateLegacyEnrichedTicker(conn, dataDir, ticker, bounds);\n }\n }\n }\n await migrateLegacyEnrichedContext(conn, dataDir, bounds);\n}\n","import type { DuckDBConnection } from \"@duckdb/node-api\";\nimport * as path from \"path\";\nimport { getDataRoot } from \"./data-root.ts\";\nimport {\n writeParquetAtomic,\n writeParquetPartition,\n type ParquetWriteResult,\n} from \"./parquet-writer.ts\";\nimport { MARKET_DATASETS } from \"../market/provenance/dataset-registry.ts\";\n\nexport type CanonicalSingleFileDataset = \"daily\" | \"date_context\";\nexport type CanonicalPartitionedDataset = \"intraday\" | \"option_chain\" | \"option_quote_minutes\";\nexport type CanonicalMarketDataset = CanonicalSingleFileDataset | CanonicalPartitionedDataset;\n\nconst SINGLE_FILE_DATASETS: Record<CanonicalSingleFileDataset, string> = {\n daily: \"daily.parquet\",\n date_context: \"date_context.parquet\",\n};\n\nconst PARTITIONED_DATASETS: Record<CanonicalPartitionedDataset, string> = {\n intraday: \"intraday\",\n option_chain: \"option_chain\",\n option_quote_minutes: \"option_quote_minutes\",\n};\n\nexport function resolveMarketDir(dataDir: string): string {\n return path.join(getDataRoot(dataDir), \"market\");\n}\n\nexport function resolveCanonicalMarketFile(\n dataDir: string,\n dataset: CanonicalSingleFileDataset,\n): string {\n return path.join(resolveMarketDir(dataDir), SINGLE_FILE_DATASETS[dataset]);\n}\n\nexport function resolveCanonicalMarketPartitionDir(\n dataDir: string,\n dataset: CanonicalPartitionedDataset,\n): string {\n return path.join(resolveMarketDir(dataDir), PARTITIONED_DATASETS[dataset]);\n}\n\nexport function resolveCanonicalMarketPartitionPath(\n dataDir: string,\n dataset: CanonicalPartitionedDataset,\n date: string,\n): string {\n return path.join(resolveCanonicalMarketPartitionDir(dataDir, dataset), `date=${date}`);\n}\n\nexport function resolveCanonicalMarketPartitionFile(\n dataDir: string,\n dataset: CanonicalPartitionedDataset,\n date: string,\n): string {\n return path.join(resolveCanonicalMarketPartitionPath(dataDir, dataset, date), \"data.parquet\");\n}\n\nexport function canonicalMarketTableName(dataset: CanonicalMarketDataset): string {\n return `market.${dataset}`;\n}\n\n// ============================================================================\n// Declarative dataset registry — canonical Parquet layout\n//\n// spot: spot/ticker=X/date=Y/data.parquet\n// enriched: enriched/ticker=X/data.parquet\n// enriched_context: enriched/context/data.parquet\n// option_chain: option_chain/underlying=X/date=Y/data.parquet\n// option_quote_minutes: option_quote_minutes/underlying=X/date=Y/data.parquet\n//\n// This mutable exported registry is a compatibility contract for the public\n// tradeblocks-mcp/db/market-datasets subpath. Bounded provenance writers use\n// the separate frozen internal registry below.\n// ============================================================================\n\nexport interface DatasetDef {\n subdir: string;\n partitionKeys: string[];\n filename: string;\n}\n\nexport type DatasetWriteQuality =\n { inputRows: number; droppedRows: number } | { kind: \"writer-input-complete\" };\n\nfunction provenanceOptions(\n dataset: string,\n partition: Record<string, string>,\n schemaRevision: number,\n relativePath: string,\n coverage: { kind: \"prepared-date-range\"; column: string },\n quality?: DatasetWriteQuality,\n) {\n return { dataset, partition, schemaRevision, relativePath, coverage, quality };\n}\n\nexport const DATASETS_V3: Record<string, DatasetDef> = {\n spot: { subdir: \"spot\", partitionKeys: [\"ticker\", \"date\"], filename: \"data.parquet\" },\n enriched: { subdir: \"enriched\", partitionKeys: [\"ticker\"], filename: \"data.parquet\" },\n enriched_context: { subdir: \"enriched/context\", partitionKeys: [], filename: \"data.parquet\" },\n option_chain: {\n subdir: \"option_chain\",\n partitionKeys: [\"underlying\", \"date\"],\n filename: \"data.parquet\",\n },\n option_quote_minutes: {\n subdir: \"option_quote_minutes\",\n partitionKeys: [\"underlying\", \"date\"],\n filename: \"data.parquet\",\n },\n option_oi_daily: {\n subdir: \"option_oi_daily\",\n partitionKeys: [\"underlying\", \"date\"],\n filename: \"data.parquet\",\n },\n};\n\ntype BoundedProvenanceDatasetRegistry = typeof MARKET_DATASETS;\nconst BOUNDED_PROVENANCE_DATASETS: BoundedProvenanceDatasetRegistry = MARKET_DATASETS;\n\nfunction assertCanonicalPartitionDate(value: unknown, helper: string): asserts value is string {\n if (typeof value !== \"string\" || !/^\\d{4}-\\d{2}-\\d{2}$/.test(value)) {\n throw new TypeError(\n `${helper}: date must be an ISO calendar date (YYYY-MM-DD): ${JSON.stringify(value)}`,\n );\n }\n const parsed = new Date(`${value}T00:00:00.000Z`);\n if (!Number.isFinite(parsed.getTime()) || parsed.toISOString().slice(0, 10) !== value) {\n throw new TypeError(`${helper}: date is not a real calendar date: ${JSON.stringify(value)}`);\n }\n}\n\n// ------ Per-dataset write helpers ------\n//\n// Each helper reads its DatasetDef, composes the partitions map in the order\n// given by DatasetDef.partitionKeys, and delegates to writeParquetPartition\n// (the generic multi-level writer from parquet-writer.ts).\n//\n// Security note: writeParquetPartition applies a whitelist to every partition\n// key and value — /^[A-Za-z0-9._-]+$/ on values, /^[A-Za-z_][A-Za-z0-9_]*$/ on keys.\n// That is the deepest defense-in-depth layer against path traversal. Bounded\n// helpers additionally validate dates before composing paths or provenance.\n\nexport async function writeSpotPartition(\n conn: DuckDBConnection,\n args: {\n dataDir: string;\n ticker: string;\n date: string;\n selectQuery: string;\n compression?: string;\n quality?: DatasetWriteQuality;\n },\n): Promise<ParquetWriteResult> {\n assertCanonicalPartitionDate(args.date, \"writeSpotPartition\");\n const def = BOUNDED_PROVENANCE_DATASETS.spot;\n return writeParquetPartition(conn, {\n baseDir: path.join(resolveMarketDir(args.dataDir), def.subdir),\n partitions: { ticker: args.ticker, date: args.date }, // order matches def.partitionKeys\n selectQuery: args.selectQuery,\n compression: args.compression,\n filename: def.filename,\n provenance: provenanceOptions(\n \"spot\",\n { ticker: args.ticker, date: args.date },\n def.schemaRevision,\n path.posix.join(def.subdir, `ticker=${args.ticker}`, `date=${args.date}`, def.filename),\n { kind: \"prepared-date-range\", column: \"date\" },\n args.quality,\n ),\n });\n}\n\nexport async function writeChainPartition(\n conn: DuckDBConnection,\n args: {\n dataDir: string;\n underlying: string;\n date: string;\n selectQuery: string;\n compression?: string;\n quality?: DatasetWriteQuality;\n },\n): Promise<ParquetWriteResult> {\n assertCanonicalPartitionDate(args.date, \"writeChainPartition\");\n const def = BOUNDED_PROVENANCE_DATASETS.option_chain;\n return writeParquetPartition(conn, {\n baseDir: path.join(resolveMarketDir(args.dataDir), def.subdir),\n partitions: { underlying: args.underlying, date: args.date },\n selectQuery: args.selectQuery,\n compression: args.compression,\n filename: def.filename,\n provenance: provenanceOptions(\n \"option_chain\",\n { underlying: args.underlying, date: args.date },\n def.schemaRevision,\n path.posix.join(\n def.subdir,\n `underlying=${args.underlying}`,\n `date=${args.date}`,\n def.filename,\n ),\n { kind: \"prepared-date-range\", column: \"date\" },\n args.quality,\n ),\n });\n}\n\nexport async function writeQuoteMinutesPartition(\n conn: DuckDBConnection,\n args: {\n dataDir: string;\n underlying: string;\n date: string;\n selectQuery: string;\n compression?: string;\n quality?: DatasetWriteQuality;\n },\n): Promise<ParquetWriteResult> {\n assertCanonicalPartitionDate(args.date, \"writeQuoteMinutesPartition\");\n const def = BOUNDED_PROVENANCE_DATASETS.option_quote_minutes;\n // Sort rows by (ticker, time) before writing so DuckDB row groups in the\n // resulting parquet have tight min/max statistics on `ticker`. The\n // dominant read pattern is ticker-windowed scans across a time range\n // (querying a specific symbol across many minutes/days), so sorting\n // partitions by `(ticker, time)` lets DuckDB prune row groups by ticker\n // first and gives column-statistics benefits within each ticker.\n //\n // The previous `(time, ticker)` order favored single-minute multi-ticker\n // scans; that shape regresses slightly under the new sort, but it is no\n // longer the dominant consumer pattern.\n //\n // Wrapping the caller's selectQuery is safer than asking every caller to\n // remember to ORDER BY: writes go through one funnel.\n //\n // If you change this, also re-run `tools/sort-quote-parquet.mjs` to\n // re-sort existing partitions. The tool is idempotent (skips\n // already-sorted files via row-group ticker stats).\n const sortedSelect = `SELECT * FROM (${args.selectQuery}) AS q ORDER BY q.ticker, q.time`;\n return writeParquetPartition(conn, {\n baseDir: path.join(resolveMarketDir(args.dataDir), def.subdir),\n partitions: { underlying: args.underlying, date: args.date },\n selectQuery: sortedSelect,\n compression: args.compression,\n filename: def.filename,\n provenance: provenanceOptions(\n \"option_quote_minutes\",\n { underlying: args.underlying, date: args.date },\n def.schemaRevision,\n path.posix.join(\n def.subdir,\n `underlying=${args.underlying}`,\n `date=${args.date}`,\n def.filename,\n ),\n { kind: \"prepared-date-range\", column: \"date\" },\n args.quality,\n ),\n });\n}\n\nexport async function writeOiDailyPartition(\n conn: DuckDBConnection,\n args: {\n dataDir: string;\n underlying: string;\n date: string;\n selectQuery: string;\n compression?: string;\n quality?: DatasetWriteQuality;\n },\n): Promise<ParquetWriteResult> {\n assertCanonicalPartitionDate(args.date, \"writeOiDailyPartition\");\n const def = BOUNDED_PROVENANCE_DATASETS.option_oi_daily;\n // Sort rows by ticker before writing so DuckDB row groups carry tight\n // min/max statistics on `ticker` — the dominant read pattern is a\n // ticker-windowed scan within a (underlying, date) partition, matching the\n // quote store's (ticker, time) sort rationale (one value per ticker per day\n // here, so ticker alone is the sort key).\n const sortedSelect = `SELECT * FROM (${args.selectQuery}) AS q ORDER BY q.ticker`;\n return writeParquetPartition(conn, {\n baseDir: path.join(resolveMarketDir(args.dataDir), def.subdir),\n partitions: { underlying: args.underlying, date: args.date },\n selectQuery: sortedSelect,\n compression: args.compression,\n filename: def.filename,\n provenance: provenanceOptions(\n \"option_oi_daily\",\n { underlying: args.underlying, date: args.date },\n def.schemaRevision,\n path.posix.join(\n def.subdir,\n `underlying=${args.underlying}`,\n `date=${args.date}`,\n def.filename,\n ),\n { kind: \"prepared-date-range\", column: \"date\" },\n args.quality,\n ),\n });\n}\n\n/**\n * Backward-compatible whole-file writer for the legacy 3.3.x layout:\n * enriched/ticker=X/data.parquet.\n */\nexport async function writeEnrichedTickerFile(\n conn: DuckDBConnection,\n args: { dataDir: string; ticker: string; selectQuery: string; compression?: string },\n): Promise<{ rowCount: number }> {\n const def = DATASETS_V3.enriched;\n return writeParquetPartition(conn, {\n baseDir: path.join(resolveMarketDir(args.dataDir), def.subdir),\n partitions: { ticker: args.ticker },\n selectQuery: args.selectQuery,\n compression: args.compression,\n filename: def.filename,\n });\n}\n\n/**\n * Writes one bounded ticker/session slice:\n * enriched/ticker=X/date=Y/data.parquet.\n */\nexport async function writeEnrichedTickerPartition(\n conn: DuckDBConnection,\n args: {\n dataDir: string;\n ticker: string;\n date: string;\n selectQuery: string;\n compression?: string;\n quality?: DatasetWriteQuality;\n },\n): Promise<ParquetWriteResult> {\n assertCanonicalPartitionDate(args.date, \"writeEnrichedTickerPartition\");\n const def = BOUNDED_PROVENANCE_DATASETS.enriched;\n return writeParquetPartition(conn, {\n baseDir: path.join(resolveMarketDir(args.dataDir), def.subdir),\n partitions: { ticker: args.ticker, date: args.date },\n selectQuery: args.selectQuery,\n compression: args.compression,\n filename: def.filename,\n provenance: provenanceOptions(\n \"enriched\",\n { ticker: args.ticker, date: args.date },\n def.schemaRevision,\n path.posix.join(def.subdir, `ticker=${args.ticker}`, `date=${args.date}`, def.filename),\n { kind: \"prepared-date-range\", column: \"date\" },\n args.quality,\n ),\n });\n}\n\n/**\n * Backward-compatible whole-file writer for the legacy 3.3.x layout:\n * enriched/context/data.parquet.\n */\nexport async function writeEnrichedContext(\n conn: DuckDBConnection,\n args: { dataDir: string; selectQuery: string; compression?: string },\n): Promise<{ rowCount: number }> {\n const def = DATASETS_V3.enriched_context;\n return writeParquetAtomic(conn, {\n targetPath: path.join(resolveMarketDir(args.dataDir), def.subdir, def.filename),\n selectQuery: args.selectQuery,\n compression: args.compression,\n });\n}\n\n/**\n * Writes one bounded cross-ticker context session:\n * enriched/context/date=Y/data.parquet.\n */\nexport async function writeEnrichedContextPartition(\n conn: DuckDBConnection,\n args: {\n dataDir: string;\n date: string;\n selectQuery: string;\n compression?: string;\n quality?: DatasetWriteQuality;\n },\n): Promise<ParquetWriteResult> {\n assertCanonicalPartitionDate(args.date, \"writeEnrichedContextPartition\");\n const completeness = await conn.runAndReadAll(\n `SELECT date, Vol_Regime, Term_Structure_State, Trend_Direction,\n VIX_Spike_Pct, VIX_Gap_Pct\n FROM (${args.selectQuery}) AS bounded_enriched_context`,\n );\n const rows = completeness.getRows();\n if (rows.length !== 1) {\n throw new Error(\n `Enriched context partition ${args.date} must contain exactly one logical session row`,\n );\n }\n const [date, volRegime, termStructure, trendDirection, vixSpikePct, vixGapPct] = rows[0];\n if (String(date) !== args.date) {\n throw new Error(`Enriched context partition ${args.date} contains a different logical date`);\n }\n if (\n !Number.isInteger(volRegime) ||\n Number(volRegime) < 1 ||\n Number(volRegime) > 6 ||\n !Number.isInteger(termStructure) ||\n ![-1, 0, 1].includes(Number(termStructure)) ||\n typeof trendDirection !== \"string\" ||\n ![\"up\", \"down\", \"flat\"].includes(trendDirection) ||\n typeof vixSpikePct !== \"number\" ||\n !Number.isFinite(vixSpikePct) ||\n typeof vixGapPct !== \"number\" ||\n !Number.isFinite(vixGapPct)\n ) {\n throw new Error(\n `Enriched context partition ${args.date} is missing required VIX completeness fields`,\n );\n }\n const def = BOUNDED_PROVENANCE_DATASETS.enriched_context;\n return writeParquetPartition(conn, {\n baseDir: path.join(resolveMarketDir(args.dataDir), def.subdir),\n partitions: { date: args.date },\n selectQuery: args.selectQuery,\n compression: args.compression,\n filename: def.filename,\n provenance: provenanceOptions(\n \"enriched_context\",\n { date: args.date },\n def.schemaRevision,\n path.posix.join(def.subdir, `date=${args.date}`, def.filename),\n { kind: \"prepared-date-range\", column: \"date\" },\n args.quality,\n ),\n });\n}\n","/**\n * Data Root Directory Override\n *\n * When --data-root is set, shared data (market/, market-meta/, strategies/, blocks/)\n * lives under this path instead of alongside DuckDB files.\n *\n * Set via --data-root CLI flag or TRADEBLOCKS_DATA_ROOT env var.\n * When not set, getDataRoot() falls back to its argument (backward compat).\n *\n * Stored on globalThis so all bundle instances in the same process share state.\n * tsup duplicates this module across separate bundles; a module-scoped variable\n * would give each bundle its own _dataRoot, leaving one path correct (set by\n * the CLI parser) and the other null (a consumer reads its own copy and falls\n * back to the default → wrong path).\n *\n * Note: globalThis is per-realm. Consumers running this across Workers, VM\n * contexts, or sandboxed iframes will see the same divergence across realm\n * boundaries and must coordinate state another way.\n */\nimport path from \"node:path\";\n\nconst KEY = \"__tradeblocks_data_root__\";\ntype GlobalSlot = { [KEY]?: string | null };\n\n/**\n * The DuckDB files that live under a data root's `database/` subdirectory.\n * - `analytics` — the base DB hosting the `trades` schema (CSV-imported blocks)\n * - `market` — attached market data (`market.duckdb`)\n * - `backtests` — the backtest run-persistence index (`backtests.duckdb`)\n */\nexport type DbKind = \"analytics\" | \"market\" | \"backtests\";\n\n/**\n * Single source of truth for where a DuckDB file lives under a data root:\n * `<dataRoot>/database/<kind>.duckdb`. Every writer and reader across the fleet\n * (the engine's backtests-db resolver, the console reader, the calibration\n * probe) MUST resolve through this so the `database/` segment can never drift —\n * a missing segment silently splits reads from writes (runs succeed, the console\n * shows an empty history forever).\n */\nexport function resolveDbPath(dataRoot: string, kind: DbKind): string {\n return path.join(dataRoot, \"database\", `${kind}.duckdb`);\n}\n\nexport function setDataRoot(dir: string): void {\n (globalThis as GlobalSlot)[KEY] = dir;\n}\n\nexport function getDataRoot(fallback: string): string {\n return (globalThis as GlobalSlot)[KEY] ?? fallback;\n}\n\n/** Reset for testing. Not used in production. */\nexport function resetDataRoot(): void {\n (globalThis as GlobalSlot)[KEY] = null;\n}\n","/**\n * Parquet Writer Utility\n *\n * Provides atomic Parquet file writing via DuckDB's COPY TO command.\n * Used by all market data importers and enrichers when TRADEBLOCKS_PARQUET=true.\n *\n * Pattern: INSERT into staging temp table -> COPY TO Parquet -> DROP staging.\n * This ensures atomicity: if COPY TO fails, the original Parquet file is untouched.\n *\n * Exports:\n * - isParquetMode() - Check if Parquet write mode is enabled\n * - resolveMarketDir() - Centralized market directory path\n * - writeParquetAtomic() - Atomic single-file Parquet write via staging table\n * - writeParquetPartition() - Hive-partitioned write. Two overloads:\n * (a) legacy { baseDir, date, selectQuery } → baseDir/date=Y/data.parquet\n * (b) generic { baseDir, partitions: {...}, ... } → baseDir/k1=v1/k2=v2/.../data.parquet\n */\n\nimport type { DuckDBConnection } from \"@duckdb/node-api\";\nimport { createHash } from \"node:crypto\";\nimport { createReadStream, existsSync } from \"node:fs\";\nimport * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport type {\n ExactFileFingerprint,\n LogicalCoverage,\n PartitionQualityCounts,\n StoredPartitionCommit,\n} from \"../market/provenance/partition-commit-store.ts\";\nimport {\n PartitionFilePublicationError,\n assertCanonicalParquetSchema,\n} from \"../market/provenance/partition-commit-store.ts\";\nimport {\n activePartitionCommitAttempt,\n capturePartitionCommitReceipt,\n} from \"../market/provenance/partition-commit-attempt.ts\";\nimport { canonicalJsonBytes } from \"../market/provenance/canonical-json.ts\";\nexport { resolveMarketDir } from \"./market-datasets.ts\";\n\n// ---------------------------------------------------------------------------\n// Parquet mode detection\n// ---------------------------------------------------------------------------\n\n/**\n * Check if Parquet write mode is enabled.\n * Reads process.env.TRADEBLOCKS_PARQUET on each call for testability.\n *\n * @returns true when TRADEBLOCKS_PARQUET === 'true', false otherwise\n */\nexport function isParquetMode(): boolean {\n return process.env.TRADEBLOCKS_PARQUET === \"true\";\n}\n\n// ---------------------------------------------------------------------------\n// Atomic Parquet write\n// ---------------------------------------------------------------------------\n\nexport interface WriteParquetAtomicOpts {\n /** Target Parquet file path (e.g., '{dataDir}/market/daily.parquet') */\n targetPath: string;\n /** SELECT query that produces the final dataset */\n selectQuery: string;\n /** Temp table name (default: _staging_{Date.now()}) */\n stagingName?: string;\n /** Parquet compression codec (default: 'ZSTD') */\n compression?: string;\n /** Optional exact-byte partition provenance. Omit for legacy behavior. */\n provenance?: WriteParquetProvenanceOpts;\n}\n\nexport interface WriteParquetProvenanceOpts {\n dataset: string;\n partition: Record<string, string>;\n schemaRevision: number;\n /** Stable path relative to the canonical market directory. */\n relativePath: string;\n /** Coverage is measured from the completed Parquet bytes, never staging state. */\n coverage: { kind: \"prepared-date-range\"; column: string };\n /** Required inside a provenance attempt; omitted legacy writes remain supported. */\n quality?: { inputRows: number; droppedRows: number } | { kind: \"writer-input-complete\" };\n}\n\nexport interface ParquetWriteResult {\n rowCount: number;\n /** Additive writer-level evidence; store facades intentionally strip this field. */\n provenance?: StoredPartitionCommit;\n}\n\nfunction captureWriteProvenance(\n provenance: WriteParquetProvenanceOpts | undefined,\n): WriteParquetProvenanceOpts | undefined {\n if (!provenance) return undefined;\n const captured = {\n dataset: provenance.dataset,\n partition: provenance.partition,\n schemaRevision: provenance.schemaRevision,\n relativePath: provenance.relativePath,\n coverage: provenance.coverage,\n ...(provenance.quality === undefined ? {} : { quality: provenance.quality }),\n };\n return JSON.parse(canonicalJsonBytes(captured).toString(\"utf8\")) as WriteParquetProvenanceOpts;\n}\n\n/**\n * The Parquet rename succeeded but the immutable receipt/head update failed.\n * The target is intentionally left in place and must be reconciled before a\n * manifest can treat it as committed.\n */\nexport class ParquetProvenanceOrphanError extends Error {\n readonly targetPath: string;\n readonly file: ExactFileFingerprint;\n\n constructor(targetPath: string, file: ExactFileFingerprint, cause: unknown) {\n super(`Parquet data committed without provenance receipt: ${targetPath}`, { cause });\n this.name = \"ParquetProvenanceOrphanError\";\n this.targetPath = targetPath;\n this.file = file;\n }\n}\n\n/** An active commit attempt encountered a write with no registered receipt shape. */\nexport class UnmanifestedParquetWriteError extends Error {\n readonly targetPath: string;\n\n constructor(targetPath: string) {\n super(`Active partition commit attempt refuses an unregistered Parquet write: ${targetPath}`);\n this.name = \"UnmanifestedParquetWriteError\";\n this.targetPath = targetPath;\n }\n}\n\nasync function exactFileFingerprint(filePath: string, rows: number): Promise<ExactFileFingerprint> {\n const hash = createHash(\"sha256\");\n let bytes = 0;\n for await (const chunk of createReadStream(filePath)) {\n const buffer = chunk as Buffer;\n bytes += buffer.byteLength;\n hash.update(buffer);\n }\n return { address: `sha256:${hash.digest(\"hex\")}`, bytes, rows };\n}\n\nfunction escapeSqlLiteral(value: string): string {\n return value.replaceAll(\"'\", \"''\");\n}\n\nconst MIN_QUOTE_PARTITION_ROW_FRACTION = 0.5;\n\nclass QuotePartitionShrinkError extends Error {\n constructor(partition: Record<string, string>, existing: number, candidate: number) {\n super(\n `Quote partition shrink refused: underlying=${partition.underlying}/date=${partition.date}; ` +\n `existing=${existing}, candidate=${candidate}, threshold=${MIN_QUOTE_PARTITION_ROW_FRACTION}`,\n );\n this.name = \"QuotePartitionShrinkError\";\n }\n}\n\nasync function assertQuotePartitionRowCount(\n conn: DuckDBConnection,\n targetPath: string,\n provenance: WriteParquetProvenanceOpts | undefined,\n candidate: number,\n): Promise<void> {\n // Canonical quote writes carry this dataset identity even outside a provenance attempt.\n if (provenance?.dataset !== \"option_quote_minutes\" || !existsSync(targetPath)) return;\n const reader = await conn.runAndReadAll(\n `SELECT COUNT(*) FROM read_parquet('${escapeSqlLiteral(targetPath)}', hive_partitioning=false)`,\n );\n const existing = Number(reader.getRows()[0][0]);\n if (candidate < existing * MIN_QUOTE_PARTITION_ROW_FRACTION) {\n throw new QuotePartitionShrinkError(provenance.partition, existing, candidate);\n }\n}\n\nasync function inspectPreparedParquet(\n conn: DuckDBConnection,\n preparedPath: string,\n coverage: WriteParquetProvenanceOpts[\"coverage\"],\n): Promise<{ rowCount: number; coverage: LogicalCoverage }> {\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(coverage.column)) {\n throw new TypeError(`Unsafe provenance coverage column: ${JSON.stringify(coverage.column)}`);\n }\n // Never let Hive path keys synthesize/override the stored date column. The\n // coverage proof must inspect exact file content, not its destination name.\n const source = `read_parquet('${escapeSqlLiteral(preparedPath)}', hive_partitioning=false)`;\n const reader = await conn.runAndReadAll(\n `SELECT COUNT(*)::BIGINT,\n COUNT(\"${coverage.column}\")::BIGINT,\n MIN(CAST(\"${coverage.column}\" AS VARCHAR)),\n MAX(CAST(\"${coverage.column}\" AS VARCHAR))\n FROM ${source}`,\n );\n const row = reader.getRows()[0];\n const rowCount = Number(row[0]);\n const coveredRows = Number(row[1]);\n if (!Number.isSafeInteger(rowCount) || rowCount < 0 || !Number.isSafeInteger(coveredRows)) {\n throw new Error(\"Prepared Parquet returned an invalid row count\");\n }\n if (rowCount === 0) {\n if (coveredRows !== 0 || row[2] != null || row[3] != null) {\n throw new Error(\"Empty prepared Parquet returned inconsistent logical coverage\");\n }\n return { rowCount, coverage: { kind: \"empty\" } };\n }\n if (coveredRows !== rowCount || row[2] == null || row[3] == null) {\n throw new Error(\n `Prepared Parquet contains NULL or incomplete logical coverage in ${coverage.column}`,\n );\n }\n return {\n rowCount,\n coverage: { kind: \"date-range\", from: String(row[2]), through: String(row[3]) },\n };\n}\n\nasync function syncFile(filePath: string): Promise<void> {\n const handle = await fs.open(filePath, \"r\");\n try {\n await handle.sync();\n } finally {\n await handle.close();\n }\n}\n\nasync function syncDirectory(directory: string): Promise<void> {\n const handle = await fs.open(directory, \"r\");\n try {\n await handle.sync();\n } finally {\n await handle.close();\n }\n}\n\nfunction resolveQuality(\n rowCount: number,\n quality: WriteParquetProvenanceOpts[\"quality\"],\n): PartitionQualityCounts {\n if (!quality) {\n throw new Error(\"Partition provenance requires explicit inputRows and droppedRows\");\n }\n if (\"kind\" in quality) {\n return { inputRows: rowCount, writtenRows: rowCount, droppedRows: 0 };\n }\n if (\n !Number.isSafeInteger(quality.inputRows) ||\n !Number.isSafeInteger(quality.droppedRows) ||\n quality.inputRows < 0 ||\n quality.droppedRows < 0 ||\n quality.inputRows !== rowCount + quality.droppedRows\n ) {\n throw new Error(\n `Partition provenance quality must satisfy inputRows (${quality.inputRows}) = writtenRows (${rowCount}) + droppedRows (${quality.droppedRows})`,\n );\n }\n return {\n inputRows: quality.inputRows,\n writtenRows: rowCount,\n droppedRows: quality.droppedRows,\n };\n}\n\n/**\n * Atomic single-file Parquet write via DuckDB staging table.\n *\n * 1. CREATE TEMP TABLE {staging} AS {selectQuery}\n * 2. mkdir -p parent directory\n * 3. COPY {staging} TO '{targetPath}' (FORMAT PARQUET, COMPRESSION {compression})\n * 4. COUNT(*) for rowCount\n * 5. DROP staging in finally block\n *\n * Path-traversal mitigation: targetPath is always constructed by callers via\n * path.join(dataDir, 'market', ...) with no user-supplied path components.\n * Identifier-injection mitigation: staging table names use Date.now() — no user input.\n *\n * @param conn - Active DuckDB connection\n * @param opts - Write options\n * @returns Object with rowCount of written rows\n */\nexport async function writeParquetAtomic(\n conn: DuckDBConnection,\n opts: WriteParquetAtomicOpts,\n): Promise<ParquetWriteResult> {\n const {\n targetPath,\n selectQuery,\n stagingName = `_staging_${Date.now()}`,\n compression = \"ZSTD\",\n provenance: callerProvenance,\n } = opts;\n const provenance = captureWriteProvenance(callerProvenance);\n const provenanceAttempt = activePartitionCommitAttempt();\n if (provenanceAttempt && !provenance) throw new UnmanifestedParquetWriteError(targetPath);\n\n // Write to a temp sibling path, then atomic-rename into place. DuckDB's\n // COPY ... TO 'data.parquet' writes directly to the target — concurrent\n // readers (e.g. createMarketParquetViews globbing the archive) can observe\n // the file as empty / truncated / missing during the write. fs.rename is\n // atomic on local filesystems (APFS, ext4), so after this block a reader\n // either sees the old file or the new file, never a partially-written or\n // absent one. The temp name ends in `.tmp-PID-TS` (not `.parquet`) so\n // `**/data.parquet` and `**/*.parquet` globs both skip it.\n const tempPath = `${targetPath}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n try {\n // Stage data into a temp table\n await conn.run(`CREATE TEMP TABLE \"${stagingName}\" AS ${selectQuery}`);\n\n // Ensure parent directory exists\n await fs.mkdir(path.dirname(targetPath), { recursive: true });\n\n // Write to sidecar temp path\n await conn.run(\n `COPY \"${stagingName}\" TO '${tempPath}' (FORMAT PARQUET, COMPRESSION ${compression})`,\n );\n\n // Inside a partition commit attempt the completed temp sibling must\n // already match the canonical dataset schema before any fingerprint,\n // receipt, event, or install step can observe it.\n if (provenanceAttempt && provenance) {\n await assertCanonicalParquetSchema(conn, tempPath, provenance.dataset);\n }\n\n // Re-open the exact completed bytes. Counts and coverage must describe the\n // file being installed, not mutable staging state that merely preceded it.\n const inspected = provenanceAttempt\n ? await inspectPreparedParquet(conn, tempPath, provenance!.coverage)\n : undefined;\n const rowCount = inspected\n ? inspected.rowCount\n : Number(\n (\n await conn.runAndReadAll(`SELECT COUNT(*)::INTEGER AS cnt FROM \"${stagingName}\"`)\n ).getRows()[0][0],\n );\n await assertQuotePartitionRowCount(conn, targetPath, provenance, rowCount);\n const logicalCoverage = inspected?.coverage;\n const quality = provenanceAttempt ? resolveQuality(rowCount, provenance!.quality) : undefined;\n const fingerprint = provenanceAttempt\n ? await exactFileFingerprint(tempPath, rowCount)\n : undefined;\n\n if (provenance && provenanceAttempt && fingerprint && logicalCoverage && quality) {\n try {\n const stored = await provenanceAttempt.recorder.publishFileCommit({\n dataset: provenance.dataset,\n partition: provenance.partition,\n schemaRevision: provenance.schemaRevision,\n relativePath: provenance.relativePath,\n coverage: logicalCoverage,\n quality,\n file: fingerprint,\n preparedPath: tempPath,\n expectedTargetPath: targetPath,\n });\n capturePartitionCommitReceipt(stored);\n return { rowCount, provenance: stored };\n } catch (error) {\n if (error instanceof PartitionFilePublicationError) {\n throw new ParquetProvenanceOrphanError(targetPath, fingerprint, error);\n }\n throw error;\n }\n }\n\n await syncFile(tempPath);\n await syncDirectory(path.dirname(tempPath));\n await fs.rename(tempPath, targetPath);\n await syncDirectory(path.dirname(targetPath));\n\n return { rowCount };\n } catch (writeErr) {\n // Clean up sidecar on failure so the next attempt starts fresh\n try {\n await fs.unlink(tempPath);\n } catch {\n /* may not exist */\n }\n throw writeErr;\n } finally {\n // Always clean up staging table\n try {\n await conn.run(`DROP TABLE IF EXISTS \"${stagingName}\"`);\n } catch {\n // Non-fatal: table may not exist if creation failed\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Hive-partitioned Parquet write\n// ---------------------------------------------------------------------------\n\nexport interface WriteParquetPartitionOpts {\n /** Base directory for Hive partitions (e.g., '{dataDir}/market/intraday') */\n baseDir: string;\n /** Partition date (e.g., '2025-01-06') */\n date: string;\n /** SELECT query that produces rows for this date */\n selectQuery: string;\n /** Parquet compression codec (default: 'ZSTD') */\n compression?: string;\n provenance?: WriteParquetProvenanceOpts;\n}\n\n/**\n * Generic multi-level Hive partition writer options.\n *\n * Insertion order of `partitions` determines the Hive directory component order.\n * ES2015 guarantees string-keyed object insertion order is preserved by `Object.entries`.\n *\n * Examples:\n * { partitions: { ticker: 'SPX', date: '2025-01-06' } }\n * → baseDir/ticker=SPX/date=2025-01-06/data.parquet\n * { partitions: { underlying: 'SPX', date: '2025-01-06' } }\n * → baseDir/underlying=SPX/date=2025-01-06/data.parquet\n * { partitions: { ticker: 'VIX' } }\n * → baseDir/ticker=VIX/data.parquet\n * { partitions: {} }\n * → baseDir/data.parquet (callers that need this path should prefer writeParquetAtomic)\n */\nexport interface WriteParquetPartitionOptsV3 {\n baseDir: string;\n /** Key=value pairs composed in insertion order into Hive directory segments. */\n partitions: Record<string, string>;\n selectQuery: string;\n compression?: string;\n /** Defaults to 'data.parquet'. */\n filename?: string;\n provenance?: WriteParquetProvenanceOpts;\n}\n\n// Partition-value whitelist — deepest defense-in-depth boundary against path\n// traversal. Allows uppercase/lowercase alnum, dot, underscore, hyphen.\n// Rejects / \\ .. null whitespace and newlines. Zod schemas and the ticker\n// registry also validate upstream.\nconst PARTITION_VALUE_RE = /^[A-Za-z0-9._-]+$/;\n// Partition-key whitelist — keys become `key=` prefix in directory names.\n// Must start with letter or underscore (no leading digit), then alnum/underscore.\nconst PARTITION_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\n/**\n * Write a single Hive partition to the correct directory layout.\n *\n * Two supported shapes (via TypeScript overloads):\n * 1. Generic multi-level:\n * writeParquetPartition(conn, { baseDir, partitions: {ticker,date}, selectQuery })\n * → baseDir/ticker=X/date=Y/data.parquet\n * 2. Legacy single-{date} shim (retained for existing callers):\n * writeParquetPartition(conn, { baseDir, date, selectQuery })\n * → baseDir/date=Y/data.parquet (byte-identical to historical behavior)\n *\n * Overwrites existing partition file (idempotent — safe to re-run).\n *\n * Security: partition keys and values are validated against strict whitelists\n * BEFORE any filesystem operation. Unsafe input throws immediately.\n *\n * @param conn - Active DuckDB connection\n * @param opts - Partition write options (either shape)\n * @returns Object with rowCount of written rows\n */\n// Overload: generic multi-level signature\nexport function writeParquetPartition(\n conn: DuckDBConnection,\n opts: WriteParquetPartitionOptsV3,\n): Promise<ParquetWriteResult>;\n// Overload: legacy single-{date} signature\nexport function writeParquetPartition(\n conn: DuckDBConnection,\n opts: WriteParquetPartitionOpts,\n): Promise<ParquetWriteResult>;\n// Implementation\nexport async function writeParquetPartition(\n conn: DuckDBConnection,\n opts: WriteParquetPartitionOpts | WriteParquetPartitionOptsV3,\n): Promise<ParquetWriteResult> {\n // Runtime dispatch — this boolean is load-bearing.\n // The legacy shape has `date` but no `partitions`; the generic shape has `partitions`.\n const isLegacy = \"date\" in opts && !(\"partitions\" in opts);\n const partitions: Record<string, string> = isLegacy\n ? { date: (opts as WriteParquetPartitionOpts).date }\n : (opts as WriteParquetPartitionOptsV3).partitions;\n const filename = isLegacy\n ? \"data.parquet\"\n : ((opts as WriteParquetPartitionOptsV3).filename ?? \"data.parquet\");\n\n // Path-traversal mitigation: whitelist every partition key and value BEFORE\n // composing any path. Reject unsafe input (separators, whitespace, nulls).\n for (const [k, v] of Object.entries(partitions)) {\n if (!PARTITION_KEY_RE.test(k)) {\n throw new Error(`writeParquetPartition: unsafe partition key: ${JSON.stringify(k)}`);\n }\n if (!PARTITION_VALUE_RE.test(v)) {\n throw new Error(\n `writeParquetPartition: unsafe partition value for ${k}: ${JSON.stringify(v)}`,\n );\n }\n }\n\n // Preserve insertion order (ES2015 guarantees for string keys).\n const partitionSegments = Object.entries(partitions).map(([k, v]) => `${k}=${v}`);\n const targetPath = path.join(opts.baseDir, ...partitionSegments, filename);\n\n // writeParquetAtomic (existing, unchanged) handles: staging table → mkdir -p\n // (arbitrary depth) → COPY TO → rowCount → cleanup in finally.\n return writeParquetAtomic(conn, {\n targetPath,\n selectQuery: opts.selectQuery,\n compression: opts.compression,\n provenance: opts.provenance,\n });\n}\n","/**\n * Zod schemas for the ticker registry.\n *\n * Applied at three trust boundaries (defense in depth per RESEARCH.md Pitfall 3):\n * 1. MCP tool input boundary (schemas exported here, consumed by src/tools/tickers.ts in Plan 05)\n * 2. Registry constructor / register (registry.ts applies the same regex)\n * 3. Writer partition-value whitelist (src/db/parquet-writer.ts — Plan 03)\n */\nimport { z } from \"zod\";\n\n/**\n * Whitelist for ticker-like strings. Must START with an uppercase letter\n * (forbids \"..\" and other digit/punctuation-only inputs from validating).\n *\n * Accepts after the leading letter: uppercase A-Z, digits 0-9, and `^ _ -`\n * which appear in a handful of real-world option roots and continuous-futures\n * symbols. Forbids `.` (and therefore `..`), `/`, `\\`, whitespace, null bytes,\n * newlines, and any other non-filesystem-safe characters.\n */\nexport const TICKER_RE = /^[A-Z][A-Z0-9^_-]*$/;\n\nexport const UnderlyingsFileSchema = z.object({\n version: z.literal(1),\n underlyings: z.array(\n z.object({\n underlying: z.string().min(1).max(16).regex(TICKER_RE),\n roots: z.array(z.string().min(1).max(16).regex(TICKER_RE)).min(1).max(32),\n }),\n ),\n});\n\n// MCP tool input schemas (consumed by src/tools/tickers.ts in Plan 05).\nexport const registerUnderlyingSchema = z.object({\n underlying: z\n .string()\n .min(1)\n .max(16)\n .regex(TICKER_RE)\n .describe(\"Canonical underlying symbol, e.g. SPX\"),\n roots: z\n .array(z.string().min(1).max(16).regex(TICKER_RE))\n .min(1)\n .max(32)\n .describe(\"OCC roots that resolve to this underlying, e.g. ['SPX','SPXW','SPXQ']\"),\n});\n\nexport const unregisterUnderlyingSchema = z.object({\n underlying: z\n .string()\n .min(1)\n .max(16)\n .regex(TICKER_RE)\n .describe(\"Underlying to remove. Bundled defaults cannot be removed.\"),\n});\n\nexport const listUnderlyingsSchema = z.object({});\n\nexport const resolveRootSchema = z.object({\n input: z\n .string()\n .min(1)\n .max(32)\n .describe(\"Bare root ('SPXW') or full OCC ticker ('SPXW251219C05000000')\"),\n});\n","import type { DuckDBConnection } from \"@duckdb/node-api\";\nimport { constants } from \"node:fs\";\nimport * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { canonicalJson, type CanonicalJsonAddress, type Sha256Address } from \"./canonical-json.ts\";\nimport type { ContentObjectStore, PutContentObjectResult } from \"./content-object-store.ts\";\nimport {\n type CutoffManifestV1,\n type InputClosureObservationV1,\n type InputResolverRegistryV1,\n type ManifestInputResolver,\n type ManifestLeafReferenceV1,\n type ManifestResolution,\n type MaterializedResolverClassV1,\n type PartitionedResolverClassV1,\n proveCutoffManifestPrefix,\n publishCutoffManifest,\n publishInputResolverRegistry,\n publishMissingProbeEvidence,\n publishSemanticInputLeaf,\n restrictInputClosureDescriptor,\n verifyCutoffManifest,\n verifyInputClosure,\n verifyInputResolverRegistry,\n verifySemanticInputLeaf,\n} from \"./content-manifest.ts\";\nimport {\n MARKET_DATASETS,\n isRealMarketSessionDate,\n type BoundedMarketDatasetDefinition,\n} from \"./dataset-registry.ts\";\nimport {\n FilePartitionCommitStore,\n INTERNAL_HISTORICAL_PARTITION_ADOPTION,\n type StoredPartitionCommit,\n} from \"./partition-commit-store.ts\";\nimport {\n XNYS_SESSION_CALENDAR_REVISION,\n enumerateXnysSessions,\n isXnysSessionDate,\n} from \"./xnys-session-calendar.ts\";\nimport { verifyCanonicalRefreshCompletion } from \"./refresh-completion.ts\";\nimport { publishCanonicalRateSlice, type CanonicalRateDataClass } from \"./rate-slices.ts\";\n\nexport const CANONICAL_MARKET_RESOLVER_REVISION = \"tradeblocks-market-resolver-v1\" as const;\nexport const BLACKOUT_SLICE_KIND = \"tradeblocks.market-data.blackout-slice\" as const;\nexport const BLACKOUT_SLICE_VERSION = 1 as const;\n\nexport interface CanonicalControlIdentity {\n dataClass: string;\n role: string;\n relativePath: string;\n}\n\nexport interface PublishCanonicalMarketRegistryInput {\n /** Engine-observed data-root-relative control paths. */\n controlFiles?: readonly string[];\n}\n\nexport interface AdoptCanonicalHistoricalClosureResult {\n readonly closure: CanonicalJsonAddress;\n readonly completeThrough: string;\n readonly receipts: readonly StoredPartitionCommit[];\n}\n\nfunction compareCodePoints(left: string, right: string): number {\n const leftPoints = Array.from(left, (character) => character.codePointAt(0) as number);\n const rightPoints = Array.from(right, (character) => character.codePointAt(0) as number);\n const length = Math.min(leftPoints.length, rightPoints.length);\n for (let index = 0; index < length; index += 1) {\n if (leftPoints[index] !== rightPoints[index]) return leftPoints[index] - rightPoints[index];\n }\n return leftPoints.length - rightPoints.length;\n}\n\nexport function canonicalControlIdentity(relativePath: string): CanonicalControlIdentity {\n const normalized = relativePath.normalize(\"NFC\").replaceAll(\"\\\\\", \"/\");\n const match = /^blackouts\\/([A-Za-z_][A-Za-z0-9._-]*)\\.json$/.exec(normalized);\n if (!match) {\n throw new TypeError(\n `Unsupported canonical market control path: ${JSON.stringify(relativePath)}`,\n );\n }\n const role = `blackout.${match[1]}`;\n return Object.freeze({ dataClass: role, role, relativePath: normalized });\n}\n\nfunction canonicalPartitionedClasses(): PartitionedResolverClassV1[] {\n return Object.entries(MARKET_DATASETS).flatMap(([dataset, candidate]) => {\n if (candidate.provenance.kind !== \"bounded-session\") return [];\n const definition = candidate as BoundedMarketDatasetDefinition;\n return [\n {\n kind: \"partitioned\" as const,\n dataClass: dataset,\n dataset,\n selectorKeys: definition.partitionKeys,\n sessionKey: definition.provenance.sessionKey,\n pathPrefix: definition.subdir,\n filename: definition.filename,\n supportedSchemaRevisions: [definition.schemaRevision],\n resolverRevision: CANONICAL_MARKET_RESOLVER_REVISION,\n calendarRevision: XNYS_SESSION_CALENDAR_REVISION,\n },\n ];\n });\n}\n\nfunction canonicalMaterializedClasses(): MaterializedResolverClassV1[] {\n return ([\"sofr_rates\", \"treasury_rates\"] as const).map((dataClass) => ({\n kind: \"materialized\",\n dataClass,\n selectorKeys: [\"date\"],\n sessionKey: \"date\",\n supportedSchemaRevisions: [1],\n resolverRevision: CANONICAL_MARKET_RESOLVER_REVISION,\n calendarRevision: XNYS_SESSION_CALENDAR_REVISION,\n }));\n}\n\nfunction canonicalRegistryClasses(controls: readonly CanonicalControlIdentity[]) {\n return [\n ...canonicalPartitionedClasses(),\n ...canonicalMaterializedClasses(),\n ...controls.map((control) => ({\n kind: \"static\" as const,\n ...control,\n supportedSchemaRevisions: [1],\n resolverRevision: CANONICAL_MARKET_RESOLVER_REVISION,\n })),\n ].sort((left, right) => {\n const byClass = compareCodePoints(left.dataClass, right.dataClass);\n return byClass === 0 ? compareCodePoints(left.kind, right.kind) : byClass;\n });\n}\n\nfunction validateCanonicalRegistry(registry: InputResolverRegistryV1): void {\n const controls = registry.classes\n .filter((entry) => entry.kind === \"static\")\n .map((entry) => canonicalControlIdentity(entry.relativePath))\n .sort((left, right) => compareCodePoints(left.dataClass, right.dataClass));\n const expectedRevision = `${CANONICAL_MARKET_RESOLVER_REVISION}.${XNYS_SESSION_CALENDAR_REVISION}`;\n if (\n registry.revision !== expectedRevision ||\n canonicalJson(registry.classes) !== canonicalJson(canonicalRegistryClasses(controls))\n ) {\n throw new Error(\"Input resolver registry is not the canonical producer registry\");\n }\n}\n\nexport async function publishCanonicalMarketResolverRegistry(\n objects: ContentObjectStore,\n input: PublishCanonicalMarketRegistryInput = {},\n): Promise<PutContentObjectResult<InputResolverRegistryV1>> {\n const controls = [\n ...new Map(\n (input.controlFiles ?? []).map((controlPath) => {\n const identity = canonicalControlIdentity(controlPath);\n return [identity.relativePath, identity] as const;\n }),\n ).values(),\n ].sort((left, right) => compareCodePoints(left.dataClass, right.dataClass));\n return publishInputResolverRegistry(objects, {\n revision: `${CANONICAL_MARKET_RESOLVER_REVISION}.${XNYS_SESSION_CALENDAR_REVISION}`,\n classes: canonicalRegistryClasses(controls),\n });\n}\n\n/**\n * Bring existing canonical-layout Parquet bytes under producer authority for\n * one authenticated input closure. The caller cannot nominate arbitrary files:\n * identities are derived only from the verified canonical registry + closure,\n * and the store independently validates schema, partition values, coverage,\n * row count, inode stability, and exact bytes before publishing each receipt.\n *\n * This is the bounded migration seam for data that predates receipt stamping.\n * It deliberately does not mint refresh-completion authority or a cutoff; a\n * normal canonical refresh must still finalize the requested tail session.\n */\nexport async function adoptCanonicalHistoricalInputClosure(\n partitions: FilePartitionCommitStore,\n conn: DuckDBConnection,\n closureAddress: CanonicalJsonAddress,\n completeThrough: string,\n): Promise<AdoptCanonicalHistoricalClosureResult> {\n if (!isXnysSessionDate(completeThrough)) {\n throw new Error(\n `Historical adoption cutoff is not a supported XNYS session: ${completeThrough}`,\n );\n }\n const verifiedClosure = await verifyInputClosure(partitions.objects, closureAddress);\n const registryObject = await verifyInputResolverRegistry(\n partitions.objects,\n verifiedClosure.value.registry,\n );\n validateCanonicalRegistry(registryObject.value);\n const closure = restrictInputClosureDescriptor(verifiedClosure.value, completeThrough);\n const identities = new Map<string, { dataset: string; partition: Record<string, string> }>();\n\n for (const observation of closure.observations) {\n if (observation.kind === \"unmanifestable\") {\n throw new Error(`Historical adoption closure is unmanifestable: ${observation.reasonCode}`);\n }\n if (observation.kind === \"control-file\") continue;\n if (\n (observation.kind === \"exact\" || observation.kind === \"missing-probe\") &&\n !isXnysSessionDate(observation.session)\n ) {\n throw new Error(\n `Historical adoption ${observation.kind} is not an XNYS session: ${observation.session}`,\n );\n }\n if (observation.kind === \"missing-probe\") {\n const resolverClass = registryObject.value.classes.find(\n (entry) => entry.dataClass === observation.dataClass,\n );\n if (!resolverClass || resolverClass.kind !== \"partitioned\") {\n throw new Error(\"Historical adoption missing-probe is not partition-backed\");\n }\n const inspected = await partitions.inspectPartition({\n dataset: resolverClass.dataset,\n partition: observation.selector,\n });\n if (inspected.status !== \"absent\") {\n throw new Error(\n `Historical adoption missing-probe is no longer absent: ${resolverClass.dataset} ${canonicalJson(observation.selector)} (${inspected.status})`,\n );\n }\n continue;\n }\n const resolverClass = requireCanonicalClass(registryObject.value, observation);\n if (resolverClass.kind !== \"partitioned\") continue;\n const sessions =\n observation.kind === \"exact\"\n ? [sessionFromObservation(observation) as string]\n : enumerateXnysSessions(observation.fromSession, observation.throughSession);\n for (const session of sessions) {\n const partition =\n observation.kind === \"exact\"\n ? { ...observation.selector }\n : { ...observation.selectorPrefix, [resolverClass.sessionKey]: session };\n const identity = { dataset: resolverClass.dataset, partition };\n identities.set(canonicalJson(identity), identity);\n }\n }\n\n const receipts: StoredPartitionCommit[] = [];\n for (const identity of [...identities.values()].sort((left, right) =>\n compareCodePoints(canonicalJson(left), canonicalJson(right)),\n )) {\n receipts.push(await partitions[INTERNAL_HISTORICAL_PARTITION_ADOPTION](conn, identity));\n }\n return Object.freeze({\n closure: verifiedClosure.address,\n completeThrough,\n receipts: Object.freeze(receipts),\n });\n}\n\nfunction requireCanonicalClass(\n registry: InputResolverRegistryV1,\n observation: Exclude<InputClosureObservationV1, { kind: \"unmanifestable\" }>,\n) {\n const resolverClass = registry.classes.find((entry) => entry.dataClass === observation.dataClass);\n if (!resolverClass) throw new Error(`Unknown canonical input class ${observation.dataClass}`);\n if (resolverClass.resolverRevision !== CANONICAL_MARKET_RESOLVER_REVISION) {\n throw new Error(`Unsupported resolver revision for ${observation.dataClass}`);\n }\n if (\n resolverClass.kind !== \"static\" &&\n resolverClass.calendarRevision !== XNYS_SESSION_CALENDAR_REVISION\n ) {\n throw new Error(`Unsupported calendar revision for ${observation.dataClass}`);\n }\n return resolverClass;\n}\n\nfunction partitionLeafReference(\n leaf: CanonicalJsonAddress,\n receipt: CanonicalJsonAddress,\n): ManifestLeafReferenceV1 {\n return { leaf, evidence: { kind: \"partition-receipt\", receipt } };\n}\n\nfunction sessionFromObservation(observation: InputClosureObservationV1): string | undefined {\n return observation.kind === \"exact\" || observation.kind === \"missing-probe\"\n ? observation.session\n : undefined;\n}\n\nasync function readCanonicalBlackoutSlice(\n objects: ContentObjectStore,\n dataRootDir: string,\n identity: CanonicalControlIdentity,\n completeThrough: string,\n) {\n const root = await fs.realpath(path.resolve(dataRootDir));\n const components = identity.relativePath.split(\"/\");\n let parent = root;\n for (const component of components.slice(0, -1)) {\n parent = path.join(parent, component);\n const stat = await fs.lstat(parent);\n if (!stat.isDirectory() || stat.isSymbolicLink()) {\n throw new Error(\"Canonical control parents must be real directories\");\n }\n }\n const realParent = await fs.realpath(parent);\n const containment = path.relative(root, realParent);\n if (\n containment === \"..\" ||\n containment.startsWith(`..${path.sep}`) ||\n path.isAbsolute(containment)\n ) {\n throw new Error(\"Canonical control path escapes the configured data root\");\n }\n const candidate = path.join(parent, components.at(-1) as string);\n const handle = await fs.open(\n candidate,\n constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK,\n );\n try {\n const before = await handle.stat({ bigint: true });\n if (!before.isFile() || before.nlink !== 1n) {\n throw new Error(\"Canonical control input must be a singly-linked regular file\");\n }\n const bytes = await handle.readFile();\n const after = await handle.stat({ bigint: true });\n if (\n !after.isFile() ||\n after.nlink !== 1n ||\n before.dev !== after.dev ||\n before.ino !== after.ino ||\n before.size !== after.size ||\n before.mtimeNs !== after.mtimeNs ||\n before.ctimeNs !== after.ctimeNs\n ) {\n throw new Error(\"Canonical control input changed while it was read\");\n }\n let revalidatedParent = root;\n for (const component of components.slice(0, -1)) {\n revalidatedParent = path.join(revalidatedParent, component);\n const stat = await fs.lstat(revalidatedParent);\n if (!stat.isDirectory() || stat.isSymbolicLink()) {\n throw new Error(\"Canonical control parent changed while it was read\");\n }\n }\n if ((await fs.realpath(revalidatedParent)) !== realParent) {\n throw new Error(\"Canonical control parent changed while it was read\");\n }\n const named = await fs.lstat(candidate, { bigint: true });\n if (\n !named.isFile() ||\n named.isSymbolicLink() ||\n named.nlink !== 1n ||\n named.dev !== after.dev ||\n named.ino !== after.ino ||\n named.size !== after.size ||\n named.mtimeNs !== after.mtimeNs ||\n named.ctimeNs !== after.ctimeNs\n ) {\n throw new Error(\"Canonical control input name changed while it was read\");\n }\n const parsed = JSON.parse(bytes.toString(\"utf8\")) as unknown;\n const dates = Array.isArray(parsed)\n ? parsed\n : parsed !== null && typeof parsed === \"object\" && !Array.isArray(parsed)\n ? (parsed as { dates?: unknown }).dates\n : undefined;\n if (!Array.isArray(dates)) throw new Error(\"Blackout control input has no dates array\");\n const normalized = dates.map((date, index) => {\n if (typeof date !== \"string\" || !isRealMarketSessionDate(date)) {\n throw new Error(`Blackout control date ${index} is invalid`);\n }\n return date.normalize(\"NFC\");\n });\n normalized.sort(compareCodePoints);\n const unique = normalized.filter(\n (date, index) => date <= completeThrough && (index === 0 || date !== normalized[index - 1]),\n );\n return objects.put({\n kind: BLACKOUT_SLICE_KIND,\n version: BLACKOUT_SLICE_VERSION,\n role: identity.role,\n dates: unique,\n });\n } finally {\n await handle.close();\n }\n}\n\nfunction normalizeBlackoutSlice(\n value: unknown,\n expectedRole: string,\n completeThrough: string,\n): {\n kind: typeof BLACKOUT_SLICE_KIND;\n version: typeof BLACKOUT_SLICE_VERSION;\n role: string;\n dates: string[];\n} {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n throw new Error(\"Blackout slice must be an object\");\n }\n const record = value as Record<string, unknown>;\n const keys = Object.keys(record).sort(compareCodePoints);\n if (canonicalJson(keys) !== canonicalJson([\"dates\", \"kind\", \"role\", \"version\"])) {\n throw new Error(\"Blackout slice has unknown or missing fields\");\n }\n if (\n record.kind !== BLACKOUT_SLICE_KIND ||\n record.version !== BLACKOUT_SLICE_VERSION ||\n record.role !== expectedRole ||\n !Array.isArray(record.dates)\n ) {\n throw new Error(\"Blackout slice identity is invalid\");\n }\n const dates = record.dates.map((date, index) => {\n if (typeof date !== \"string\" || !isRealMarketSessionDate(date) || date > completeThrough) {\n throw new Error(`Blackout slice date ${index} is invalid`);\n }\n return date.normalize(\"NFC\");\n });\n const sorted = [...dates].sort(compareCodePoints);\n if (canonicalJson(dates) !== canonicalJson(sorted) || new Set(dates).size !== dates.length) {\n throw new Error(\"Blackout slice dates are not normalized\");\n }\n return {\n kind: BLACKOUT_SLICE_KIND,\n version: BLACKOUT_SLICE_VERSION,\n role: expectedRole,\n dates,\n };\n}\n\n/**\n * Producer-owned resolver for the bounded market registry.\n *\n * Range completeness comes from XNYS session enumeration, never from the set\n * of files that happen to exist. Every expected partition must have a current\n * exact-byte authority tip before the resolver reports a complete horizon.\n */\nexport class CanonicalMarketInputResolver implements ManifestInputResolver {\n readonly dataRootDir: string;\n readonly partitions: FilePartitionCommitStore;\n\n constructor(partitions: FilePartitionCommitStore) {\n this.partitions = partitions;\n const marketRoot = path.resolve(partitions.marketRootDir);\n if (path.basename(marketRoot) !== \"market\") {\n throw new Error(\"Canonical market resolver requires a data-root/market authority store\");\n }\n this.dataRootDir = path.dirname(marketRoot);\n }\n\n private async resolvePartition(\n registryAddress: CanonicalJsonAddress,\n observation: Exclude<\n InputClosureObservationV1,\n { kind: \"control-file\" | \"unmanifestable\" | \"missing-probe\" }\n >,\n resolverClass: PartitionedResolverClassV1,\n partition: Record<string, string>,\n ): Promise<ManifestLeafReferenceV1> {\n const inspected = await this.partitions.inspectPartition({\n dataset: resolverClass.dataset,\n partition,\n });\n if (inspected.status !== \"match\") {\n throw new Error(\n `Canonical partition is not complete/current: ${resolverClass.dataset} ${JSON.stringify(partition)} (${inspected.status})`,\n );\n }\n const receipt = inspected.receipt.receipt;\n const session = partition[resolverClass.sessionKey];\n if (\n !resolverClass.supportedSchemaRevisions.includes(receipt.schemaRevision) ||\n receipt.file.rows <= 0 ||\n receipt.coverage.kind !== \"date-range\" ||\n receipt.coverage.from !== session ||\n receipt.coverage.through !== session ||\n receipt.quality.writtenRows !== receipt.file.rows ||\n receipt.quality.inputRows !== receipt.file.rows ||\n receipt.quality.droppedRows !== 0\n ) {\n throw new Error(\n `Canonical partition is not a complete zero-drop cutoff partition: ${resolverClass.dataset} ${JSON.stringify(partition)}`,\n );\n }\n const leaf = await publishSemanticInputLeaf(this.partitions.objects, {\n registry: registryAddress,\n observation,\n source: {\n kind: \"partition-projection\",\n dataset: receipt.dataset,\n partition: receipt.partition,\n relativePath: receipt.relativePath,\n session,\n schemaRevision: receipt.schemaRevision,\n coverage: receipt.coverage,\n quality: receipt.quality,\n file: receipt.file,\n },\n });\n return partitionLeafReference(leaf.address, inspected.receipt.address);\n }\n\n private async resolveMaterializedRate(\n registryAddress: CanonicalJsonAddress,\n observation: Extract<InputClosureObservationV1, { kind: \"exact\" | \"range\" }>,\n resolverClass: MaterializedResolverClassV1,\n selector: Record<string, string>,\n ): Promise<ManifestLeafReferenceV1> {\n const session = selector[resolverClass.sessionKey];\n const object = await publishCanonicalRateSlice(\n this.partitions.objects,\n resolverClass.dataClass as CanonicalRateDataClass,\n session,\n );\n const leaf = await publishSemanticInputLeaf(this.partitions.objects, {\n registry: registryAddress,\n observation,\n source: {\n kind: \"materialized-slice\",\n selector,\n session,\n schemaRevision: 1,\n object: { address: object.address, bytes: object.bytes },\n },\n });\n return {\n leaf: leaf.address,\n evidence: { kind: \"content-object\", object: object.address },\n };\n }\n\n async resolve(input: {\n registry: InputResolverRegistryV1;\n closure: import(\"./content-manifest.ts\").InputClosureDescriptorV1;\n observation: InputClosureObservationV1;\n dependency: CanonicalJsonAddress;\n completeThrough: string;\n }): Promise<ManifestResolution> {\n const { registry, observation, completeThrough } = input;\n if (observation.kind === \"unmanifestable\") {\n return { kind: \"unmanifestable\", reasonCode: observation.reasonCode };\n }\n try {\n validateCanonicalRegistry(registry);\n if (!isXnysSessionDate(completeThrough)) {\n return { kind: \"unresolved\", reasonCode: \"cutoff-not-xnys-session\" };\n }\n const resolverClass = requireCanonicalClass(registry, observation);\n if (observation.kind === \"control-file\") {\n if (resolverClass.kind !== \"static\") {\n return { kind: \"unmanifestable\", reasonCode: \"control-class-not-static\" };\n }\n const identity = canonicalControlIdentity(resolverClass.relativePath);\n if (identity.role !== observation.role || identity.role !== resolverClass.role) {\n return { kind: \"unmanifestable\", reasonCode: \"control-identity-mismatch\" };\n }\n const object = await readCanonicalBlackoutSlice(\n this.partitions.objects,\n this.dataRootDir,\n identity,\n completeThrough,\n );\n const leaf = await publishSemanticInputLeaf(this.partitions.objects, {\n registry: input.closure.registry,\n observation,\n source: {\n kind: \"control-file\",\n role: identity.role,\n relativePath: identity.relativePath,\n schemaRevision: 1,\n object: { address: object.address, bytes: object.bytes },\n },\n });\n return {\n kind: \"resolved\",\n completeThrough,\n entries: [\n {\n leaf: leaf.address,\n evidence: { kind: \"content-object\", object: object.address },\n },\n ],\n };\n }\n if (resolverClass.kind === \"static\") {\n return { kind: \"unmanifestable\", reasonCode: \"session-observation-class-is-static\" };\n }\n if (observation.kind === \"missing-probe\") {\n if (resolverClass.kind !== \"partitioned\") {\n return { kind: \"unmanifestable\", reasonCode: \"probe-class-not-partitioned\" };\n }\n if (!isXnysSessionDate(observation.session)) {\n return { kind: \"unmanifestable\", reasonCode: \"probe-not-xnys-session\" };\n }\n const inspected = await this.partitions.inspectPartition({\n dataset: resolverClass.dataset,\n partition: observation.selector,\n });\n if (inspected.status !== \"absent\") {\n return { kind: \"unresolved\", reasonCode: `probe-${inspected.status}` };\n }\n const evidence = await publishMissingProbeEvidence(this.partitions.objects, {\n registry: input.closure.registry,\n observation,\n completeThrough,\n });\n const leaf = await publishSemanticInputLeaf(this.partitions.objects, {\n registry: input.closure.registry,\n observation,\n source: { kind: \"missing-probe\", session: observation.session },\n });\n return {\n kind: \"resolved\",\n completeThrough,\n entries: [\n {\n leaf: leaf.address,\n evidence: { kind: \"absence-object\", object: evidence.address },\n },\n ],\n };\n }\n const sessions =\n observation.kind === \"exact\"\n ? [sessionFromObservation(observation) as string]\n : enumerateXnysSessions(observation.fromSession, observation.throughSession);\n if (sessions.length === 0) {\n return { kind: \"unresolved\", reasonCode: \"range-has-no-xnys-sessions\" };\n }\n const entries: ManifestLeafReferenceV1[] = [];\n for (const session of sessions) {\n if (!isXnysSessionDate(session)) {\n return { kind: \"unmanifestable\", reasonCode: \"exact-not-xnys-session\" };\n }\n const partition =\n observation.kind === \"exact\"\n ? observation.selector\n : { ...observation.selectorPrefix, [resolverClass.sessionKey]: session };\n entries.push(\n resolverClass.kind === \"partitioned\"\n ? await this.resolvePartition(\n input.closure.registry,\n observation,\n resolverClass,\n partition,\n )\n : await this.resolveMaterializedRate(\n input.closure.registry,\n observation,\n resolverClass,\n partition,\n ),\n );\n }\n return { kind: \"resolved\", completeThrough, entries };\n } catch (error) {\n return {\n kind: \"unresolved\",\n reasonCode: error instanceof Error ? error.message : \"canonical-resolution-failed\",\n };\n }\n }\n\n async projectStaticPrefix(input: {\n registry: InputResolverRegistryV1;\n registryAddress: CanonicalJsonAddress;\n dataClass: string;\n ancestorCompleteThrough: string;\n descendantCompleteThrough: string;\n descendantEntries: readonly ManifestLeafReferenceV1[];\n }): Promise<readonly ManifestLeafReferenceV1[]> {\n validateCanonicalRegistry(input.registry);\n const resolverClass = input.registry.classes.find(\n (entry) => entry.dataClass === input.dataClass,\n );\n if (!resolverClass || resolverClass.kind !== \"static\") {\n throw new Error(\"Canonical static prefix projection requires a static registry class\");\n }\n if (input.descendantEntries.length !== 1) {\n throw new Error(\"Canonical static prefix projection requires exactly one descendant leaf\");\n }\n const reference = input.descendantEntries[0];\n const leaf = await verifySemanticInputLeaf(this.partitions.objects, reference.leaf);\n if (\n leaf.value.registry !== input.registryAddress ||\n leaf.value.dataClass !== input.dataClass ||\n leaf.value.scope.kind !== \"static\" ||\n leaf.value.source.kind !== \"control-file\" ||\n reference.evidence.kind !== \"content-object\" ||\n reference.evidence.object !== leaf.value.source.object.address\n ) {\n throw new Error(\"Canonical static prefix projection received invalid descendant evidence\");\n }\n const descendantObject = await this.partitions.objects.get<unknown>(reference.evidence.object);\n const descendantSlice = normalizeBlackoutSlice(\n descendantObject,\n resolverClass.role,\n input.descendantCompleteThrough,\n );\n const projectedObject = await this.partitions.objects.put({\n ...descendantSlice,\n dates: descendantSlice.dates.filter((date) => date <= input.ancestorCompleteThrough),\n });\n const observation: InputClosureObservationV1 = {\n kind: \"control-file\",\n dataClass: input.dataClass,\n role: resolverClass.role,\n };\n const projectedLeaf = await publishSemanticInputLeaf(this.partitions.objects, {\n registry: input.registryAddress,\n observation,\n source: {\n ...leaf.value.source,\n object: { address: projectedObject.address, bytes: projectedObject.bytes },\n },\n });\n return [\n {\n leaf: projectedLeaf.address,\n evidence: { kind: \"content-object\", object: projectedObject.address },\n },\n ];\n }\n}\n\nexport async function finalizeCanonicalMarketDataCutoff(\n partitions: FilePartitionCommitStore,\n input: {\n closure: CanonicalJsonAddress;\n completeThrough: string;\n refreshCompletion: CanonicalJsonAddress;\n predecessor?: { manifest: CanonicalJsonAddress; aggregateRoot: Sha256Address };\n },\n): Promise<PutContentObjectResult<CutoffManifestV1>> {\n if (!isXnysSessionDate(input.completeThrough)) {\n throw new Error(`Canonical cutoff is not a supported XNYS session: ${input.completeThrough}`);\n }\n const completion = await verifyCanonicalRefreshCompletion(partitions, input.refreshCompletion);\n if (\n completion.value.plan.asOf !== input.completeThrough ||\n completion.value.closure !== input.closure\n ) {\n throw new Error(\"Canonical refresh completion does not authorize this closure and cutoff\");\n }\n const manifest = await publishCutoffManifest(partitions, {\n closure: input.closure,\n completeThrough: input.completeThrough,\n resolver: new CanonicalMarketInputResolver(partitions),\n refreshCompletion: completion.address,\n ...(input.predecessor ? { predecessor: input.predecessor } : {}),\n });\n await verifyCanonicalRefreshCompletion(partitions, completion.address);\n return manifest;\n}\n\nexport async function verifyCanonicalMarketDataCutoff(\n partitions: FilePartitionCommitStore,\n manifest: CanonicalJsonAddress,\n) {\n const verified = await verifyCutoffManifest(\n partitions,\n manifest,\n new CanonicalMarketInputResolver(partitions),\n );\n if (!verified.manifest.refreshCompletion) {\n throw new Error(\"Canonical cutoff manifest has no refresh completion authority\");\n }\n const completion = await verifyCanonicalRefreshCompletion(\n partitions,\n verified.manifest.refreshCompletion,\n );\n if (\n completion.value.plan.asOf !== verified.manifest.completeThrough ||\n completion.value.closure !== verified.manifest.closure\n ) {\n throw new Error(\"Canonical cutoff manifest refresh authority is inconsistent\");\n }\n return verified;\n}\n\nexport async function proveCanonicalMarketDataPrefix(\n partitions: FilePartitionCommitStore,\n ancestor: CanonicalJsonAddress,\n descendant: CanonicalJsonAddress,\n) {\n await verifyCanonicalMarketDataCutoff(partitions, ancestor);\n await verifyCanonicalMarketDataCutoff(partitions, descendant);\n const proof = await proveCutoffManifestPrefix(\n partitions,\n ancestor,\n descendant,\n new CanonicalMarketInputResolver(partitions),\n );\n await verifyCanonicalMarketDataCutoff(partitions, ancestor);\n await verifyCanonicalMarketDataCutoff(partitions, descendant);\n return proof;\n}\n","import {\n addressCanonicalJson,\n canonicalJson,\n canonicalJsonBytes,\n parseCanonicalJsonAddress,\n parseSha256Address,\n type CanonicalJsonAddress,\n type Sha256Address,\n} from \"./canonical-json.ts\";\nimport { ContentObjectStore, type PutContentObjectResult } from \"./content-object-store.ts\";\nimport {\n canonicalPartitionRelativePath,\n isRealMarketSessionDate,\n marketDatasetDefinition,\n} from \"./dataset-registry.ts\";\nimport type {\n ExactFileFingerprint,\n FilePartitionCommitStore,\n LogicalCoverage,\n PartitionQualityCounts,\n} from \"./partition-commit-store.ts\";\n\nexport const INPUT_RESOLVER_REGISTRY_KIND =\n \"tradeblocks.market-data.input-resolver-registry\" as const;\nexport const INPUT_RESOLVER_REGISTRY_VERSION = 1 as const;\nexport const INPUT_CLOSURE_DESCRIPTOR_KIND = \"tradeblocks.market-data.input-closure\" as const;\nexport const INPUT_CLOSURE_DESCRIPTOR_VERSION = 1 as const;\nexport const INPUT_DEPENDENCY_KEY_KIND = \"tradeblocks.market-data.input-dependency\" as const;\nexport const INPUT_DEPENDENCY_KEY_VERSION = 1 as const;\nexport const SEMANTIC_INPUT_LEAF_KIND = \"tradeblocks.market-data.semantic-input-leaf\" as const;\nexport const SEMANTIC_INPUT_LEAF_VERSION = 1 as const;\nexport const MISSING_PROBE_EVIDENCE_KIND =\n \"tradeblocks.market-data.missing-probe-evidence\" as const;\nexport const MISSING_PROBE_EVIDENCE_VERSION = 1 as const;\nexport const CUTOFF_MANIFEST_KIND = \"tradeblocks.market-data.cutoff-manifest\" as const;\nexport const CUTOFF_MANIFEST_VERSION = 1 as const;\n\nexport class ManifestVerificationError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"ManifestVerificationError\";\n }\n}\n\nexport interface PartitionedResolverClassV1 {\n kind: \"partitioned\";\n dataClass: string;\n dataset: string;\n selectorKeys: readonly string[];\n sessionKey: string;\n pathPrefix: string;\n filename: string;\n supportedSchemaRevisions: readonly number[];\n resolverRevision: string;\n calendarRevision: string;\n}\n\nexport interface StaticResolverClassV1 {\n kind: \"static\";\n dataClass: string;\n role: string;\n relativePath: string;\n supportedSchemaRevisions: readonly number[];\n resolverRevision: string;\n}\n\nexport interface MaterializedResolverClassV1 {\n kind: \"materialized\";\n dataClass: string;\n selectorKeys: readonly string[];\n sessionKey: string;\n supportedSchemaRevisions: readonly number[];\n resolverRevision: string;\n calendarRevision: string;\n}\n\nexport type InputResolverClassV1 =\n PartitionedResolverClassV1 | StaticResolverClassV1 | MaterializedResolverClassV1;\n\nexport interface InputResolverRegistryV1 {\n kind: typeof INPUT_RESOLVER_REGISTRY_KIND;\n version: typeof INPUT_RESOLVER_REGISTRY_VERSION;\n revision: string;\n classes: readonly InputResolverClassV1[];\n}\n\nexport type InputResolverRegistryInputV1 = Omit<InputResolverRegistryV1, \"kind\" | \"version\">;\n\nexport type InputClosureObservationV1 =\n | {\n kind: \"exact\";\n dataClass: string;\n selector: Record<string, string>;\n session: string;\n }\n | {\n kind: \"range\";\n dataClass: string;\n selectorPrefix: Record<string, string>;\n fromSession: string;\n throughSession: string;\n }\n | {\n kind: \"missing-probe\";\n dataClass: string;\n selector: Record<string, string>;\n session: string;\n }\n | { kind: \"control-file\"; dataClass: string; role: string }\n | { kind: \"unmanifestable\"; readClass: string; reasonCode: string };\n\nexport interface InputClosureDescriptorV1 {\n kind: typeof INPUT_CLOSURE_DESCRIPTOR_KIND;\n version: typeof INPUT_CLOSURE_DESCRIPTOR_VERSION;\n registry: CanonicalJsonAddress;\n observations: readonly InputClosureObservationV1[];\n}\n\nexport interface PartitionProjectionV1 {\n kind: \"partition-projection\";\n dataset: string;\n partition: Record<string, string>;\n relativePath: string;\n session: string;\n schemaRevision: number;\n coverage: LogicalCoverage;\n quality: PartitionQualityCounts;\n file: ExactFileFingerprint;\n}\n\nexport interface MaterializedSliceV1 {\n kind: \"materialized-slice\";\n selector: Record<string, string>;\n session: string;\n schemaRevision: number;\n object: { address: CanonicalJsonAddress; bytes: number };\n}\n\nexport interface ControlFileProjectionV1 {\n kind: \"control-file\";\n role: string;\n relativePath: string;\n schemaRevision: number;\n object: { address: CanonicalJsonAddress; bytes: number };\n}\n\nexport interface MissingProbeProjectionV1 {\n kind: \"missing-probe\";\n session: string;\n}\n\nexport type SemanticInputSourceV1 =\n PartitionProjectionV1 | MaterializedSliceV1 | ControlFileProjectionV1 | MissingProbeProjectionV1;\n\nexport interface SemanticInputLeafV1 {\n kind: typeof SEMANTIC_INPUT_LEAF_KIND;\n version: typeof SEMANTIC_INPUT_LEAF_VERSION;\n registry: CanonicalJsonAddress;\n dependency: CanonicalJsonAddress;\n dataClass: string;\n scope: { kind: \"session\"; session: string } | { kind: \"static\" };\n source: SemanticInputSourceV1;\n}\n\nexport interface MissingProbeEvidenceV1 {\n kind: typeof MISSING_PROBE_EVIDENCE_KIND;\n version: typeof MISSING_PROBE_EVIDENCE_VERSION;\n registry: CanonicalJsonAddress;\n dependency: CanonicalJsonAddress;\n completeThrough: string;\n}\n\nexport type ManifestLeafEvidenceV1 =\n | { kind: \"partition-receipt\"; receipt: CanonicalJsonAddress }\n | { kind: \"content-object\"; object: CanonicalJsonAddress }\n | { kind: \"absence-object\"; object: CanonicalJsonAddress };\n\nexport interface ManifestLeafReferenceV1 {\n leaf: CanonicalJsonAddress;\n evidence: ManifestLeafEvidenceV1;\n}\n\nexport interface ManifestClassV1 {\n dataClass: string;\n completeThrough: string;\n entries: readonly ManifestLeafReferenceV1[];\n leafCount: number;\n root: Sha256Address;\n}\n\nexport interface CutoffManifestV1 {\n kind: typeof CUTOFF_MANIFEST_KIND;\n version: typeof CUTOFF_MANIFEST_VERSION;\n closure: CanonicalJsonAddress;\n completeThrough: string;\n classes: readonly ManifestClassV1[];\n aggregateRoot: Sha256Address;\n refreshCompletion?: CanonicalJsonAddress;\n predecessor?: { manifest: CanonicalJsonAddress; aggregateRoot: Sha256Address };\n}\n\nexport type ManifestResolution =\n | {\n kind: \"resolved\";\n completeThrough: string;\n entries: readonly ManifestLeafReferenceV1[];\n }\n | { kind: \"unresolved\" | \"unmanifestable\"; reasonCode: string };\n\nexport interface ManifestInputResolver {\n resolve(input: {\n registry: InputResolverRegistryV1;\n closure: InputClosureDescriptorV1;\n observation: InputClosureObservationV1;\n dependency: CanonicalJsonAddress;\n completeThrough: string;\n }): Promise<ManifestResolution>;\n /**\n * Project immutable descendant static leaves back to an older cutoff.\n *\n * Partition/session leaves are always checked directly from the descendant\n * manifest. A static class may opt into cutoff projection only when its\n * producer can derive the older value from the descendant's immutable\n * content object; re-reading mutable live state is not a valid projection.\n */\n projectStaticPrefix?(input: {\n registry: InputResolverRegistryV1;\n registryAddress: CanonicalJsonAddress;\n dataClass: string;\n ancestorCompleteThrough: string;\n descendantCompleteThrough: string;\n descendantEntries: readonly ManifestLeafReferenceV1[];\n }): Promise<readonly ManifestLeafReferenceV1[]>;\n}\n\ntype JsonRecord = Record<string, unknown>;\n\nconst IDENTIFIER_RE = /^[A-Za-z_][A-Za-z0-9._-]*$/;\nconst SAFE_PATH_COMPONENT_RE = /^[A-Za-z0-9._=-]+$/;\nconst OBSERVATION_RANK: Readonly<Record<InputClosureObservationV1[\"kind\"], number>> = Object.freeze(\n {\n exact: 0,\n range: 1,\n \"missing-probe\": 2,\n \"control-file\": 3,\n unmanifestable: 4,\n },\n);\n\nexport function compareUnicodeCodePoints(left: string, right: string): number {\n const leftPoints = Array.from(left, (character) => character.codePointAt(0) as number);\n const rightPoints = Array.from(right, (character) => character.codePointAt(0) as number);\n const length = Math.min(leftPoints.length, rightPoints.length);\n for (let index = 0; index < length; index += 1) {\n if (leftPoints[index] !== rightPoints[index]) return leftPoints[index] - rightPoints[index];\n }\n return leftPoints.length - rightPoints.length;\n}\n\nfunction fail(message: string): never {\n throw new ManifestVerificationError(message);\n}\n\nfunction plainRecord(value: unknown, label: string): JsonRecord {\n if (\n value === null ||\n typeof value !== \"object\" ||\n Array.isArray(value) ||\n (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null)\n ) {\n fail(`${label} must be a plain object`);\n }\n return value as JsonRecord;\n}\n\nfunction exactKeys(record: JsonRecord, expected: readonly string[], label: string): void {\n const observed = Object.keys(record).sort(compareUnicodeCodePoints);\n const wanted = [...expected].sort(compareUnicodeCodePoints);\n if (observed.length !== wanted.length || observed.some((key, index) => key !== wanted[index])) {\n fail(`${label} has unknown or missing fields`);\n }\n for (const key of observed) {\n if (record[key] === null) fail(`${label}.${key} must use omission instead of null`);\n }\n}\n\nfunction nonemptyString(value: unknown, label: string): string {\n if (typeof value !== \"string\" || value.length === 0) fail(`${label} must be a non-empty string`);\n return value.normalize(\"NFC\");\n}\n\nfunction identifier(value: unknown, label: string): string {\n const normalized = nonemptyString(value, label);\n if (!IDENTIFIER_RE.test(normalized)) fail(`${label} is not a safe identifier`);\n return normalized;\n}\n\nfunction revision(value: unknown, label: string): string {\n const normalized = nonemptyString(value, label);\n if (!/^[A-Za-z0-9._-]+$/.test(normalized)) fail(`${label} is not a safe revision`);\n return normalized;\n}\n\nfunction sessionDate(value: unknown, label: string): string {\n const normalized = nonemptyString(value, label);\n if (!isRealMarketSessionDate(normalized)) fail(`${label} is not a valid session date`);\n return normalized;\n}\n\nfunction relativePath(value: unknown, label: string): string {\n const normalized = nonemptyString(value, label).replaceAll(\"\\\\\", \"/\");\n if (\n normalized.startsWith(\"/\") ||\n normalized.endsWith(\"/\") ||\n normalized\n .split(\"/\")\n .some((part) => !SAFE_PATH_COMPONENT_RE.test(part) || part === \".\" || part === \"..\")\n ) {\n fail(`${label} is not a safe relative path`);\n }\n return normalized;\n}\n\nfunction stringMap(value: unknown, label: string): Record<string, string> {\n const record = plainRecord(value, label);\n const normalized: Record<string, string> = {};\n const normalizedKeys = new Map<string, string>();\n for (const sourceKey of Object.keys(record)) {\n const key = identifier(sourceKey, `${label} key`);\n const collision = normalizedKeys.get(key);\n if (collision !== undefined && collision !== sourceKey) {\n fail(`${label} has an NFC-normalized key collision`);\n }\n normalizedKeys.set(key, sourceKey);\n normalized[key] = nonemptyString(record[sourceKey], `${label}.${sourceKey}`);\n }\n return Object.fromEntries(\n Object.entries(normalized).sort(([left], [right]) => compareUnicodeCodePoints(left, right)),\n );\n}\n\nfunction positiveSafeInteger(value: unknown, label: string): number {\n if (!Number.isSafeInteger(value) || (value as number) <= 0)\n fail(`${label} must be a positive safe integer`);\n return value as number;\n}\n\nfunction address(value: unknown, label: string): CanonicalJsonAddress {\n const normalized = nonemptyString(value, label);\n try {\n parseCanonicalJsonAddress(normalized);\n } catch (error) {\n throw new ManifestVerificationError(`${label} is not a canonical object address`, {\n cause: error,\n });\n }\n return normalized as CanonicalJsonAddress;\n}\n\nfunction snapshot<T>(value: unknown, label: string): T {\n try {\n return JSON.parse(canonicalJsonBytes(value).toString(\"utf8\")) as T;\n } catch (error) {\n throw new ManifestVerificationError(`${label} is not canonical JSON v1`, { cause: error });\n }\n}\n\nfunction rawStableJson(value: unknown): string {\n if (value === null || typeof value !== \"object\") return JSON.stringify(value);\n if (Array.isArray(value)) return `[${value.map(rawStableJson).join(\",\")}]`;\n const record = value as JsonRecord;\n return `{${Object.keys(record)\n .sort(compareUnicodeCodePoints)\n .map((key) => `${JSON.stringify(key)}:${rawStableJson(record[key])}`)\n .join(\",\")}}`;\n}\n\nfunction normalizeSchemaRevisions(value: unknown, label: string): readonly number[] {\n if (!Array.isArray(value) || value.length === 0) fail(`${label} must be a non-empty array`);\n const revisions = value.map((entry, index) => positiveSafeInteger(entry, `${label}[${index}]`));\n const sorted = [...revisions].sort((left, right) => left - right);\n if (sorted.some((entry, index) => index > 0 && entry === sorted[index - 1])) {\n fail(`${label} contains a duplicate revision`);\n }\n return sorted;\n}\n\nfunction normalizeSelectorKeys(value: unknown, label: string): readonly string[] {\n if (!Array.isArray(value) || value.length === 0) fail(`${label} must be a non-empty array`);\n const keys = value.map((entry, index) => identifier(entry, `${label}[${index}]`));\n if (new Set(keys).size !== keys.length) fail(`${label} contains a duplicate key`);\n return keys;\n}\n\nfunction normalizeRegistryClass(value: unknown, label: string): InputResolverClassV1 {\n const record = plainRecord(value, label);\n const kind = record.kind;\n if (kind === \"partitioned\") {\n exactKeys(\n record,\n [\n \"kind\",\n \"dataClass\",\n \"dataset\",\n \"selectorKeys\",\n \"sessionKey\",\n \"pathPrefix\",\n \"filename\",\n \"supportedSchemaRevisions\",\n \"resolverRevision\",\n \"calendarRevision\",\n ],\n label,\n );\n const dataClass = identifier(record.dataClass, `${label}.dataClass`);\n const dataset = identifier(record.dataset, `${label}.dataset`);\n const selectorKeys = normalizeSelectorKeys(record.selectorKeys, `${label}.selectorKeys`);\n const sessionKey = identifier(record.sessionKey, `${label}.sessionKey`);\n const pathPrefix = relativePath(record.pathPrefix, `${label}.pathPrefix`);\n const filename = relativePath(record.filename, `${label}.filename`);\n if (filename.includes(\"/\")) fail(`${label}.filename must be one path component`);\n const supportedSchemaRevisions = normalizeSchemaRevisions(\n record.supportedSchemaRevisions,\n `${label}.supportedSchemaRevisions`,\n );\n const resolverRevision = revision(record.resolverRevision, `${label}.resolverRevision`);\n const calendarRevision = revision(record.calendarRevision, `${label}.calendarRevision`);\n const shared = marketDatasetDefinition(dataset);\n if (!shared || shared.provenance.kind !== \"bounded-session\") {\n fail(`${label} references an unsupported or unbounded dataset`);\n }\n if (\n dataClass !== dataset ||\n canonicalJson(selectorKeys) !== canonicalJson(shared.partitionKeys) ||\n sessionKey !== shared.provenance.sessionKey ||\n pathPrefix !== shared.subdir ||\n filename !== shared.filename ||\n canonicalJson(supportedSchemaRevisions) !== canonicalJson([shared.schemaRevision])\n ) {\n fail(`${label} disagrees with the canonical dataset registry`);\n }\n return {\n kind,\n dataClass,\n dataset,\n selectorKeys,\n sessionKey,\n pathPrefix,\n filename,\n supportedSchemaRevisions,\n resolverRevision,\n calendarRevision,\n };\n }\n if (kind === \"static\") {\n exactKeys(\n record,\n [\"kind\", \"dataClass\", \"role\", \"relativePath\", \"supportedSchemaRevisions\", \"resolverRevision\"],\n label,\n );\n return {\n kind,\n dataClass: identifier(record.dataClass, `${label}.dataClass`),\n role: identifier(record.role, `${label}.role`),\n relativePath: relativePath(record.relativePath, `${label}.relativePath`),\n supportedSchemaRevisions: normalizeSchemaRevisions(\n record.supportedSchemaRevisions,\n `${label}.supportedSchemaRevisions`,\n ),\n resolverRevision: revision(record.resolverRevision, `${label}.resolverRevision`),\n };\n }\n if (kind === \"materialized\") {\n exactKeys(\n record,\n [\n \"kind\",\n \"dataClass\",\n \"selectorKeys\",\n \"sessionKey\",\n \"supportedSchemaRevisions\",\n \"resolverRevision\",\n \"calendarRevision\",\n ],\n label,\n );\n const selectorKeys = normalizeSelectorKeys(record.selectorKeys, `${label}.selectorKeys`);\n const sessionKey = identifier(record.sessionKey, `${label}.sessionKey`);\n if (!selectorKeys.includes(sessionKey)) {\n fail(`${label}.sessionKey is not one of its selector keys`);\n }\n return {\n kind,\n dataClass: identifier(record.dataClass, `${label}.dataClass`),\n selectorKeys,\n sessionKey,\n supportedSchemaRevisions: normalizeSchemaRevisions(\n record.supportedSchemaRevisions,\n `${label}.supportedSchemaRevisions`,\n ),\n resolverRevision: revision(record.resolverRevision, `${label}.resolverRevision`),\n calendarRevision: revision(record.calendarRevision, `${label}.calendarRevision`),\n };\n }\n fail(`${label}.kind is unsupported`);\n}\n\nfunction normalizeRegistry(value: unknown): InputResolverRegistryV1 {\n const captured = snapshot<unknown>(value, \"input resolver registry\");\n const record = plainRecord(captured, \"input resolver registry\");\n exactKeys(record, [\"kind\", \"version\", \"revision\", \"classes\"], \"input resolver registry\");\n if (record.kind !== INPUT_RESOLVER_REGISTRY_KIND) fail(\"input resolver registry kind is invalid\");\n if (record.version !== INPUT_RESOLVER_REGISTRY_VERSION) {\n fail(\"input resolver registry version is unsupported\");\n }\n if (!Array.isArray(record.classes) || record.classes.length === 0) {\n fail(\"input resolver registry classes must be a non-empty array\");\n }\n const classes = record.classes.map((entry, index) =>\n normalizeRegistryClass(entry, `input resolver registry classes[${index}]`),\n );\n classes.sort((left, right) => {\n const byClass = compareUnicodeCodePoints(left.dataClass, right.dataClass);\n return byClass === 0 ? compareUnicodeCodePoints(left.kind, right.kind) : byClass;\n });\n for (let index = 1; index < classes.length; index += 1) {\n if (classes[index - 1].dataClass === classes[index].dataClass) {\n fail(\n `input resolver registry repeats data class ${JSON.stringify(classes[index].dataClass)}`,\n );\n }\n }\n return {\n kind: INPUT_RESOLVER_REGISTRY_KIND,\n version: INPUT_RESOLVER_REGISTRY_VERSION,\n revision: revision(record.revision, \"input resolver registry revision\"),\n classes,\n };\n}\n\nexport async function publishInputResolverRegistry(\n objects: ContentObjectStore,\n input: InputResolverRegistryInputV1,\n): Promise<PutContentObjectResult<InputResolverRegistryV1>> {\n const registry = normalizeRegistry({\n kind: INPUT_RESOLVER_REGISTRY_KIND,\n version: INPUT_RESOLVER_REGISTRY_VERSION,\n revision: input.revision,\n classes: input.classes,\n });\n return objects.put(registry);\n}\n\nexport async function verifyInputResolverRegistry(\n objects: ContentObjectStore,\n registryAddress: CanonicalJsonAddress,\n): Promise<PutContentObjectResult<InputResolverRegistryV1>> {\n address(registryAddress, \"input resolver registry address\");\n const stored = await objects.get<unknown>(registryAddress);\n const registry = normalizeRegistry(stored);\n if (!canonicalJsonBytes(registry).equals(canonicalJsonBytes(stored))) {\n fail(\"input resolver registry is not normalized and deterministically ordered\");\n }\n return {\n address: registryAddress,\n value: registry,\n path: objects.objectPath(registryAddress),\n bytes: canonicalJsonBytes(stored).byteLength,\n created: false,\n };\n}\n\nfunction normalizeObservation(value: unknown, label: string): InputClosureObservationV1 {\n const record = plainRecord(snapshot(value, label), label);\n switch (record.kind) {\n case \"exact\":\n case \"missing-probe\": {\n exactKeys(record, [\"kind\", \"dataClass\", \"selector\", \"session\"], label);\n return {\n kind: record.kind,\n dataClass: identifier(record.dataClass, `${label}.dataClass`),\n selector: stringMap(record.selector, `${label}.selector`),\n session: sessionDate(record.session, `${label}.session`),\n };\n }\n case \"range\": {\n exactKeys(\n record,\n [\"kind\", \"dataClass\", \"selectorPrefix\", \"fromSession\", \"throughSession\"],\n label,\n );\n const fromSession = sessionDate(record.fromSession, `${label}.fromSession`);\n const throughSession = sessionDate(record.throughSession, `${label}.throughSession`);\n if (fromSession > throughSession) fail(`${label} has an inverted session range`);\n return {\n kind: record.kind,\n dataClass: identifier(record.dataClass, `${label}.dataClass`),\n selectorPrefix: stringMap(record.selectorPrefix, `${label}.selectorPrefix`),\n fromSession,\n throughSession,\n };\n }\n case \"control-file\":\n exactKeys(record, [\"kind\", \"dataClass\", \"role\"], label);\n return {\n kind: record.kind,\n dataClass: identifier(record.dataClass, `${label}.dataClass`),\n role: identifier(record.role, `${label}.role`),\n };\n case \"unmanifestable\":\n exactKeys(record, [\"kind\", \"readClass\", \"reasonCode\"], label);\n return {\n kind: record.kind,\n readClass: identifier(record.readClass, `${label}.readClass`),\n reasonCode: revision(record.reasonCode, `${label}.reasonCode`),\n };\n default:\n fail(`${label}.kind is unsupported`);\n }\n}\n\nfunction observationTuple(observation: InputClosureObservationV1): readonly string[] {\n switch (observation.kind) {\n case \"exact\":\n case \"missing-probe\":\n return [\n String(OBSERVATION_RANK[observation.kind]),\n observation.dataClass,\n canonicalJson(observation.selector),\n observation.session,\n ];\n case \"range\":\n return [\n String(OBSERVATION_RANK[observation.kind]),\n observation.dataClass,\n canonicalJson(observation.selectorPrefix),\n observation.fromSession,\n observation.throughSession,\n ];\n case \"control-file\":\n return [String(OBSERVATION_RANK[observation.kind]), observation.dataClass, observation.role];\n case \"unmanifestable\":\n return [\n String(OBSERVATION_RANK[observation.kind]),\n observation.readClass,\n observation.reasonCode,\n ];\n }\n}\n\nfunction compareTuples(left: readonly string[], right: readonly string[]): number {\n const length = Math.min(left.length, right.length);\n for (let index = 0; index < length; index += 1) {\n const compared = compareUnicodeCodePoints(left[index], right[index]);\n if (compared !== 0) return compared;\n }\n return left.length - right.length;\n}\n\nfunction normalizeObservations(value: unknown): readonly InputClosureObservationV1[] {\n if (!Array.isArray(value) || value.length === 0) {\n fail(\"input closure observations must be a non-empty array\");\n }\n const normalized = value.map((entry, index) => ({\n value: normalizeObservation(entry, `input closure observations[${index}]`),\n raw: rawStableJson(entry),\n }));\n normalized.sort((left, right) =>\n compareTuples(observationTuple(left.value), observationTuple(right.value)),\n );\n const result: InputClosureObservationV1[] = [];\n let previousNormalized: string | undefined;\n let previousRaw: string | undefined;\n for (const entry of normalized) {\n const encoded = canonicalJson(entry.value);\n if (encoded === previousNormalized) {\n if (entry.raw !== previousRaw) {\n fail(\"input closure observations collide after NFC normalization\");\n }\n continue;\n }\n result.push(entry.value);\n previousNormalized = encoded;\n previousRaw = entry.raw;\n }\n return result;\n}\n\nfunction normalizeDescriptor(value: unknown): InputClosureDescriptorV1 {\n const captured = snapshot<unknown>(value, \"input closure descriptor\");\n const record = plainRecord(captured, \"input closure descriptor\");\n exactKeys(record, [\"kind\", \"version\", \"registry\", \"observations\"], \"input closure descriptor\");\n if (record.kind !== INPUT_CLOSURE_DESCRIPTOR_KIND)\n fail(\"input closure descriptor kind is invalid\");\n if (record.version !== INPUT_CLOSURE_DESCRIPTOR_VERSION) {\n fail(\"input closure descriptor version is unsupported\");\n }\n return {\n kind: INPUT_CLOSURE_DESCRIPTOR_KIND,\n version: INPUT_CLOSURE_DESCRIPTOR_VERSION,\n registry: address(record.registry, \"input closure registry\"),\n observations: normalizeObservations(record.observations),\n };\n}\n\nfunction sameStringSet(observed: readonly string[], expected: readonly string[]): boolean {\n const left = [...observed].sort(compareUnicodeCodePoints);\n const right = [...expected].sort(compareUnicodeCodePoints);\n return left.length === right.length && left.every((entry, index) => entry === right[index]);\n}\n\nfunction validateObservationAgainstRegistry(\n observation: InputClosureObservationV1,\n registry: InputResolverRegistryV1,\n): void {\n if (observation.kind === \"unmanifestable\") return;\n const resolverClass = registry.classes.find((entry) => entry.dataClass === observation.dataClass);\n if (!resolverClass) {\n fail(`input closure references unknown data class ${JSON.stringify(observation.dataClass)}`);\n }\n if (observation.kind === \"control-file\") {\n if (resolverClass.kind !== \"static\" || resolverClass.role !== observation.role) {\n fail(\"control-file observation disagrees with its registry class\");\n }\n return;\n }\n if (resolverClass.kind === \"static\") {\n fail(`${observation.kind} observation requires a session-scoped registry class`);\n }\n if (observation.kind === \"range\") {\n const expectedPrefixKeys = resolverClass.selectorKeys.filter(\n (key) => key !== resolverClass.sessionKey,\n );\n const observedKeys = Object.keys(observation.selectorPrefix);\n if (!sameStringSet(observedKeys, expectedPrefixKeys)) {\n fail(\"range selector prefix disagrees with its registry class\");\n }\n return;\n }\n const observedKeys = Object.keys(observation.selector);\n if (!sameStringSet(observedKeys, resolverClass.selectorKeys)) {\n fail(`${observation.kind} selector disagrees with its registry class`);\n }\n if (observation.selector[resolverClass.sessionKey] !== observation.session) {\n fail(`${observation.kind} selector session disagrees with its explicit session`);\n }\n}\n\nfunction validateDescriptorAgainstRegistry(\n descriptor: InputClosureDescriptorV1,\n registry: InputResolverRegistryV1,\n): void {\n for (const observation of descriptor.observations) {\n validateObservationAgainstRegistry(observation, registry);\n }\n}\n\nexport function createInputClosureDescriptor(\n registry: CanonicalJsonAddress,\n observations: readonly InputClosureObservationV1[],\n): InputClosureDescriptorV1 {\n return normalizeDescriptor({\n kind: INPUT_CLOSURE_DESCRIPTOR_KIND,\n version: INPUT_CLOSURE_DESCRIPTOR_VERSION,\n registry: address(registry, \"input closure registry\"),\n observations,\n });\n}\n\nexport async function publishInputClosure(\n objects: ContentObjectStore,\n input: {\n registry: CanonicalJsonAddress;\n observations: readonly InputClosureObservationV1[];\n },\n): Promise<PutContentObjectResult<InputClosureDescriptorV1>> {\n const descriptor = createInputClosureDescriptor(input.registry, input.observations);\n const registry = await verifyInputResolverRegistry(objects, descriptor.registry);\n validateDescriptorAgainstRegistry(descriptor, registry.value);\n return objects.put(descriptor);\n}\n\nexport async function verifyInputClosure(\n objects: ContentObjectStore,\n closureAddress: CanonicalJsonAddress,\n): Promise<PutContentObjectResult<InputClosureDescriptorV1>> {\n address(closureAddress, \"input closure address\");\n const stored = await objects.get<unknown>(closureAddress);\n const descriptor = normalizeDescriptor(stored);\n if (!canonicalJsonBytes(descriptor).equals(canonicalJsonBytes(stored))) {\n fail(\"input closure is not normalized and deterministically ordered\");\n }\n const registry = await verifyInputResolverRegistry(objects, descriptor.registry);\n validateDescriptorAgainstRegistry(descriptor, registry.value);\n return {\n address: closureAddress,\n value: descriptor,\n path: objects.objectPath(closureAddress),\n bytes: canonicalJsonBytes(stored).byteLength,\n created: false,\n };\n}\n\nfunction stableDependencyObservation(\n observation: InputClosureObservationV1,\n):\n | Exclude<InputClosureObservationV1, { kind: \"unmanifestable\" }>\n | Omit<Extract<InputClosureObservationV1, { kind: \"range\" }>, \"throughSession\"> {\n if (observation.kind === \"unmanifestable\") {\n fail(\"unmanifestable observations do not have resolvable dependency keys\");\n }\n if (observation.kind !== \"range\") return observation;\n return {\n kind: observation.kind,\n dataClass: observation.dataClass,\n selectorPrefix: observation.selectorPrefix,\n fromSession: observation.fromSession,\n };\n}\n\nexport function dependencyKeyAddress(\n registry: CanonicalJsonAddress,\n observation: InputClosureObservationV1,\n): CanonicalJsonAddress {\n const normalizedRegistry = address(registry, \"input dependency registry\");\n const normalizedObservation = normalizeObservation(observation, \"input dependency observation\");\n return addressCanonicalJson({\n kind: INPUT_DEPENDENCY_KEY_KIND,\n version: INPUT_DEPENDENCY_KEY_VERSION,\n registry: normalizedRegistry,\n observation: stableDependencyObservation(normalizedObservation),\n });\n}\n\nexport function restrictInputClosureDescriptor(\n descriptor: InputClosureDescriptorV1,\n completeThrough: string,\n): InputClosureDescriptorV1 {\n const normalized = normalizeDescriptor(descriptor);\n const cutoff = sessionDate(completeThrough, \"input closure restriction cutoff\");\n const observations: InputClosureObservationV1[] = [];\n for (const observation of normalized.observations) {\n switch (observation.kind) {\n case \"exact\":\n case \"missing-probe\":\n if (observation.session <= cutoff) observations.push(observation);\n break;\n case \"range\":\n if (observation.fromSession <= cutoff) {\n observations.push({\n ...observation,\n throughSession:\n observation.throughSession <= cutoff ? observation.throughSession : cutoff,\n });\n }\n break;\n case \"control-file\":\n case \"unmanifestable\":\n observations.push(observation);\n break;\n }\n }\n if (observations.length === 0) {\n fail(\"input closure restriction removed every observation\");\n }\n return createInputClosureDescriptor(normalized.registry, observations);\n}\n\nfunction nonnegativeSafeInteger(value: unknown, label: string): number {\n if (!Number.isSafeInteger(value) || (value as number) < 0) {\n fail(`${label} must be a non-negative safe integer`);\n }\n return value as number;\n}\n\nfunction sha256Address(value: unknown, label: string): Sha256Address {\n const normalized = nonemptyString(value, label);\n try {\n parseSha256Address(normalized);\n } catch (error) {\n throw new ManifestVerificationError(`${label} is not a SHA-256 address`, { cause: error });\n }\n return normalized as Sha256Address;\n}\n\nfunction normalizeCoverage(value: unknown, label: string): LogicalCoverage {\n const record = plainRecord(value, label);\n if (record.kind === \"empty\") {\n exactKeys(record, [\"kind\"], label);\n return { kind: \"empty\" };\n }\n if (record.kind === \"date-range\") {\n exactKeys(record, [\"kind\", \"from\", \"through\"], label);\n const from = sessionDate(record.from, `${label}.from`);\n const through = sessionDate(record.through, `${label}.through`);\n if (from > through) fail(`${label} has an inverted date range`);\n return { kind: \"date-range\", from, through };\n }\n fail(`${label}.kind is unsupported`);\n}\n\nfunction normalizeQuality(value: unknown, label: string): PartitionQualityCounts {\n const record = plainRecord(value, label);\n exactKeys(record, [\"inputRows\", \"writtenRows\", \"droppedRows\"], label);\n const quality = {\n inputRows: nonnegativeSafeInteger(record.inputRows, `${label}.inputRows`),\n writtenRows: nonnegativeSafeInteger(record.writtenRows, `${label}.writtenRows`),\n droppedRows: nonnegativeSafeInteger(record.droppedRows, `${label}.droppedRows`),\n };\n if (quality.inputRows !== quality.writtenRows + quality.droppedRows) {\n fail(`${label} row counts are inconsistent`);\n }\n return quality;\n}\n\nfunction normalizeFile(value: unknown, label: string): ExactFileFingerprint {\n const record = plainRecord(value, label);\n exactKeys(record, [\"address\", \"bytes\", \"rows\"], label);\n return {\n address: sha256Address(record.address, `${label}.address`),\n bytes: nonnegativeSafeInteger(record.bytes, `${label}.bytes`),\n rows: nonnegativeSafeInteger(record.rows, `${label}.rows`),\n };\n}\n\nfunction normalizeObjectReference(\n value: unknown,\n label: string,\n): { address: CanonicalJsonAddress; bytes: number } {\n const record = plainRecord(value, label);\n exactKeys(record, [\"address\", \"bytes\"], label);\n return {\n address: address(record.address, `${label}.address`),\n bytes: positiveSafeInteger(record.bytes, `${label}.bytes`),\n };\n}\n\nfunction registryClass(registry: InputResolverRegistryV1, dataClass: string): InputResolverClassV1 {\n const found = registry.classes.find((entry) => entry.dataClass === dataClass);\n if (!found) fail(`semantic input references unknown data class ${JSON.stringify(dataClass)}`);\n return found;\n}\n\nfunction normalizePartitionProjection(\n record: JsonRecord,\n label: string,\n resolverClass: PartitionedResolverClassV1,\n): PartitionProjectionV1 {\n exactKeys(\n record,\n [\n \"kind\",\n \"dataset\",\n \"partition\",\n \"relativePath\",\n \"session\",\n \"schemaRevision\",\n \"coverage\",\n \"quality\",\n \"file\",\n ],\n label,\n );\n const dataset = identifier(record.dataset, `${label}.dataset`);\n const partition = stringMap(record.partition, `${label}.partition`);\n const relative = relativePath(record.relativePath, `${label}.relativePath`);\n const session = sessionDate(record.session, `${label}.session`);\n const schemaRevision = positiveSafeInteger(record.schemaRevision, `${label}.schemaRevision`);\n const coverage = normalizeCoverage(record.coverage, `${label}.coverage`);\n const quality = normalizeQuality(record.quality, `${label}.quality`);\n const file = normalizeFile(record.file, `${label}.file`);\n if (dataset !== resolverClass.dataset) fail(`${label}.dataset disagrees with the registry`);\n if (!sameStringSet(Object.keys(partition), resolverClass.selectorKeys)) {\n fail(`${label}.partition disagrees with the registry selector keys`);\n }\n if (partition[resolverClass.sessionKey] !== session) {\n fail(`${label}.partition session disagrees with its explicit session`);\n }\n const expectedPath = canonicalPartitionRelativePath({ dataset, partition });\n if (relative !== expectedPath) fail(`${label}.relativePath disagrees with the registry`);\n if (!resolverClass.supportedSchemaRevisions.includes(schemaRevision)) {\n fail(`${label}.schemaRevision is unsupported`);\n }\n if (quality.writtenRows !== file.rows) fail(`${label}.quality disagrees with file rows`);\n if (coverage.kind === \"empty\" && file.rows !== 0) {\n fail(`${label}.coverage is empty for a non-empty file`);\n }\n if (coverage.kind === \"date-range\" && file.rows === 0) {\n fail(`${label}.coverage is non-empty for an empty file`);\n }\n return {\n kind: \"partition-projection\",\n dataset,\n partition,\n relativePath: relative,\n session,\n schemaRevision,\n coverage,\n quality,\n file,\n };\n}\n\nfunction normalizeMaterializedSlice(\n record: JsonRecord,\n label: string,\n resolverClass: MaterializedResolverClassV1,\n): MaterializedSliceV1 {\n exactKeys(record, [\"kind\", \"selector\", \"session\", \"schemaRevision\", \"object\"], label);\n const selector = stringMap(record.selector, `${label}.selector`);\n const session = sessionDate(record.session, `${label}.session`);\n const schemaRevision = positiveSafeInteger(record.schemaRevision, `${label}.schemaRevision`);\n if (!sameStringSet(Object.keys(selector), resolverClass.selectorKeys)) {\n fail(`${label}.selector disagrees with the registry selector keys`);\n }\n if (selector[resolverClass.sessionKey] !== session) {\n fail(`${label}.selector session disagrees with its explicit session`);\n }\n if (!resolverClass.supportedSchemaRevisions.includes(schemaRevision)) {\n fail(`${label}.schemaRevision is unsupported`);\n }\n return {\n kind: \"materialized-slice\",\n selector,\n session,\n schemaRevision,\n object: normalizeObjectReference(record.object, `${label}.object`),\n };\n}\n\nfunction normalizeSemanticSource(\n value: unknown,\n label: string,\n resolverClass: InputResolverClassV1,\n): SemanticInputSourceV1 {\n const record = plainRecord(snapshot(value, label), label);\n switch (record.kind) {\n case \"partition-projection\":\n if (resolverClass.kind !== \"partitioned\") {\n fail(`${label} requires a partitioned registry class`);\n }\n return normalizePartitionProjection(record, label, resolverClass);\n case \"control-file\": {\n if (resolverClass.kind !== \"static\") fail(`${label} requires a static registry class`);\n exactKeys(record, [\"kind\", \"role\", \"relativePath\", \"schemaRevision\", \"object\"], label);\n const role = identifier(record.role, `${label}.role`);\n const relative = relativePath(record.relativePath, `${label}.relativePath`);\n const schemaRevision = positiveSafeInteger(record.schemaRevision, `${label}.schemaRevision`);\n if (role !== resolverClass.role || relative !== resolverClass.relativePath) {\n fail(`${label} disagrees with the static registry class`);\n }\n if (!resolverClass.supportedSchemaRevisions.includes(schemaRevision)) {\n fail(`${label}.schemaRevision is unsupported`);\n }\n return {\n kind: \"control-file\",\n role,\n relativePath: relative,\n schemaRevision,\n object: normalizeObjectReference(record.object, `${label}.object`),\n };\n }\n case \"missing-probe\": {\n if (resolverClass.kind !== \"partitioned\") {\n fail(`${label} requires a partitioned registry class`);\n }\n exactKeys(record, [\"kind\", \"session\"], label);\n return {\n kind: \"missing-probe\",\n session: sessionDate(record.session, `${label}.session`),\n };\n }\n case \"materialized-slice\":\n if (resolverClass.kind !== \"materialized\") {\n fail(`${label} requires a materialized registry class`);\n }\n return normalizeMaterializedSlice(record, label, resolverClass);\n default:\n fail(`${label}.kind is unsupported`);\n }\n}\n\nfunction expectedScope(\n observation: Exclude<InputClosureObservationV1, { kind: \"unmanifestable\" }>,\n source: SemanticInputSourceV1,\n): SemanticInputLeafV1[\"scope\"] {\n if (observation.kind === \"control-file\") return { kind: \"static\" };\n if (source.kind === \"control-file\") {\n fail(`${observation.kind} observation cannot use ${source.kind} source evidence`);\n }\n return { kind: \"session\", session: source.session };\n}\n\nfunction validateSourceAgainstObservation(\n source: SemanticInputSourceV1,\n observation: Exclude<InputClosureObservationV1, { kind: \"unmanifestable\" }>,\n resolverClass: InputResolverClassV1,\n options: { allowRangeFuture?: boolean } = {},\n): \"included\" | \"future\" {\n if (observation.kind === \"control-file\") {\n if (source.kind !== \"control-file\" || resolverClass.kind !== \"static\") {\n fail(\"control-file observation has incompatible semantic source evidence\");\n }\n if (source.role !== observation.role) fail(\"control-file source role is incorrect\");\n return \"included\";\n }\n if (observation.kind === \"missing-probe\") {\n if (source.kind !== \"missing-probe\") {\n fail(\"missing-probe observation has incompatible semantic source evidence\");\n }\n if (source.session !== observation.session) fail(\"missing-probe source session is incorrect\");\n return \"included\";\n }\n if (\n (source.kind !== \"partition-projection\" || resolverClass.kind !== \"partitioned\") &&\n (source.kind !== \"materialized-slice\" || resolverClass.kind !== \"materialized\")\n ) {\n fail(`${observation.kind} observation requires compatible session evidence`);\n }\n const selector = source.kind === \"partition-projection\" ? source.partition : source.selector;\n if (observation.kind === \"exact\") {\n if (\n source.session !== observation.session ||\n canonicalJson(selector) !== canonicalJson(observation.selector)\n ) {\n fail(\"exact source partition is incorrect\");\n }\n return \"included\";\n }\n for (const [key, value] of Object.entries(observation.selectorPrefix)) {\n if (selector[key] !== value) fail(\"range source partition prefix is incorrect\");\n }\n if (source.session < observation.fromSession) fail(\"range source precedes the requested range\");\n if (source.session > observation.throughSession) {\n if (options.allowRangeFuture) return \"future\";\n fail(\"range source exceeds the requested range\");\n }\n return \"included\";\n}\n\nfunction normalizeSemanticLeaf(value: unknown): SemanticInputLeafV1 {\n const captured = snapshot<unknown>(value, \"semantic input leaf\");\n const record = plainRecord(captured, \"semantic input leaf\");\n exactKeys(\n record,\n [\"kind\", \"version\", \"registry\", \"dependency\", \"dataClass\", \"scope\", \"source\"],\n \"semantic input leaf\",\n );\n if (record.kind !== SEMANTIC_INPUT_LEAF_KIND) fail(\"semantic input leaf kind is invalid\");\n if (record.version !== SEMANTIC_INPUT_LEAF_VERSION) {\n fail(\"semantic input leaf version is unsupported\");\n }\n const registryAddress = address(record.registry, \"semantic input leaf registry\");\n const dependency = address(record.dependency, \"semantic input leaf dependency\");\n const dataClass = identifier(record.dataClass, \"semantic input leaf dataClass\");\n const scopeRecord = plainRecord(record.scope, \"semantic input leaf scope\");\n let scope: SemanticInputLeafV1[\"scope\"];\n if (scopeRecord.kind === \"static\") {\n exactKeys(scopeRecord, [\"kind\"], \"semantic input leaf scope\");\n scope = { kind: \"static\" };\n } else if (scopeRecord.kind === \"session\") {\n exactKeys(scopeRecord, [\"kind\", \"session\"], \"semantic input leaf scope\");\n scope = {\n kind: \"session\",\n session: sessionDate(scopeRecord.session, \"semantic input leaf scope.session\"),\n };\n } else {\n fail(\"semantic input leaf scope kind is unsupported\");\n }\n return {\n kind: SEMANTIC_INPUT_LEAF_KIND,\n version: SEMANTIC_INPUT_LEAF_VERSION,\n registry: registryAddress,\n dependency,\n dataClass,\n scope,\n source: record.source as SemanticInputSourceV1,\n };\n}\n\nasync function normalizeSemanticLeafWithRegistry(\n objects: ContentObjectStore,\n value: unknown,\n): Promise<SemanticInputLeafV1> {\n const leaf = normalizeSemanticLeaf(value);\n const registry = await verifyInputResolverRegistry(objects, leaf.registry);\n const resolverClass = registryClass(registry.value, leaf.dataClass);\n const source = normalizeSemanticSource(leaf.source, \"semantic input leaf source\", resolverClass);\n if (source.kind === \"control-file\") {\n if (leaf.scope.kind !== \"static\") fail(\"control-file leaf must have static scope\");\n } else {\n if (leaf.scope.kind !== \"session\" || leaf.scope.session !== source.session) {\n fail(\"semantic input leaf scope disagrees with its source\");\n }\n }\n return { ...leaf, source };\n}\n\nexport async function publishSemanticInputLeaf(\n objects: ContentObjectStore,\n input: {\n registry: CanonicalJsonAddress;\n observation: InputClosureObservationV1;\n source: SemanticInputSourceV1;\n },\n): Promise<PutContentObjectResult<SemanticInputLeafV1>> {\n const registryAddress = address(input.registry, \"semantic input registry\");\n const observation = normalizeObservation(input.observation, \"semantic input observation\");\n const capturedSource = snapshot<SemanticInputSourceV1>(input.source, \"semantic input source\");\n if (observation.kind === \"unmanifestable\") {\n fail(\"unmanifestable observations cannot publish semantic leaves\");\n }\n const registry = await verifyInputResolverRegistry(objects, registryAddress);\n validateObservationAgainstRegistry(observation, registry.value);\n const resolverClass = registryClass(registry.value, observation.dataClass);\n const source = normalizeSemanticSource(capturedSource, \"semantic input source\", resolverClass);\n validateSourceAgainstObservation(source, observation, resolverClass);\n if (source.kind === \"control-file\") {\n const stored = await objects.get<unknown>(source.object.address);\n if (canonicalJsonBytes(stored).byteLength !== source.object.bytes) {\n fail(\"control-file object byte length is incorrect\");\n }\n }\n return objects.put({\n kind: SEMANTIC_INPUT_LEAF_KIND,\n version: SEMANTIC_INPUT_LEAF_VERSION,\n registry: registryAddress,\n dependency: dependencyKeyAddress(registryAddress, observation),\n dataClass: observation.dataClass,\n scope: expectedScope(observation, source),\n source,\n });\n}\n\nexport async function verifySemanticInputLeaf(\n objects: ContentObjectStore,\n leafAddress: CanonicalJsonAddress,\n): Promise<PutContentObjectResult<SemanticInputLeafV1>> {\n address(leafAddress, \"semantic input leaf address\");\n const stored = await objects.get<unknown>(leafAddress);\n const leaf = await normalizeSemanticLeafWithRegistry(objects, stored);\n if (!canonicalJsonBytes(leaf).equals(canonicalJsonBytes(stored))) {\n fail(\"semantic input leaf is not normalized\");\n }\n return {\n address: leafAddress,\n value: leaf,\n path: objects.objectPath(leafAddress),\n bytes: canonicalJsonBytes(stored).byteLength,\n created: false,\n };\n}\n\nexport async function publishMissingProbeEvidence(\n objects: ContentObjectStore,\n input: {\n registry: CanonicalJsonAddress;\n observation: Extract<InputClosureObservationV1, { kind: \"missing-probe\" }>;\n completeThrough: string;\n },\n): Promise<PutContentObjectResult<MissingProbeEvidenceV1>> {\n const registryAddress = address(input.registry, \"missing-probe evidence registry\");\n const observation = normalizeObservation(input.observation, \"missing-probe evidence observation\");\n if (observation.kind !== \"missing-probe\") fail(\"missing-probe evidence requires a probe\");\n const completeThrough = sessionDate(\n input.completeThrough,\n \"missing-probe evidence completeThrough\",\n );\n const registry = await verifyInputResolverRegistry(objects, registryAddress);\n validateObservationAgainstRegistry(observation, registry.value);\n if (completeThrough < observation.session) {\n fail(\"missing-probe evidence complete horizon precedes the probe\");\n }\n return objects.put({\n kind: MISSING_PROBE_EVIDENCE_KIND,\n version: MISSING_PROBE_EVIDENCE_VERSION,\n registry: registryAddress,\n dependency: dependencyKeyAddress(registryAddress, observation),\n completeThrough,\n });\n}\n\nfunction normalizeMissingProbeEvidence(value: unknown): MissingProbeEvidenceV1 {\n const captured = snapshot<unknown>(value, \"missing-probe evidence\");\n const record = plainRecord(captured, \"missing-probe evidence\");\n exactKeys(\n record,\n [\"kind\", \"version\", \"registry\", \"dependency\", \"completeThrough\"],\n \"missing-probe evidence\",\n );\n if (record.kind !== MISSING_PROBE_EVIDENCE_KIND) {\n fail(\"missing-probe evidence kind is invalid\");\n }\n if (record.version !== MISSING_PROBE_EVIDENCE_VERSION) {\n fail(\"missing-probe evidence version is unsupported\");\n }\n return {\n kind: MISSING_PROBE_EVIDENCE_KIND,\n version: MISSING_PROBE_EVIDENCE_VERSION,\n registry: address(record.registry, \"missing-probe evidence registry\"),\n dependency: address(record.dependency, \"missing-probe evidence dependency\"),\n completeThrough: sessionDate(record.completeThrough, \"missing-probe evidence completeThrough\"),\n };\n}\n\nasync function verifyMissingProbeEvidence(\n objects: ContentObjectStore,\n evidenceAddress: CanonicalJsonAddress,\n): Promise<MissingProbeEvidenceV1> {\n address(evidenceAddress, \"missing-probe evidence address\");\n const stored = await objects.get<unknown>(evidenceAddress);\n const evidence = normalizeMissingProbeEvidence(stored);\n if (!canonicalJsonBytes(evidence).equals(canonicalJsonBytes(stored))) {\n fail(\"missing-probe evidence is not normalized\");\n }\n await verifyInputResolverRegistry(objects, evidence.registry);\n return evidence;\n}\n\nfunction normalizeLeafEvidence(value: unknown, label: string): ManifestLeafEvidenceV1 {\n const record = plainRecord(value, label);\n switch (record.kind) {\n case \"partition-receipt\":\n exactKeys(record, [\"kind\", \"receipt\"], label);\n return {\n kind: \"partition-receipt\",\n receipt: address(record.receipt, `${label}.receipt`),\n };\n case \"content-object\":\n exactKeys(record, [\"kind\", \"object\"], label);\n return {\n kind: \"content-object\",\n object: address(record.object, `${label}.object`),\n };\n case \"absence-object\":\n exactKeys(record, [\"kind\", \"object\"], label);\n return {\n kind: \"absence-object\",\n object: address(record.object, `${label}.object`),\n };\n default:\n fail(`${label}.kind is unsupported`);\n }\n}\n\nfunction normalizeLeafReferences(\n value: unknown,\n label: string,\n): readonly ManifestLeafReferenceV1[] {\n if (!Array.isArray(value) || value.length === 0) fail(`${label} must be a non-empty array`);\n const references = value.map((entry, index) => {\n const record = plainRecord(entry, `${label}[${index}]`);\n exactKeys(record, [\"leaf\", \"evidence\"], `${label}[${index}]`);\n return {\n leaf: address(record.leaf, `${label}[${index}].leaf`),\n evidence: normalizeLeafEvidence(record.evidence, `${label}[${index}].evidence`),\n };\n });\n references.sort((left, right) => {\n const byLeaf = compareUnicodeCodePoints(left.leaf, right.leaf);\n return byLeaf === 0\n ? compareUnicodeCodePoints(canonicalJson(left.evidence), canonicalJson(right.evidence))\n : byLeaf;\n });\n for (let index = 1; index < references.length; index += 1) {\n if (references[index - 1].leaf === references[index].leaf) {\n fail(`${label} contains a duplicate semantic leaf`);\n }\n }\n return references;\n}\n\ninterface MerkleNode {\n address: Sha256Address;\n count: number;\n}\n\nfunction merkleTreeRoot(leaves: readonly CanonicalJsonAddress[]): Sha256Address {\n if (leaves.length === 0) {\n return addressCanonicalJson({\n kind: \"tradeblocks.market-data.merkle-empty\",\n version: 1,\n count: 0,\n });\n }\n let level: MerkleNode[] = leaves.map((leaf) => ({\n address: addressCanonicalJson({\n kind: \"tradeblocks.market-data.merkle-leaf\",\n version: 1,\n count: 1,\n leaf,\n }),\n count: 1,\n }));\n while (level.length > 1) {\n const next: MerkleNode[] = [];\n for (let index = 0; index < level.length; index += 2) {\n const left = level[index];\n const right = level[index + 1];\n if (!right) {\n next.push({\n address: addressCanonicalJson({\n kind: \"tradeblocks.market-data.merkle-unary\",\n version: 1,\n count: left.count,\n child: left.address,\n }),\n count: left.count,\n });\n } else {\n const count = left.count + right.count;\n next.push({\n address: addressCanonicalJson({\n kind: \"tradeblocks.market-data.merkle-binary\",\n version: 1,\n count,\n left: left.address,\n right: right.address,\n }),\n count,\n });\n }\n }\n level = next;\n }\n return level[0].address;\n}\n\nfunction createManifestClass(\n dataClass: string,\n completeThrough: string,\n entries: readonly ManifestLeafReferenceV1[],\n): ManifestClassV1 {\n const normalizedEntries = normalizeLeafReferences(entries, `${dataClass} manifest entries`);\n const leafCount = normalizedEntries.length;\n const treeRoot = merkleTreeRoot(normalizedEntries.map((entry) => entry.leaf));\n return {\n dataClass,\n completeThrough,\n entries: normalizedEntries,\n leafCount,\n root: addressCanonicalJson({\n kind: \"tradeblocks.market-data.merkle-class\",\n version: 1,\n dataClass,\n completeThrough,\n leafCount,\n treeRoot,\n }),\n };\n}\n\nfunction normalizePredecessor(\n value: unknown,\n label: string,\n): { manifest: CanonicalJsonAddress; aggregateRoot: Sha256Address } {\n const record = plainRecord(value, label);\n exactKeys(record, [\"manifest\", \"aggregateRoot\"], label);\n return {\n manifest: address(record.manifest, `${label}.manifest`),\n aggregateRoot: sha256Address(record.aggregateRoot, `${label}.aggregateRoot`),\n };\n}\n\nfunction createCutoffManifestValue(\n closure: CanonicalJsonAddress,\n completeThrough: string,\n classes: readonly ManifestClassV1[],\n refreshCompletion?: CanonicalJsonAddress,\n predecessor?: { manifest: CanonicalJsonAddress; aggregateRoot: Sha256Address },\n): CutoffManifestV1 {\n const sortedClasses = [...classes].sort((left, right) =>\n compareUnicodeCodePoints(left.dataClass, right.dataClass),\n );\n if (sortedClasses.length === 0) fail(\"cutoff manifest must contain at least one data class\");\n const aggregateRoot = addressCanonicalJson({\n kind: \"tradeblocks.market-data.merkle-aggregate\",\n version: 1,\n closure,\n completeThrough,\n ...(refreshCompletion ? { refreshCompletion } : {}),\n classes: sortedClasses.map(({ dataClass, leafCount, root }) => ({\n dataClass,\n leafCount,\n root,\n })),\n });\n return {\n kind: CUTOFF_MANIFEST_KIND,\n version: CUTOFF_MANIFEST_VERSION,\n closure,\n completeThrough,\n classes: sortedClasses,\n aggregateRoot,\n ...(refreshCompletion ? { refreshCompletion } : {}),\n ...(predecessor ? { predecessor } : {}),\n };\n}\n\nfunction normalizeManifestClass(value: unknown, label: string): ManifestClassV1 {\n const record = plainRecord(value, label);\n exactKeys(record, [\"dataClass\", \"completeThrough\", \"entries\", \"leafCount\", \"root\"], label);\n const entries = normalizeLeafReferences(record.entries, `${label}.entries`);\n const leafCount = positiveSafeInteger(record.leafCount, `${label}.leafCount`);\n if (leafCount !== entries.length) fail(`${label}.leafCount disagrees with its entries`);\n return {\n dataClass: identifier(record.dataClass, `${label}.dataClass`),\n completeThrough: sessionDate(record.completeThrough, `${label}.completeThrough`),\n entries,\n leafCount,\n root: sha256Address(record.root, `${label}.root`),\n };\n}\n\nfunction normalizeCutoffManifest(value: unknown): CutoffManifestV1 {\n const captured = snapshot<unknown>(value, \"cutoff manifest\");\n const record = plainRecord(captured, \"cutoff manifest\");\n const expected = [\n \"kind\",\n \"version\",\n \"closure\",\n \"completeThrough\",\n \"classes\",\n \"aggregateRoot\",\n ...(Object.hasOwn(record, \"refreshCompletion\") ? [\"refreshCompletion\"] : []),\n ...(Object.hasOwn(record, \"predecessor\") ? [\"predecessor\"] : []),\n ];\n exactKeys(record, expected, \"cutoff manifest\");\n if (record.kind !== CUTOFF_MANIFEST_KIND) fail(\"cutoff manifest kind is invalid\");\n if (record.version !== CUTOFF_MANIFEST_VERSION) fail(\"cutoff manifest version is unsupported\");\n if (!Array.isArray(record.classes) || record.classes.length === 0) {\n fail(\"cutoff manifest classes must be a non-empty array\");\n }\n const classes = record.classes.map((entry, index) =>\n normalizeManifestClass(entry, `cutoff manifest classes[${index}]`),\n );\n classes.sort((left, right) => compareUnicodeCodePoints(left.dataClass, right.dataClass));\n for (let index = 1; index < classes.length; index += 1) {\n if (classes[index - 1].dataClass === classes[index].dataClass) {\n fail(\"cutoff manifest contains a duplicate data class\");\n }\n }\n return {\n kind: CUTOFF_MANIFEST_KIND,\n version: CUTOFF_MANIFEST_VERSION,\n closure: address(record.closure, \"cutoff manifest closure\"),\n completeThrough: sessionDate(record.completeThrough, \"cutoff manifest completeThrough\"),\n classes,\n aggregateRoot: sha256Address(record.aggregateRoot, \"cutoff manifest aggregateRoot\"),\n ...(record.refreshCompletion === undefined\n ? {}\n : {\n refreshCompletion: address(record.refreshCompletion, \"cutoff manifest refreshCompletion\"),\n }),\n ...(record.predecessor === undefined\n ? {}\n : { predecessor: normalizePredecessor(record.predecessor, \"cutoff manifest predecessor\") }),\n };\n}\n\nasync function verifyLeafEvidence(\n partitions: FilePartitionCommitStore,\n leaf: SemanticInputLeafV1,\n reference: ManifestLeafReferenceV1,\n observation: Exclude<InputClosureObservationV1, { kind: \"unmanifestable\" }>,\n resolverClass: InputResolverClassV1,\n completeThrough: string,\n): Promise<void> {\n switch (reference.evidence.kind) {\n case \"partition-receipt\": {\n if (leaf.source.kind !== \"partition-projection\" || resolverClass.kind !== \"partitioned\") {\n fail(\"partition receipt evidence requires a partition projection leaf\");\n }\n const commit = await partitions.readCommit(reference.evidence.receipt);\n const receipt = commit.receipt;\n const projected: PartitionProjectionV1 = {\n kind: \"partition-projection\",\n dataset: receipt.dataset,\n partition: receipt.partition,\n relativePath: receipt.relativePath,\n session: receipt.partition[resolverClass.sessionKey],\n schemaRevision: receipt.schemaRevision,\n coverage: receipt.coverage,\n quality: receipt.quality,\n file: receipt.file,\n };\n if (canonicalJson(projected) !== canonicalJson(leaf.source)) {\n fail(\"partition receipt does not reproduce the semantic leaf\");\n }\n const inspected = await partitions.inspectPartition({\n dataset: receipt.dataset,\n partition: receipt.partition,\n });\n if (\n inspected.status !== \"match\" ||\n inspected.receipt.address !== reference.evidence.receipt\n ) {\n fail(\"partition receipt is not the current exact-byte authority tip\");\n }\n return;\n }\n case \"content-object\": {\n if (leaf.source.kind !== \"control-file\" && leaf.source.kind !== \"materialized-slice\") {\n fail(\"content-object evidence requires an object-backed semantic leaf\");\n }\n if (leaf.source.object.address !== reference.evidence.object) {\n fail(\"content-object evidence address disagrees with the semantic leaf\");\n }\n const stored = await partitions.objects.get<unknown>(reference.evidence.object);\n if (canonicalJsonBytes(stored).byteLength !== leaf.source.object.bytes) {\n fail(\"content-object evidence byte length disagrees with the semantic leaf\");\n }\n return;\n }\n case \"absence-object\": {\n if (\n leaf.source.kind !== \"missing-probe\" ||\n observation.kind !== \"missing-probe\" ||\n resolverClass.kind !== \"partitioned\"\n ) {\n fail(\"absence-object evidence requires a missing-probe leaf\");\n }\n const evidence = await verifyMissingProbeEvidence(\n partitions.objects,\n reference.evidence.object,\n );\n if (\n evidence.registry !== leaf.registry ||\n evidence.dependency !== leaf.dependency ||\n evidence.completeThrough < completeThrough\n ) {\n fail(\"missing-probe evidence does not cover the requested dependency horizon\");\n }\n const inspected = await partitions.inspectPartition({\n dataset: resolverClass.dataset,\n partition: observation.selector,\n });\n if (inspected.status !== \"absent\") {\n fail(\"missing-probe evidence is stale because the partition is no longer absent\");\n }\n return;\n }\n }\n}\n\nasync function resolveManifestClasses(\n partitions: FilePartitionCommitStore,\n descriptor: InputClosureDescriptorV1,\n completeThrough: string,\n resolver: ManifestInputResolver,\n): Promise<readonly ManifestClassV1[]> {\n const cutoffClosure = restrictInputClosureDescriptor(descriptor, completeThrough);\n const registry = await verifyInputResolverRegistry(partitions.objects, cutoffClosure.registry);\n const entriesByClass = new Map<string, ManifestLeafReferenceV1[]>();\n const dependencies = new Set<string>();\n for (const observation of cutoffClosure.observations) {\n if (observation.kind === \"unmanifestable\") {\n fail(\n `input closure contains unmanifestable read ${JSON.stringify(observation.readClass)} (${observation.reasonCode})`,\n );\n }\n const dependency = dependencyKeyAddress(cutoffClosure.registry, observation);\n if (dependencies.has(dependency)) {\n fail(\"input closure contains more than one observation for the same stable dependency\");\n }\n dependencies.add(dependency);\n const resolution = await resolver.resolve({\n registry: registry.value,\n closure: cutoffClosure,\n observation,\n dependency,\n completeThrough,\n });\n if (resolution.kind !== \"resolved\") {\n fail(`input dependency is ${resolution.kind}: ${resolution.reasonCode}`);\n }\n const resolvedThrough = sessionDate(\n resolution.completeThrough,\n `resolved ${observation.dataClass} completeThrough`,\n );\n if (resolvedThrough < completeThrough) {\n fail(`resolved ${observation.dataClass} input does not reach the complete horizon`);\n }\n const resolverClass = registryClass(registry.value, observation.dataClass);\n const candidates = normalizeLeafReferences(\n resolution.entries,\n `resolved ${observation.dataClass} entries`,\n );\n const included: ManifestLeafReferenceV1[] = [];\n for (const reference of candidates) {\n const leaf = await verifySemanticInputLeaf(partitions.objects, reference.leaf);\n if (\n leaf.value.registry !== cutoffClosure.registry ||\n leaf.value.dependency !== dependency ||\n leaf.value.dataClass !== observation.dataClass\n ) {\n fail(\"resolved semantic leaf disagrees with its closure dependency\");\n }\n const posture = validateSourceAgainstObservation(\n leaf.value.source,\n observation,\n resolverClass,\n { allowRangeFuture: observation.kind === \"range\" },\n );\n if (posture === \"future\") continue;\n await verifyLeafEvidence(\n partitions,\n leaf.value,\n reference,\n observation,\n resolverClass,\n completeThrough,\n );\n included.push(reference);\n }\n if (included.length === 0) {\n fail(`resolved ${observation.dataClass} dependency has no applicable semantic leaves`);\n }\n if (observation.kind !== \"range\" && included.length !== 1) {\n fail(`${observation.kind} dependency must resolve to exactly one semantic leaf`);\n }\n const classEntries = entriesByClass.get(observation.dataClass) ?? [];\n classEntries.push(...included);\n entriesByClass.set(observation.dataClass, classEntries);\n }\n return [...entriesByClass.entries()]\n .sort(([left], [right]) => compareUnicodeCodePoints(left, right))\n .map(([dataClass, entries]) => createManifestClass(dataClass, completeThrough, entries));\n}\n\nexport async function publishCutoffManifest(\n partitions: FilePartitionCommitStore,\n input: {\n closure: CanonicalJsonAddress;\n completeThrough: string;\n resolver: ManifestInputResolver;\n refreshCompletion?: CanonicalJsonAddress;\n predecessor?: { manifest: CanonicalJsonAddress; aggregateRoot: Sha256Address };\n },\n): Promise<PutContentObjectResult<CutoffManifestV1>> {\n // Capture every caller-owned semantic field before the first await. Mutable\n // input objects must not let verification and publication use two closures.\n const closureAddress = address(input.closure, \"cutoff manifest closure\");\n const completeThrough = sessionDate(input.completeThrough, \"cutoff manifest completeThrough\");\n const resolver = input.resolver;\n const refreshCompletion = input.refreshCompletion\n ? address(input.refreshCompletion, \"cutoff manifest refreshCompletion\")\n : undefined;\n const predecessor = input.predecessor\n ? normalizePredecessor(input.predecessor, \"cutoff manifest predecessor\")\n : undefined;\n const closure = await verifyInputClosure(partitions.objects, closureAddress);\n const classes = await resolveManifestClasses(\n partitions,\n closure.value,\n completeThrough,\n resolver,\n );\n if (refreshCompletion) await partitions.objects.get<unknown>(refreshCompletion);\n const value = createCutoffManifestValue(\n closureAddress,\n completeThrough,\n classes,\n refreshCompletion,\n predecessor,\n );\n const published = await partitions.objects.put(value);\n // Evidence checks span multiple independently locked resources. Re-resolve\n // after immutable publication so a repair or control change during the first\n // pass makes this object an unadvertised orphan instead of a successful mint.\n const finalClasses = await resolveManifestClasses(\n partitions,\n closure.value,\n completeThrough,\n resolver,\n );\n const finalValue = createCutoffManifestValue(\n closureAddress,\n completeThrough,\n finalClasses,\n refreshCompletion,\n predecessor,\n );\n if (!canonicalJsonBytes(finalValue).equals(canonicalJsonBytes(value))) {\n fail(\"market inputs changed during cutoff manifest publication\");\n }\n return published;\n}\n\nexport async function verifyCutoffManifest(\n partitions: FilePartitionCommitStore,\n manifestAddress: CanonicalJsonAddress,\n resolver: ManifestInputResolver,\n): Promise<{ address: CanonicalJsonAddress; manifest: CutoffManifestV1 }> {\n address(manifestAddress, \"cutoff manifest address\");\n const stored = await partitions.objects.get<unknown>(manifestAddress);\n const manifest = normalizeCutoffManifest(stored);\n if (!canonicalJsonBytes(manifest).equals(canonicalJsonBytes(stored))) {\n fail(\"cutoff manifest is not normalized and deterministically ordered\");\n }\n if (manifest.refreshCompletion) {\n await partitions.objects.get<unknown>(manifest.refreshCompletion);\n }\n const closure = await verifyInputClosure(partitions.objects, manifest.closure);\n const classes = await resolveManifestClasses(\n partitions,\n closure.value,\n manifest.completeThrough,\n resolver,\n );\n const expected = createCutoffManifestValue(\n manifest.closure,\n manifest.completeThrough,\n classes,\n manifest.refreshCompletion,\n manifest.predecessor,\n );\n if (!canonicalJsonBytes(expected).equals(canonicalJsonBytes(manifest))) {\n fail(\"cutoff manifest does not match the resolver-owned complete input set\");\n }\n return { address: manifestAddress, manifest };\n}\n\nexport async function proveCutoffManifestPrefix(\n partitions: FilePartitionCommitStore,\n ancestorAddress: CanonicalJsonAddress,\n descendantAddress: CanonicalJsonAddress,\n resolver: ManifestInputResolver,\n): Promise<{ valid: boolean; reason?: string }> {\n const ancestor = await verifyCutoffManifest(partitions, ancestorAddress, resolver);\n const descendant = await verifyCutoffManifest(partitions, descendantAddress, resolver);\n // Prefix is reflexive for one immutable, content-addressed manifest. This is\n // the producer proof used by already-current resume operations: both reads\n // above still re-verify the exact object before equality is accepted.\n if (ancestorAddress === descendantAddress) {\n return { valid: true };\n }\n if (ancestor.manifest.completeThrough >= descendant.manifest.completeThrough) {\n return { valid: false, reason: \"cutoff-not-increasing\" };\n }\n const ancestorClosure = await verifyInputClosure(partitions.objects, ancestor.manifest.closure);\n const descendantClosure = await verifyInputClosure(\n partitions.objects,\n descendant.manifest.closure,\n );\n if (ancestorClosure.value.registry !== descendantClosure.value.registry) {\n return { valid: false, reason: \"registry-mismatch\" };\n }\n const restricted = restrictInputClosureDescriptor(\n descendantClosure.value,\n ancestor.manifest.completeThrough,\n );\n if (canonicalJson(restricted) !== canonicalJson(ancestorClosure.value)) {\n return { valid: false, reason: \"closure-restriction-mismatch\" };\n }\n if (\n descendant.manifest.predecessor &&\n (descendant.manifest.predecessor.manifest !== ancestorAddress ||\n descendant.manifest.predecessor.aggregateRoot !== ancestor.manifest.aggregateRoot)\n ) {\n return { valid: false, reason: \"predecessor-hint-mismatch\" };\n }\n const ancestorByClass = new Map(\n ancestor.manifest.classes.map((entry) => [entry.dataClass, entry]),\n );\n const descendantByClass = new Map(\n descendant.manifest.classes.map((entry) => [entry.dataClass, entry]),\n );\n if (!sameStringSet([...ancestorByClass.keys()], [...descendantByClass.keys()])) {\n return { valid: false, reason: \"class-set-mismatch\" };\n }\n const registry = await verifyInputResolverRegistry(\n partitions.objects,\n ancestorClosure.value.registry,\n );\n for (const [dataClass, ancestorClass] of ancestorByClass) {\n const descendantClass = descendantByClass.get(dataClass) as ManifestClassV1;\n const resolverClass = registryClass(registry.value, dataClass);\n let retained: readonly ManifestLeafReferenceV1[];\n if (resolverClass.kind === \"static\" && resolver.projectStaticPrefix) {\n retained = await resolver.projectStaticPrefix({\n registry: registry.value,\n registryAddress: ancestorClosure.value.registry,\n dataClass,\n ancestorCompleteThrough: ancestor.manifest.completeThrough,\n descendantCompleteThrough: descendant.manifest.completeThrough,\n descendantEntries: descendantClass.entries,\n });\n } else {\n const historical: ManifestLeafReferenceV1[] = [];\n for (const reference of descendantClass.entries) {\n const leaf = await verifySemanticInputLeaf(partitions.objects, reference.leaf);\n if (\n leaf.value.scope.kind === \"static\" ||\n leaf.value.scope.session <= ancestor.manifest.completeThrough\n ) {\n historical.push(reference);\n }\n }\n retained = historical;\n }\n const normalizedRetained = normalizeLeafReferences(retained, `prefix ${dataClass} entries`);\n for (const reference of normalizedRetained) {\n const leaf = await verifySemanticInputLeaf(partitions.objects, reference.leaf);\n if (\n leaf.value.registry !== ancestorClosure.value.registry ||\n leaf.value.dataClass !== dataClass\n ) {\n fail(\"prefix projection returned a leaf outside the manifest class\");\n }\n if (resolverClass.kind === \"static\" && leaf.value.scope.kind !== \"static\") {\n fail(\"static prefix projection returned a session-scoped leaf\");\n }\n }\n if (\n canonicalJson(normalizedRetained.map((entry) => entry.leaf)) !==\n canonicalJson(ancestorClass.entries.map((entry) => entry.leaf))\n ) {\n return { valid: false, reason: \"historical-leaf-mismatch\" };\n }\n const reproduced = createManifestClass(\n dataClass,\n ancestor.manifest.completeThrough,\n normalizedRetained,\n );\n if (reproduced.root !== ancestorClass.root) {\n return { valid: false, reason: \"historical-root-mismatch\" };\n }\n }\n // Prefix authorization must end on a fresh currentness pass; otherwise a\n // repair racing the proof walk could be accepted after its evidence changed.\n await verifyCutoffManifest(partitions, ancestorAddress, resolver);\n await verifyCutoffManifest(partitions, descendantAddress, resolver);\n return { valid: true };\n}\n","import * as path from \"node:path\";\nimport {\n canonicalJson,\n canonicalJsonBytes,\n parseCanonicalJsonAddress,\n parseSha256Address,\n type CanonicalJsonAddress,\n type Sha256Address,\n} from \"./canonical-json.ts\";\nimport type { PutContentObjectResult } from \"./content-object-store.ts\";\nimport {\n canonicalPartitionDataset,\n canonicalPartitionRelativePath,\n validatePartitionIdentity,\n type DatasetPartitionIdentity,\n} from \"./dataset-registry.ts\";\nimport {\n runPartitionCommitAttempt,\n type PartitionCommitAttemptResult,\n} from \"./partition-commit-attempt.ts\";\nimport {\n FilePartitionCommitStore,\n publishRefreshCompletionAuthority,\n verifyRefreshCompletionAuthority,\n type StoredPartitionCommit,\n} from \"./partition-commit-store.ts\";\nimport { isXnysSessionDate } from \"./xnys-session-calendar.ts\";\nimport {\n finalizeCanonicalMarketDataCutoff,\n verifyCanonicalMarketDataCutoff,\n} from \"./canonical-market-resolver.ts\";\nimport { verifyInputClosure, verifyInputResolverRegistry } from \"./content-manifest.ts\";\nimport type { MarketIngestor, MarketIngestorDeps } from \"../ingestor/market-ingestor.ts\";\nimport type {\n BulkProgressEvent,\n BulkProgressReporter,\n IngestResult,\n RefreshOptions,\n RefreshResult,\n} from \"../ingestor/types.ts\";\nimport { bulkQuoteRootsForUnderlying } from \"../../utils/providers/thetadata/bulk-roots.ts\";\nimport { getEnrichedThrough, upsertEnrichedThrough } from \"../../db/json-adapters.ts\";\n\nexport const CANONICAL_REFRESH_COMPLETION_KIND =\n \"tradeblocks.market-data.canonical-refresh-completion\" as const;\nexport const CANONICAL_REFRESH_COMPLETION_VERSION = 2 as const;\n\nexport interface CanonicalRefreshPlanV2 {\n asOf: string;\n spotTickers: readonly string[];\n enrichedTickers: readonly string[];\n includeEnrichedContext: boolean;\n chainUnderlyings: readonly string[];\n quoteUnderlyings: readonly string[];\n openInterestUnderlyings: readonly string[];\n provider?: \"massive\" | \"thetadata\";\n}\n\nexport interface CanonicalRefreshReceiptV1 extends DatasetPartitionIdentity {\n receipt: CanonicalJsonAddress;\n}\n\nexport interface CanonicalRefreshOperationV1 {\n kind: \"spot\" | \"chain\" | \"quotes\" | \"open-interest\";\n target: string;\n status: \"ok\";\n rowsWritten: number;\n}\n\nexport interface CanonicalRefreshQuoteGroupV1 {\n underlying: string;\n root: string;\n right: \"call\" | \"put\";\n date: string;\n completedContracts: number;\n totalContracts: number;\n}\n\nexport interface CanonicalRefreshCompletionV2 {\n kind: typeof CANONICAL_REFRESH_COMPLETION_KIND;\n version: typeof CANONICAL_REFRESH_COMPLETION_VERSION;\n attemptId: string;\n closure: CanonicalJsonAddress;\n plan: CanonicalRefreshPlanV2;\n operations: readonly CanonicalRefreshOperationV1[];\n quoteGroups: readonly CanonicalRefreshQuoteGroupV1[];\n receipts: readonly CanonicalRefreshReceiptV1[];\n}\n\ninterface BoundedRefreshResult {\n perOperation: RefreshResult[\"perOperation\"];\n quoteGroups: readonly CanonicalRefreshQuoteGroupV1[];\n}\n\ninterface CanonicalProvenanceRefreshOptions {\n closure: CanonicalJsonAddress;\n attemptId: string;\n predecessor?: { manifest: CanonicalJsonAddress; aggregateRoot: Sha256Address };\n}\n\ntype ProvenanceRefreshInput = RefreshOptions & {\n provenance: CanonicalProvenanceRefreshOptions;\n};\n\nfunction normalizeAuthority(\n input: CanonicalProvenanceRefreshOptions,\n): CanonicalProvenanceRefreshOptions {\n parseCanonicalJsonAddress(input.closure);\n const attemptId = input.attemptId.normalize(\"NFC\").trim();\n if (attemptId.length === 0) throw new TypeError(\"Canonical refresh attemptId must not be empty\");\n const predecessor = input.predecessor\n ? {\n manifest: input.predecessor.manifest,\n aggregateRoot: input.predecessor.aggregateRoot,\n }\n : undefined;\n if (predecessor) {\n parseCanonicalJsonAddress(predecessor.manifest);\n parseSha256Address(predecessor.aggregateRoot);\n }\n return Object.freeze({\n closure: input.closure,\n attemptId,\n ...(predecessor ? { predecessor: Object.freeze(predecessor) } : {}),\n });\n}\n\nfunction compareCodePoints(left: string, right: string): number {\n const leftPoints = Array.from(left, (character) => character.codePointAt(0) as number);\n const rightPoints = Array.from(right, (character) => character.codePointAt(0) as number);\n const length = Math.min(leftPoints.length, rightPoints.length);\n for (let index = 0; index < length; index += 1) {\n if (leftPoints[index] !== rightPoints[index]) return leftPoints[index] - rightPoints[index];\n }\n return leftPoints.length - rightPoints.length;\n}\n\nfunction normalizedSymbols(values: readonly string[] | undefined, label: string): string[] {\n const normalized = (values ?? []).map((value, index) => {\n if (typeof value !== \"string\") throw new TypeError(`${label}[${index}] must be a string`);\n const symbol = value.normalize(\"NFC\").trim().toUpperCase();\n if (!/^[A-Z][A-Z0-9._-]*$/.test(symbol)) {\n throw new TypeError(`${label}[${index}] is not a canonical market symbol`);\n }\n return symbol;\n });\n return [...new Set(normalized)].sort(compareCodePoints);\n}\n\nfunction normalizePlan(input: RefreshOptions, deps: MarketIngestorDeps): CanonicalRefreshPlanV2 {\n if (!isXnysSessionDate(input.asOf)) {\n throw new Error(`Canonical refresh cutoff is not a supported XNYS session: ${input.asOf}`);\n }\n if ((input.quoteTickers?.length ?? 0) > 0) {\n throw new Error(\n \"Canonical refresh refuses quoteTickers because per-ticker writes overwrite a shared partition\",\n );\n }\n const rawQuoteUnderlyings = normalizedSymbols(input.quoteUnderlyings, \"quoteUnderlyings\");\n const quoteUnderlyings = normalizedSymbols(\n rawQuoteUnderlyings.map((underlying) => deps.stores.quote.tickers.resolve(underlying)),\n \"resolved quoteUnderlyings\",\n );\n const rawOiUnderlyings = normalizedSymbols(\n input.openInterestUnderlyings,\n \"openInterestUnderlyings\",\n );\n const openInterestUnderlyings = normalizedSymbols(\n rawOiUnderlyings.map((underlying) => deps.stores.quote.tickers.resolve(underlying)),\n \"resolved openInterestUnderlyings\",\n );\n if (\n (quoteUnderlyings.length > 0 || openInterestUnderlyings.length > 0) &&\n input.provider !== \"thetadata\"\n ) {\n throw new Error(\"Canonical option refresh requires the explicit ThetaData terminal protocol\");\n }\n const plan: CanonicalRefreshPlanV2 = {\n asOf: input.asOf,\n spotTickers: normalizedSymbols(input.spotTickers, \"spotTickers\"),\n enrichedTickers: [],\n includeEnrichedContext: false,\n chainUnderlyings: normalizedSymbols(input.chainUnderlyings, \"chainUnderlyings\"),\n quoteUnderlyings,\n openInterestUnderlyings,\n ...(input.provider ? { provider: input.provider } : {}),\n };\n return Object.freeze({\n ...plan,\n spotTickers: Object.freeze(plan.spotTickers),\n enrichedTickers: Object.freeze(plan.enrichedTickers),\n chainUnderlyings: Object.freeze(plan.chainUnderlyings),\n quoteUnderlyings: Object.freeze(plan.quoteUnderlyings),\n openInterestUnderlyings: Object.freeze(plan.openInterestUnderlyings),\n });\n}\n\nfunction expectedInventory(plan: CanonicalRefreshPlanV2): DatasetPartitionIdentity[] {\n const session = plan.asOf;\n return [\n ...plan.spotTickers.map((ticker) => ({\n dataset: \"spot\",\n partition: { ticker, date: session },\n })),\n ...plan.enrichedTickers.map((ticker) => ({\n dataset: \"enriched\",\n partition: { ticker, date: session },\n })),\n ...(plan.includeEnrichedContext\n ? [{ dataset: \"enriched_context\", partition: { date: session } }]\n : []),\n ...plan.chainUnderlyings.map((underlying) => ({\n dataset: \"option_chain\",\n partition: { underlying, date: session },\n })),\n ...plan.quoteUnderlyings.map((underlying) => ({\n dataset: \"option_quote_minutes\",\n partition: { underlying, date: session },\n })),\n ...plan.openInterestUnderlyings.map((underlying) => ({\n dataset: \"option_oi_daily\",\n partition: { underlying, date: session },\n })),\n ];\n}\n\nfunction validateDerivedPlanInputs(plan: CanonicalRefreshPlanV2): void {\n if (plan.enrichedTickers.some((ticker) => !plan.spotTickers.includes(ticker))) {\n throw new Error(\"Canonical enriched cutoff requires same-session spot refresh for its ticker\");\n }\n if (plan.includeEnrichedContext) {\n const requiredContextSpot = [\"SPX\", \"VIX\", \"VIX9D\", \"VIX3M\"];\n if (requiredContextSpot.some((ticker) => !plan.spotTickers.includes(ticker))) {\n throw new Error(\n \"Canonical enriched context requires same-session SPX/VIX/VIX9D/VIX3M spot refresh\",\n );\n }\n }\n}\n\nasync function closureTailInventory(\n partitions: FilePartitionCommitStore,\n closureAddress: CanonicalJsonAddress,\n completeThrough: string,\n): Promise<DatasetPartitionIdentity[]> {\n const closure = await verifyInputClosure(partitions.objects, closureAddress);\n const registry = await verifyInputResolverRegistry(partitions.objects, closure.value.registry);\n const identities: DatasetPartitionIdentity[] = [];\n for (const observation of closure.value.observations) {\n if (observation.kind === \"missing-probe\" && observation.session === completeThrough) {\n throw new Error(\"A cutoff missing-probe cannot satisfy refresh completion authority\");\n }\n if (observation.kind !== \"exact\" && observation.kind !== \"range\") continue;\n const reachesCutoff =\n observation.kind === \"exact\"\n ? observation.session === completeThrough\n : observation.fromSession <= completeThrough &&\n observation.throughSession >= completeThrough;\n if (!reachesCutoff) continue;\n const resolverClass = registry.value.classes.find(\n (entry) => entry.dataClass === observation.dataClass,\n );\n if (resolverClass?.kind === \"materialized\") continue;\n if (!resolverClass || resolverClass.kind !== \"partitioned\") {\n throw new Error(\"Cutoff closure tail is not a canonical partitioned input class\");\n }\n const identity: DatasetPartitionIdentity = {\n dataset: resolverClass.dataset,\n partition:\n observation.kind === \"exact\"\n ? observation.selector\n : {\n ...observation.selectorPrefix,\n [resolverClass.sessionKey]: completeThrough,\n },\n };\n validatePartitionIdentity(identity);\n identities.push(identity);\n }\n identities.sort((left, right) => compareCodePoints(identityKey(left), identityKey(right)));\n if (identities.length === 0) {\n throw new Error(\"Canonical refresh closure has no partitioned cutoff-tail inventory\");\n }\n if (new Set(identities.map(identityKey)).size !== identities.length) {\n throw new Error(\"Canonical refresh closure repeats a cutoff-tail partition\");\n }\n return identities;\n}\n\nasync function bindPlanToClosure(\n partitions: FilePartitionCommitStore,\n closure: CanonicalJsonAddress,\n base: CanonicalRefreshPlanV2,\n): Promise<CanonicalRefreshPlanV2> {\n const inventory = await closureTailInventory(partitions, closure, base.asOf);\n const enrichedTickers = inventory\n .filter((identity) => identity.dataset === \"enriched\")\n .map((identity) => identity.partition.ticker)\n .sort(compareCodePoints);\n const includeEnrichedContext = inventory.some(\n (identity) => identity.dataset === \"enriched_context\",\n );\n const rawInventory = inventory.filter(\n (identity) => identity.dataset !== \"enriched\" && identity.dataset !== \"enriched_context\",\n );\n if (\n canonicalJson(rawInventory.map(identityKey)) !==\n canonicalJson(expectedInventory(base).map(identityKey).sort(compareCodePoints))\n ) {\n throw new Error(\"Canonical refresh request does not equal the closure raw cutoff inventory\");\n }\n if (inventory.length === 0) throw new Error(\"Canonical refresh inventory must not be empty\");\n const plan = Object.freeze({\n ...base,\n enrichedTickers: Object.freeze(enrichedTickers),\n includeEnrichedContext,\n });\n validateDerivedPlanInputs(plan);\n return plan;\n}\n\nfunction identityKey(identity: DatasetPartitionIdentity): string {\n return canonicalJson({ dataset: identity.dataset, partition: identity.partition });\n}\n\nfunction requireTerminalResult(result: IngestResult, label: string): IngestResult {\n if (result.status !== \"ok\" || result.rowsWritten <= 0 || (result.skipped?.length ?? 0) > 0) {\n throw new Error(\n `Canonical refresh operation ${label} was not terminal: ${canonicalJson({\n status: result.status,\n rowsWritten: result.rowsWritten,\n skipped: result.skipped?.length ?? 0,\n error: result.error ?? \"\",\n })}`,\n );\n }\n return result;\n}\n\nasync function runBoundedRefresh(\n ingestor: MarketIngestor,\n plan: CanonicalRefreshPlanV2,\n onProgress: BulkProgressReporter | undefined,\n): Promise<BoundedRefreshResult> {\n const spot: IngestResult[] = [];\n for (const ticker of plan.spotTickers) {\n spot.push(\n requireTerminalResult(\n await ingestor.ingestBars({\n tickers: [ticker],\n from: plan.asOf,\n to: plan.asOf,\n timespan: \"1m\",\n skipEnrichment: true,\n ...(plan.provider ? { provider: plan.provider } : {}),\n }),\n `spot ${ticker}`,\n ),\n );\n }\n const chain: IngestResult[] = [];\n for (const underlying of plan.chainUnderlyings) {\n chain.push(\n requireTerminalResult(\n await ingestor.ingestChain({\n underlyings: [underlying],\n from: plan.asOf,\n to: plan.asOf,\n ...(plan.provider ? { provider: plan.provider } : {}),\n }),\n `chain ${underlying}`,\n ),\n );\n }\n const quotes: IngestResult[] = [];\n const quoteGroups: CanonicalRefreshQuoteGroupV1[] = [];\n for (const underlying of plan.quoteUnderlyings) {\n const observed = new Map<string, CanonicalRefreshQuoteGroupV1>();\n const poisoned = new Set<string>();\n const collectProgress = async (event: BulkProgressEvent) => {\n if (event.kind === \"group\" && event.phase === \"complete\") {\n const key = `${event.root.toUpperCase()}:${event.right}`;\n if (\n event.underlying.toUpperCase() === underlying &&\n event.date === plan.asOf &&\n event.status === \"ok\" &&\n Number.isSafeInteger(event.completedContracts) &&\n Number.isSafeInteger(event.totalContracts) &&\n (event.completedContracts as number) >= 0 &&\n event.completedContracts === event.totalContracts\n ) {\n if (!poisoned.has(key)) {\n observed.set(key, {\n underlying,\n root: event.root.toUpperCase(),\n right: event.right,\n date: plan.asOf,\n completedContracts: event.completedContracts as number,\n totalContracts: event.totalContracts as number,\n });\n }\n } else {\n poisoned.add(key);\n observed.delete(key);\n }\n }\n await onProgress?.(event);\n };\n quotes.push(\n requireTerminalResult(\n await ingestor.ingestQuotes({\n underlyings: [underlying],\n from: plan.asOf,\n to: plan.asOf,\n ...(plan.provider ? { provider: plan.provider } : {}),\n onProgress: collectProgress,\n }),\n `quotes ${underlying}`,\n ),\n );\n const expected = bulkQuoteRootsForUnderlying(underlying)\n .flatMap((root) => [`${root}:call`, `${root}:put`])\n .sort(compareCodePoints);\n const completed = [...observed.keys()].sort(compareCodePoints);\n if (\n canonicalJson(completed) !== canonicalJson(expected) ||\n expected.some((key) => poisoned.has(key))\n ) {\n throw new Error(\n `Canonical quote refresh did not complete every root/right group: ${canonicalJson({ expected, completed })}`,\n );\n }\n quoteGroups.push(...observed.values());\n }\n const openInterest: IngestResult[] = [];\n for (const underlying of plan.openInterestUnderlyings) {\n openInterest.push(\n requireTerminalResult(\n await ingestor.ingestOpenInterest({\n underlyings: [underlying],\n from: plan.asOf,\n to: plan.asOf,\n ...(plan.provider ? { provider: plan.provider } : {}),\n }),\n `open interest ${underlying}`,\n ),\n );\n }\n quoteGroups.sort((left, right) =>\n compareCodePoints(\n `${left.underlying}:${left.root}:${left.right}`,\n `${right.underlying}:${right.root}:${right.right}`,\n ),\n );\n return {\n perOperation: { spot, chain, quotes, openInterest, vixContext: null },\n quoteGroups,\n };\n}\n\nfunction operationKey(operation: Pick<CanonicalRefreshOperationV1, \"kind\" | \"target\">): string {\n return `${operation.kind}:${operation.target}`;\n}\n\nfunction terminalOperations(\n plan: CanonicalRefreshPlanV2,\n value: BoundedRefreshResult[\"perOperation\"],\n): CanonicalRefreshOperationV1[] {\n if (\n value.spot.length !== plan.spotTickers.length ||\n value.chain.length !== plan.chainUnderlyings.length ||\n value.quotes.length !== plan.quoteUnderlyings.length ||\n value.openInterest.length !== plan.openInterestUnderlyings.length ||\n value.vixContext !== null\n ) {\n throw new Error(\"Canonical refresh terminal operation evidence disagrees with its plan\");\n }\n const operations: CanonicalRefreshOperationV1[] = [\n ...plan.spotTickers.map((target, index) => ({\n kind: \"spot\" as const,\n target,\n status: \"ok\" as const,\n rowsWritten: value.spot[index].rowsWritten,\n })),\n ...plan.chainUnderlyings.map((target, index) => ({\n kind: \"chain\" as const,\n target,\n status: \"ok\" as const,\n rowsWritten: value.chain[index].rowsWritten,\n })),\n ...plan.quoteUnderlyings.map((target, index) => ({\n kind: \"quotes\" as const,\n target,\n status: \"ok\" as const,\n rowsWritten: value.quotes[index].rowsWritten,\n })),\n ...plan.openInterestUnderlyings.map((target, index) => ({\n kind: \"open-interest\" as const,\n target,\n status: \"ok\" as const,\n rowsWritten: value.openInterest[index].rowsWritten,\n })),\n ];\n operations.sort((left, right) => compareCodePoints(operationKey(left), operationKey(right)));\n return operations;\n}\n\nfunction expectedOperationKeys(plan: CanonicalRefreshPlanV2): string[] {\n return [\n ...plan.spotTickers.map((target) => operationKey({ kind: \"spot\", target })),\n ...plan.chainUnderlyings.map((target) => operationKey({ kind: \"chain\", target })),\n ...plan.quoteUnderlyings.map((target) => operationKey({ kind: \"quotes\", target })),\n ...plan.openInterestUnderlyings.map((target) =>\n operationKey({ kind: \"open-interest\", target }),\n ),\n ].sort(compareCodePoints);\n}\n\nfunction operationIdentity(\n operation: CanonicalRefreshOperationV1,\n asOf: string,\n): DatasetPartitionIdentity {\n switch (operation.kind) {\n case \"spot\":\n return { dataset: \"spot\", partition: { ticker: operation.target, date: asOf } };\n case \"chain\":\n return {\n dataset: \"option_chain\",\n partition: { underlying: operation.target, date: asOf },\n };\n case \"quotes\":\n return {\n dataset: \"option_quote_minutes\",\n partition: { underlying: operation.target, date: asOf },\n };\n case \"open-interest\":\n return {\n dataset: \"option_oi_daily\",\n partition: { underlying: operation.target, date: asOf },\n };\n }\n}\n\nfunction validateAttemptInventory(\n plan: CanonicalRefreshPlanV2,\n attempt: PartitionCommitAttemptResult<BoundedRefreshResult>,\n): void {\n const expected = new Map(\n expectedInventory(plan).map((identity) => [identityKey(identity), identity]),\n );\n const observed = new Map(\n attempt.receipts.map((commit) => [identityKey(commit.receipt), commit] as const),\n );\n if (expected.size !== observed.size || [...expected.keys()].some((key) => !observed.has(key))) {\n throw new Error(\n `Canonical refresh receipts do not equal the producer inventory: ${canonicalJson({\n expected: [...expected.keys()].sort(compareCodePoints),\n observed: [...observed.keys()].sort(compareCodePoints),\n })}`,\n );\n }\n}\n\nasync function validateCurrentReceipt(\n partitions: FilePartitionCommitStore,\n plan: CanonicalRefreshPlanV2,\n commit: StoredPartitionCommit,\n): Promise<void> {\n const receipt = commit.receipt;\n const definition = canonicalPartitionDataset(receipt.dataset);\n if (!definition)\n throw new Error(`Canonical refresh receipt has unknown dataset ${receipt.dataset}`);\n const session = receipt.partition[definition.provenance.sessionKey];\n if (\n session !== plan.asOf ||\n receipt.schemaRevision !== definition.schemaRevision ||\n receipt.relativePath !== canonicalPartitionRelativePath(receipt) ||\n receipt.coverage.kind !== \"date-range\" ||\n receipt.coverage.from !== plan.asOf ||\n receipt.coverage.through !== plan.asOf ||\n receipt.file.rows <= 0 ||\n receipt.quality.inputRows !== receipt.quality.writtenRows ||\n receipt.quality.writtenRows !== receipt.file.rows ||\n receipt.quality.droppedRows !== 0\n ) {\n throw new Error(`Canonical refresh receipt is not a complete zero-drop cutoff partition`);\n }\n const inspected = await partitions.inspectPartition(receipt);\n if (inspected.status !== \"match\" || inspected.receipt.address !== commit.address) {\n throw new Error(\"Canonical refresh receipt is not the current exact-byte authority tip\");\n }\n}\n\nfunction receiptValue(commit: StoredPartitionCommit): CanonicalRefreshReceiptV1 {\n return {\n dataset: commit.receipt.dataset,\n partition: commit.receipt.partition,\n receipt: commit.address,\n };\n}\n\nfunction normalizeCompletion(value: unknown): CanonicalRefreshCompletionV2 {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n throw new Error(\"Canonical refresh completion must be an object\");\n }\n const record = value as Record<string, unknown>;\n const keys = Object.keys(record).sort(compareCodePoints);\n if (\n canonicalJson(keys) !==\n canonicalJson([\n \"attemptId\",\n \"closure\",\n \"kind\",\n \"operations\",\n \"plan\",\n \"quoteGroups\",\n \"receipts\",\n \"version\",\n ])\n ) {\n throw new Error(\"Canonical refresh completion has unknown or missing fields\");\n }\n if (\n record.kind !== CANONICAL_REFRESH_COMPLETION_KIND ||\n record.version !== CANONICAL_REFRESH_COMPLETION_VERSION\n ) {\n throw new Error(\"Canonical refresh completion identity is invalid\");\n }\n if (typeof record.attemptId !== \"string\" || record.attemptId.trim().length === 0) {\n throw new Error(\"Canonical refresh completion attemptId is invalid\");\n }\n const attemptId = record.attemptId.normalize(\"NFC\").trim();\n if (typeof record.closure !== \"string\") {\n throw new Error(\"Canonical refresh completion closure is invalid\");\n }\n parseCanonicalJsonAddress(record.closure);\n if (record.plan === null || typeof record.plan !== \"object\" || Array.isArray(record.plan)) {\n throw new Error(\"Canonical refresh completion plan must be an object\");\n }\n const planRecord = record.plan as Record<string, unknown>;\n const planKeys = Object.keys(planRecord).sort(compareCodePoints);\n const expectedPlanKeys = [\n \"asOf\",\n \"chainUnderlyings\",\n \"enrichedTickers\",\n \"includeEnrichedContext\",\n \"openInterestUnderlyings\",\n \"quoteUnderlyings\",\n \"spotTickers\",\n ...(Object.hasOwn(planRecord, \"provider\") ? [\"provider\"] : []),\n ].sort(compareCodePoints);\n if (canonicalJson(planKeys) !== canonicalJson(expectedPlanKeys)) {\n throw new Error(\"Canonical refresh completion plan has unknown or missing fields\");\n }\n const plan: CanonicalRefreshPlanV2 = {\n asOf: String(planRecord.asOf),\n spotTickers: normalizedSymbols(planRecord.spotTickers as string[], \"plan.spotTickers\"),\n enrichedTickers: normalizedSymbols(\n planRecord.enrichedTickers as string[],\n \"plan.enrichedTickers\",\n ),\n includeEnrichedContext:\n typeof planRecord.includeEnrichedContext === \"boolean\"\n ? planRecord.includeEnrichedContext\n : (() => {\n throw new Error(\"Canonical refresh completion enriched context intent is invalid\");\n })(),\n chainUnderlyings: normalizedSymbols(\n planRecord.chainUnderlyings as string[],\n \"plan.chainUnderlyings\",\n ),\n quoteUnderlyings: normalizedSymbols(\n planRecord.quoteUnderlyings as string[],\n \"plan.quoteUnderlyings\",\n ),\n openInterestUnderlyings: normalizedSymbols(\n planRecord.openInterestUnderlyings as string[],\n \"plan.openInterestUnderlyings\",\n ),\n ...(planRecord.provider === undefined\n ? {}\n : planRecord.provider === \"massive\" || planRecord.provider === \"thetadata\"\n ? { provider: planRecord.provider }\n : (() => {\n throw new Error(\"Canonical refresh completion provider is invalid\");\n })()),\n };\n validateDerivedPlanInputs(plan);\n if (!isXnysSessionDate(plan.asOf) || expectedInventory(plan).length === 0) {\n throw new Error(\"Canonical refresh completion plan is empty or outside the calendar\");\n }\n if (!Array.isArray(record.operations) || record.operations.length === 0) {\n throw new Error(\"Canonical refresh completion operations must be a non-empty array\");\n }\n const operations = record.operations.map((entry, index) => {\n if (entry === null || typeof entry !== \"object\" || Array.isArray(entry)) {\n throw new Error(`Canonical refresh completion operations[${index}] must be an object`);\n }\n const operation = entry as Record<string, unknown>;\n if (\n canonicalJson(Object.keys(operation).sort(compareCodePoints)) !==\n canonicalJson([\"kind\", \"rowsWritten\", \"status\", \"target\"])\n ) {\n throw new Error(`Canonical refresh completion operations[${index}] has invalid fields`);\n }\n if (\n operation.kind !== \"spot\" &&\n operation.kind !== \"chain\" &&\n operation.kind !== \"quotes\" &&\n operation.kind !== \"open-interest\"\n ) {\n throw new Error(`Canonical refresh completion operations[${index}] kind is invalid`);\n }\n const target = normalizedSymbols(\n [operation.target as string],\n `operations[${index}].target`,\n )[0];\n if (\n operation.status !== \"ok\" ||\n !Number.isSafeInteger(operation.rowsWritten) ||\n (operation.rowsWritten as number) <= 0\n ) {\n throw new Error(`Canonical refresh completion operations[${index}] is not terminal`);\n }\n return {\n kind: operation.kind as CanonicalRefreshOperationV1[\"kind\"],\n target,\n status: \"ok\" as const,\n rowsWritten: operation.rowsWritten as number,\n };\n });\n operations.sort((left, right) => compareCodePoints(operationKey(left), operationKey(right)));\n if (canonicalJson(operations.map(operationKey)) !== canonicalJson(expectedOperationKeys(plan))) {\n throw new Error(\"Canonical refresh completion operations disagree with its plan\");\n }\n if (!Array.isArray(record.quoteGroups)) {\n throw new Error(\"Canonical refresh completion quoteGroups must be an array\");\n }\n const quoteGroups = record.quoteGroups.map((entry, index) => {\n if (entry === null || typeof entry !== \"object\" || Array.isArray(entry)) {\n throw new Error(`Canonical refresh completion quoteGroups[${index}] must be an object`);\n }\n const group = entry as Record<string, unknown>;\n if (\n canonicalJson(Object.keys(group).sort(compareCodePoints)) !==\n canonicalJson([\"completedContracts\", \"date\", \"right\", \"root\", \"totalContracts\", \"underlying\"])\n ) {\n throw new Error(`Canonical refresh completion quoteGroups[${index}] has invalid fields`);\n }\n const underlying = normalizedSymbols(\n [group.underlying as string],\n `quoteGroups[${index}].underlying`,\n )[0];\n const root = normalizedSymbols([group.root as string], `quoteGroups[${index}].root`)[0];\n if (\n (group.right !== \"call\" && group.right !== \"put\") ||\n group.date !== plan.asOf ||\n !Number.isSafeInteger(group.completedContracts) ||\n !Number.isSafeInteger(group.totalContracts) ||\n (group.completedContracts as number) < 0 ||\n group.completedContracts !== group.totalContracts\n ) {\n throw new Error(`Canonical refresh completion quoteGroups[${index}] is not terminal`);\n }\n return {\n underlying,\n root,\n right: group.right as CanonicalRefreshQuoteGroupV1[\"right\"],\n date: plan.asOf,\n completedContracts: group.completedContracts as number,\n totalContracts: group.totalContracts as number,\n };\n });\n quoteGroups.sort((left, right) =>\n compareCodePoints(\n `${left.underlying}:${left.root}:${left.right}`,\n `${right.underlying}:${right.root}:${right.right}`,\n ),\n );\n const expectedQuoteGroups = plan.quoteUnderlyings\n .flatMap((underlying) =>\n bulkQuoteRootsForUnderlying(underlying).flatMap((root) => [\n `${underlying}:${root}:call`,\n `${underlying}:${root}:put`,\n ]),\n )\n .sort(compareCodePoints);\n if (\n canonicalJson(\n quoteGroups.map((group) => `${group.underlying}:${group.root}:${group.right}`),\n ) !== canonicalJson(expectedQuoteGroups)\n ) {\n throw new Error(\"Canonical refresh completion quoteGroups disagree with its plan\");\n }\n if (!Array.isArray(record.receipts) || record.receipts.length === 0) {\n throw new Error(\"Canonical refresh completion receipts must be a non-empty array\");\n }\n const receipts = record.receipts.map((entry, index) => {\n if (entry === null || typeof entry !== \"object\" || Array.isArray(entry)) {\n throw new Error(`Canonical refresh completion receipts[${index}] must be an object`);\n }\n const receipt = entry as Record<string, unknown>;\n if (\n canonicalJson(Object.keys(receipt).sort(compareCodePoints)) !==\n canonicalJson([\"dataset\", \"partition\", \"receipt\"])\n ) {\n throw new Error(`Canonical refresh completion receipts[${index}] has invalid fields`);\n }\n const normalized: CanonicalRefreshReceiptV1 = {\n dataset: String(receipt.dataset),\n partition: receipt.partition as Record<string, string>,\n receipt: receipt.receipt as CanonicalJsonAddress,\n };\n validatePartitionIdentity(normalized);\n parseCanonicalJsonAddress(normalized.receipt);\n return normalized;\n });\n receipts.sort((left, right) => compareCodePoints(identityKey(left), identityKey(right)));\n const normalized = {\n kind: CANONICAL_REFRESH_COMPLETION_KIND,\n version: CANONICAL_REFRESH_COMPLETION_VERSION,\n attemptId,\n closure: record.closure as CanonicalJsonAddress,\n plan,\n operations,\n quoteGroups,\n receipts,\n };\n if (!canonicalJsonBytes(normalized).equals(canonicalJsonBytes(value))) {\n throw new Error(\"Canonical refresh completion is not normalized\");\n }\n return normalized;\n}\n\nexport async function verifyCanonicalRefreshCompletion(\n partitions: FilePartitionCommitStore,\n completionAddress: CanonicalJsonAddress,\n): Promise<PutContentObjectResult<CanonicalRefreshCompletionV2>> {\n parseCanonicalJsonAddress(completionAddress);\n await verifyRefreshCompletionAuthority(partitions, completionAddress);\n const stored = await partitions.objects.get<unknown>(completionAddress);\n const completion = normalizeCompletion(stored);\n const closureInventory = await closureTailInventory(\n partitions,\n completion.closure,\n completion.plan.asOf,\n );\n const expected = new Set(expectedInventory(completion.plan).map(identityKey));\n if (\n canonicalJson([...expected].sort(compareCodePoints)) !==\n canonicalJson(closureInventory.map(identityKey))\n ) {\n throw new Error(\"Canonical refresh plan does not equal the closure cutoff-tail inventory\");\n }\n const observed = new Set<string>();\n const receiptRows = new Map<string, number>();\n for (const reference of completion.receipts) {\n const key = identityKey(reference);\n if (observed.has(key)) throw new Error(\"Canonical refresh completion has duplicate receipts\");\n observed.add(key);\n const commit = await partitions.readCommit(reference.receipt);\n if (identityKey(commit.receipt) !== key) {\n throw new Error(\"Canonical refresh receipt reference disagrees with its stored receipt\");\n }\n await validateCurrentReceipt(partitions, completion.plan, commit);\n receiptRows.set(key, commit.receipt.file.rows);\n }\n if (expected.size !== observed.size || [...expected].some((key) => !observed.has(key))) {\n throw new Error(\"Canonical refresh completion does not cover its producer inventory\");\n }\n for (const operation of completion.operations) {\n const rows = receiptRows.get(identityKey(operationIdentity(operation, completion.plan.asOf)));\n if (rows !== operation.rowsWritten) {\n throw new Error(\"Canonical refresh terminal rows disagree with the exact-byte receipt\");\n }\n }\n return {\n address: completionAddress,\n bytes: canonicalJsonBytes(completion).byteLength,\n value: completion,\n path: partitions.objects.objectPath(completionAddress),\n created: false,\n };\n}\n\nasync function publishCompletion(\n partitions: FilePartitionCommitStore,\n closure: CanonicalJsonAddress,\n plan: CanonicalRefreshPlanV2,\n attempt: PartitionCommitAttemptResult<BoundedRefreshResult>,\n): Promise<PutContentObjectResult<CanonicalRefreshCompletionV2>> {\n validateAttemptInventory(plan, attempt);\n for (const commit of attempt.receipts) {\n await validateCurrentReceipt(partitions, plan, commit);\n }\n const completion = await partitions.objects.put<CanonicalRefreshCompletionV2>({\n kind: CANONICAL_REFRESH_COMPLETION_KIND,\n version: CANONICAL_REFRESH_COMPLETION_VERSION,\n attemptId: attempt.attemptId,\n closure,\n plan,\n operations: terminalOperations(plan, attempt.value.perOperation),\n quoteGroups: attempt.value.quoteGroups,\n receipts: attempt.receipts.map(receiptValue),\n });\n await publishRefreshCompletionAuthority(partitions, completion.address);\n await verifyCanonicalRefreshCompletion(partitions, completion.address);\n return completion;\n}\n\n/** Producer-owned bounded refresh + completion + cutoff publication path. */\nexport async function runCanonicalProvenanceRefresh(\n ingestor: MarketIngestor,\n deps: MarketIngestorDeps,\n input: ProvenanceRefreshInput,\n): Promise<RefreshResult> {\n // Snapshot semantic caller fields before the first await. The progress\n // callback is operational only and is deliberately excluded from identity.\n const authority = normalizeAuthority(input.provenance);\n const basePlan = normalizePlan(input, deps);\n const onProgress = input.onProgress;\n const computeVixContext = input.computeVixContext ?? true;\n const marketRoot = path.join(path.resolve(deps.dataRoot), \"market\");\n const partitions = new FilePartitionCommitStore(marketRoot);\n const plan = await bindPlanToClosure(partitions, authority.closure, basePlan);\n if (plan.includeEnrichedContext && !computeVixContext) {\n throw new Error(\"Canonical closure requires enriched context but refresh disabled it\");\n }\n let vixContext: IngestResult | null = null;\n const attempt = await runPartitionCommitAttempt(\n { attemptId: authority.attemptId, recorder: partitions },\n async () => {\n const value = await runBoundedRefresh(ingestor, plan, onProgress);\n for (const ticker of plan.enrichedTickers) {\n await deps.stores.enriched.compute(ticker, plan.asOf, plan.asOf, {\n persistWatermark: false,\n });\n }\n if (plan.includeEnrichedContext) {\n await deps.stores.enriched.computeContext(plan.asOf, plan.asOf, {\n persistWatermark: false,\n });\n vixContext = {\n status: \"ok\",\n rowsWritten: 0,\n dateRange: { from: plan.asOf, to: plan.asOf },\n };\n }\n return value;\n },\n );\n const completion = await publishCompletion(partitions, authority.closure, plan, attempt);\n const watermarkTickers = new Set(plan.enrichedTickers);\n for (const ticker of [...watermarkTickers].sort(compareCodePoints)) {\n const current = await getEnrichedThrough(ticker, deps.dataRoot);\n await upsertEnrichedThrough(\n ticker,\n current && current > plan.asOf ? current : plan.asOf,\n deps.dataRoot,\n );\n }\n\n const cutoff = await finalizeCanonicalMarketDataCutoff(partitions, {\n closure: authority.closure,\n completeThrough: plan.asOf,\n refreshCompletion: completion.address,\n ...(authority.predecessor ? { predecessor: authority.predecessor } : {}),\n });\n await verifyCanonicalMarketDataCutoff(partitions, cutoff.address);\n const coverage = Object.fromEntries(\n plan.spotTickers.map((ticker) => [\n ticker,\n { totalDates: 1, dateRange: { from: plan.asOf, to: plan.asOf } },\n ]),\n );\n return {\n status: \"ok\",\n perOperation: { ...attempt.value.perOperation, vixContext },\n coverage,\n errors: [],\n provenance: {\n attemptId: attempt.attemptId,\n completion: completion.address,\n receipts: completion.value.receipts.map((receipt) => receipt.receipt),\n cutoff: cutoff.address,\n aggregateRoot: cutoff.value.aggregateRoot,\n },\n };\n}\n","/** Wire-level roots that ThetaData bulk quote ingestion expands an underlying into. */\nexport function bulkQuoteRootsForUnderlying(underlying: string): string[] {\n const upper = underlying.toUpperCase();\n return upper === \"SPX\" ? [\"SPX\", \"SPXW\"] : [upper];\n}\n\n/** Number of final root/right groups per date. */\nexport function countBulkQuoteGroupsPerDate(underlying: string): number {\n return bulkQuoteRootsForUnderlying(underlying).length * 2;\n}\n","/**\n * JSON Adapters for Metadata Stores\n *\n * Provides CRUD operations for five metadata stores backed by JSON files:\n * 1. Strategy profiles — per-block, per-strategy JSON files\n * 2. Sync metadata — per-block .sync-meta.json files\n * 3. Market import metadata — single aggregate file\n * 4. Flat import log — single aggregate file\n * 5. Enrichment watermarks — single aggregate file\n *\n * All adapters use json-store.ts for atomic write-then-rename operations.\n * File paths follow the canonical data-root layout.\n */\n\nimport * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport { z } from \"zod\";\nimport {\n readJsonFile,\n writeJsonFile,\n deleteJsonFile,\n listJsonFiles,\n toFileSlug,\n} from \"./json-store.ts\";\nimport { getDataRoot } from \"./data-root.ts\";\nimport type { StrategyProfile } from \"../models/strategy-profile.ts\";\nimport type { BlockSyncMetadata, MarketImportMetadata } from \"../sync/metadata.ts\";\n\n// =============================================================================\n// 1. Profile Adapter\n// Path: {blocksDir}/{blockId}/profiles/{toFileSlug(strategyName)}.json\n// =============================================================================\n\n/** Profile as stored in JSON (dates as ISO strings) */\ninterface ProfileJson extends Omit<StrategyProfile, \"createdAt\" | \"updatedAt\"> {\n createdAt: string;\n updatedAt: string;\n}\n\n/** Convert StrategyProfile to JSON-safe format */\nfunction profileToJson(profile: StrategyProfile): ProfileJson {\n return {\n ...profile,\n createdAt: profile.createdAt.toISOString(),\n updatedAt: profile.updatedAt.toISOString(),\n };\n}\n\n/** Convert JSON-stored profile back to StrategyProfile with Date objects */\nfunction jsonToProfile(json: ProfileJson): StrategyProfile {\n return {\n ...json,\n createdAt: new Date(json.createdAt),\n updatedAt: new Date(json.updatedAt),\n };\n}\n\n/** Resolve file path for a profile */\nfunction profilePath(blockId: string, strategyName: string, blocksDir: string): string {\n return path.join(blocksDir, blockId, \"profiles\", toFileSlug(strategyName) + \".json\");\n}\n\n/**\n * Create or update a profile JSON file.\n * Preserves existing createdAt on update; always sets new updatedAt.\n *\n * @param profile - Profile data (createdAt/updatedAt are managed automatically)\n * @param blocksDir - Root blocks directory\n * @returns The saved StrategyProfile with Date objects\n */\nexport async function upsertProfileJson(\n profile: Omit<StrategyProfile, \"createdAt\" | \"updatedAt\">,\n blocksDir: string,\n): Promise<StrategyProfile> {\n const filePath = profilePath(profile.blockId, profile.strategyName, blocksDir);\n const now = new Date();\n\n // Preserve existing createdAt\n const existing = await readJsonFile<ProfileJson>(filePath);\n const createdAt = existing ? new Date(existing.createdAt) : now;\n\n const full: StrategyProfile = {\n ...profile,\n createdAt,\n updatedAt: now,\n };\n\n await writeJsonFile(filePath, profileToJson(full));\n return full;\n}\n\n/**\n * Get a profile by blockId and strategy name.\n *\n * @returns StrategyProfile with Date objects, or null if not found\n */\nexport async function getProfileJson(\n blockId: string,\n strategyName: string,\n blocksDir: string,\n): Promise<StrategyProfile | null> {\n const filePath = profilePath(blockId, strategyName, blocksDir);\n const json = await readJsonFile<ProfileJson>(filePath);\n return json ? jsonToProfile(json) : null;\n}\n\n/**\n * List profiles for a block, or all profiles across all blocks.\n *\n * @param blocksDir - Root blocks directory\n * @param blockId - Optional block ID. If omitted, scans all block directories.\n * @returns Array of StrategyProfile with Date objects\n */\nexport async function listProfilesJson(\n blocksDir: string,\n blockId?: string,\n): Promise<StrategyProfile[]> {\n if (blockId) {\n const profileDir = path.join(blocksDir, blockId, \"profiles\");\n const files = await listJsonFiles(profileDir);\n const profiles: StrategyProfile[] = [];\n for (const file of files) {\n const json = await readJsonFile<ProfileJson>(file);\n if (json) profiles.push(jsonToProfile(json));\n }\n return profiles;\n }\n\n // Scan all block directories\n const profiles: StrategyProfile[] = [];\n let entries: import(\"fs\").Dirent[];\n try {\n entries = await fs.readdir(blocksDir, { withFileTypes: true });\n } catch {\n return [];\n }\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const blockProfiles = await listProfilesJson(blocksDir, entry.name);\n profiles.push(...blockProfiles);\n }\n return profiles;\n}\n\n/**\n * Delete a profile JSON file.\n *\n * @returns true if deleted, false if not found\n */\nexport async function deleteProfileJson(\n blockId: string,\n strategyName: string,\n blocksDir: string,\n): Promise<boolean> {\n const filePath = profilePath(blockId, strategyName, blocksDir);\n return deleteJsonFile(filePath);\n}\n\n// =============================================================================\n// 2. Sync Metadata Adapter\n// Path: {blocksDir}/{blockId}/.sync-meta.json\n// =============================================================================\n\n/** Sync metadata as stored in JSON (synced_at as ISO string) */\ninterface SyncMetadataJson extends Omit<BlockSyncMetadata, \"synced_at\"> {\n synced_at: string;\n}\n\n/** Convert BlockSyncMetadata to JSON-safe format */\nfunction syncMetaToJson(meta: BlockSyncMetadata): SyncMetadataJson {\n return {\n ...meta,\n synced_at: meta.synced_at.toISOString(),\n };\n}\n\n/** Convert JSON-stored sync metadata back to BlockSyncMetadata with Date */\nfunction jsonToSyncMeta(json: SyncMetadataJson): BlockSyncMetadata {\n return {\n ...json,\n synced_at: new Date(json.synced_at),\n };\n}\n\n/** Resolve file path for sync metadata */\nfunction syncMetaPath(blockId: string, blocksDir: string): string {\n return path.join(blocksDir, blockId, \".sync-meta.json\");\n}\n\n/**\n * Get sync metadata for a block.\n *\n * @returns BlockSyncMetadata with synced_at as Date, or null if not found\n */\nexport async function getSyncMetadataJson(\n blockId: string,\n blocksDir: string,\n): Promise<BlockSyncMetadata | null> {\n const filePath = syncMetaPath(blockId, blocksDir);\n const json = await readJsonFile<SyncMetadataJson>(filePath);\n return json ? jsonToSyncMeta(json) : null;\n}\n\n/**\n * Write sync metadata for a block.\n */\nexport async function upsertSyncMetadataJson(\n metadata: BlockSyncMetadata,\n blocksDir: string,\n): Promise<void> {\n const filePath = syncMetaPath(metadata.block_id, blocksDir);\n await writeJsonFile(filePath, syncMetaToJson(metadata));\n}\n\n/**\n * Delete sync metadata for a block.\n *\n * @returns true if deleted, false if not found\n */\nexport async function deleteSyncMetadataJson(blockId: string, blocksDir: string): Promise<boolean> {\n const filePath = syncMetaPath(blockId, blocksDir);\n return deleteJsonFile(filePath);\n}\n\n/**\n * Scan blocksDir for directories containing .sync-meta.json.\n *\n * @returns Array of block IDs that have sync metadata\n */\nexport async function getAllSyncedBlockIdsJson(blocksDir: string): Promise<string[]> {\n let entries: import(\"fs\").Dirent[];\n try {\n entries = await fs.readdir(blocksDir, { withFileTypes: true });\n } catch {\n return [];\n }\n\n const ids: string[] = [];\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const metaPath = syncMetaPath(entry.name, blocksDir);\n try {\n await fs.access(metaPath);\n ids.push(entry.name);\n } catch {\n // No .sync-meta.json in this directory\n }\n }\n return ids;\n}\n\n// =============================================================================\n// 3. Market Import Metadata Adapter\n// Path: {dataDir}/market-meta/sync-metadata.json\n// =============================================================================\n\n/** Market import metadata as stored in JSON (synced_at as ISO string) */\ntype MarketImportMetadataJson = Omit<MarketImportMetadata, \"synced_at\"> & { synced_at: string };\n\n/** Aggregate file shape for market import metadata */\ninterface MarketSyncMetadataFile {\n entries: Record<string, MarketImportMetadataJson>;\n}\n\n/** Build composite key for market import metadata */\nfunction marketMetaKey(source: string, ticker: string, targetTable: string): string {\n return `${source}|${ticker}|${targetTable}`;\n}\n\n/** Resolve file path for market import metadata aggregate file */\nfunction marketMetaFilePath(dataDir: string): string {\n return path.join(getDataRoot(dataDir), \"market-meta\", \"sync-metadata.json\");\n}\n\n/**\n * Get market import metadata for a specific source/ticker/table combination.\n *\n * @returns MarketImportMetadata with synced_at as Date, or null if not found\n */\nexport async function getMarketImportMetadataJson(\n source: string,\n ticker: string,\n targetTable: string,\n dataDir: string,\n): Promise<MarketImportMetadata | null> {\n const filePath = marketMetaFilePath(dataDir);\n const file = await readJsonFile<MarketSyncMetadataFile>(filePath);\n if (!file) return null;\n\n const key = marketMetaKey(source, ticker, targetTable);\n const entry = file.entries[key];\n if (!entry) return null;\n\n return {\n ...entry,\n synced_at: new Date(entry.synced_at),\n };\n}\n\n/**\n * Create or update market import metadata entry.\n * Reads the aggregate file, updates the entry, writes back atomically.\n */\nexport async function upsertMarketImportMetadataJson(\n metadata: MarketImportMetadata,\n dataDir: string,\n): Promise<void> {\n const filePath = marketMetaFilePath(dataDir);\n const file = (await readJsonFile<MarketSyncMetadataFile>(filePath)) ?? { entries: {} };\n\n const key = marketMetaKey(metadata.source, metadata.ticker, metadata.target_table);\n file.entries[key] = {\n ...metadata,\n synced_at: metadata.synced_at.toISOString(),\n };\n\n await writeJsonFile(filePath, file);\n}\n\n// =============================================================================\n// 4. Flat Import Log Adapter\n// Path: {dataDir}/market-meta/flat-import-log.json\n// =============================================================================\n\n/** Single entry in the flat import log */\nexport interface FlatImportLogEntry {\n date: string;\n asset_class: string;\n underlying: string;\n imported_at: string;\n bar_count: number;\n}\n\n/** Aggregate file shape for flat import log */\ninterface FlatImportLogFile {\n entries: FlatImportLogEntry[];\n}\n\n/** Build composite key for deduplication */\nfunction flatLogKey(entry: FlatImportLogEntry): string {\n return `${entry.date}|${entry.asset_class}|${entry.underlying}`;\n}\n\n/** Resolve file path for flat import log */\nfunction flatLogFilePath(dataDir: string): string {\n return path.join(getDataRoot(dataDir), \"market-meta\", \"flat-import-log.json\");\n}\n\n/**\n * Get imported dates from the flat import log, filtered by asset_class, underlying, and date range.\n *\n * @returns Set of imported date strings\n */\nexport async function getFlatImportLogJson(\n assetClass: string,\n underlying: string,\n from: string,\n to: string,\n dataDir: string,\n): Promise<Set<string>> {\n const filePath = flatLogFilePath(dataDir);\n const file = await readJsonFile<FlatImportLogFile>(filePath);\n if (!file) return new Set();\n\n const dates = new Set<string>();\n for (const entry of file.entries) {\n if (\n entry.asset_class === assetClass &&\n entry.underlying === underlying &&\n entry.date >= from &&\n entry.date <= to\n ) {\n dates.add(entry.date);\n }\n }\n return dates;\n}\n\n/**\n * Create or update a flat import log entry.\n * Replaces by composite key (date, asset_class, underlying).\n */\nexport async function upsertFlatImportLogJson(\n entry: FlatImportLogEntry,\n dataDir: string,\n): Promise<void> {\n const filePath = flatLogFilePath(dataDir);\n const file = (await readJsonFile<FlatImportLogFile>(filePath)) ?? { entries: [] };\n\n const key = flatLogKey(entry);\n const idx = file.entries.findIndex((e) => flatLogKey(e) === key);\n if (idx >= 0) {\n file.entries[idx] = entry;\n } else {\n file.entries.push(entry);\n }\n\n await writeJsonFile(filePath, file);\n}\n\n// =============================================================================\n// 5. Enrichment Watermarks Adapter\n// Path: {dataRoot}/market-meta/enrichment-watermarks.json\n//\n// Tracks per-ticker `enriched_through` watermark for the market enricher.\n// Replaces the legacy `market._sync_metadata.enriched_through` SQL\n// reads/writes. Backend-independent — the same JSON file is written\n// whether Parquet mode is true or false.\n//\n// Storage shape:\n// {\n// \"version\": 1,\n// \"watermarks\": {\n// \"SPX\": { \"enriched_through\": \"2026-04-15\" },\n// \"VIX\": { \"enriched_through\": \"2026-04-14\" }\n// }\n// }\n//\n// Each entry is an object (not a bare string) so future additions\n// (`wilder_state`, `synced_at`, `last_source`) do not require a schema bump.\n// =============================================================================\n\nconst TickerEntrySchema = z\n .object({\n // ISO calendar date `YYYY-MM-DD` or null when the ticker has been\n // registered but not yet enriched through any date.\n enriched_through: z\n .string()\n .regex(/^\\d{4}-\\d{2}-\\d{2}$/)\n .nullable(),\n })\n // Passthrough keeps forward compatibility — fields like `wilder_state` added\n // by future phases survive load/upsert round-trips without schema changes.\n .passthrough();\n\nexport const EnrichmentWatermarksSchema = z.object({\n version: z.literal(1),\n // Defense-in-depth ticker whitelist: mirrors the TICKER_RE used by\n // src/market/tickers/schemas.ts and rejects anything not shaped like a ticker.\n watermarks: z.record(z.string().regex(/^[A-Z0-9._-]+$/), TickerEntrySchema),\n});\n\nexport type EnrichmentWatermarks = z.infer<typeof EnrichmentWatermarksSchema>;\n\n/** Resolve file path for the aggregate enrichment-watermarks file. */\nfunction watermarksFilePath(dataDir: string): string {\n return path.join(getDataRoot(dataDir), \"market-meta\", \"enrichment-watermarks.json\");\n}\n\n/**\n * Load the enrichment watermarks file.\n *\n * Missing file resolves to an empty structure — absent means \"nothing\n * enriched yet\", not an error. Malformed JSON or schema violations throw a\n * clear error; we never silently reset to empty, which would lose data\n * invisibly.\n */\nexport async function loadEnrichmentWatermarks(dataDir: string): Promise<EnrichmentWatermarks> {\n const raw = await readJsonFile<unknown>(watermarksFilePath(dataDir));\n if (raw === null) return { version: 1, watermarks: {} };\n const parsed = EnrichmentWatermarksSchema.safeParse(raw);\n if (!parsed.success) {\n throw new Error(`enrichment-watermarks.json is malformed: ${parsed.error.message}`);\n }\n return parsed.data;\n}\n\n/**\n * Return the `enriched_through` date for a ticker, or null if no entry exists.\n *\n * Callers that treat \"missing entry\" and \"entry with null enriched_through\" the\n * same (most common case) can use the value directly; callers that need to\n * distinguish can read the raw file via `loadEnrichmentWatermarks`.\n */\nexport async function getEnrichedThrough(ticker: string, dataDir: string): Promise<string | null> {\n const { watermarks } = await loadEnrichmentWatermarks(dataDir);\n return watermarks[ticker]?.enriched_through ?? null;\n}\n\n/**\n * Upsert a ticker's `enriched_through` date.\n *\n * Preserves other tickers' entries and any passthrough fields (e.g.,\n * `wilder_state`) already stored on the target ticker.\n *\n * Concurrency note: atomic at the FS level (tmp+rename via writeJsonFile);\n * this is NOT read-modify-write atomic at the application level. Serial\n * callers (the current enricher flow) are safe. If concurrent enrichers of\n * different tickers become real, add an async-mutex.\n */\nexport async function upsertEnrichedThrough(\n ticker: string,\n enrichedThrough: string,\n dataDir: string,\n): Promise<void> {\n const current = await loadEnrichmentWatermarks(dataDir);\n current.watermarks[ticker] = {\n ...(current.watermarks[ticker] ?? {}),\n enriched_through: enrichedThrough,\n };\n await writeJsonFile(watermarksFilePath(dataDir), current);\n}\n","import type { Trade } from \"../models/trade.ts\";\nimport type { DailyLogEntry } from \"../models/daily-log.ts\";\nimport type {\n WalkForwardConfig,\n WalkForwardComputation,\n WalkForwardParameterRanges,\n WalkForwardPeriodResult,\n WalkForwardProgressEvent,\n WalkForwardResults,\n WalkForwardSummary,\n WalkForwardWindow,\n PerformanceFloorConfig,\n DiversificationConfig,\n PeriodDiversificationMetrics,\n SkippedWindow,\n} from \"../models/walk-forward.ts\";\nimport { PortfolioStatsCalculator } from \"./portfolio-stats.ts\";\nimport { calculateKellyMetrics } from \"./kelly.ts\";\nimport type { PortfolioStats } from \"../models/portfolio-stats.ts\";\nimport {\n calculateCorrelationMatrix,\n calculateCorrelationAnalytics,\n type CorrelationOptions,\n} from \"./correlation.ts\";\nimport { performTailRiskAnalysis } from \"./tail-risk-analysis.ts\";\nimport type { TailRiskAnalysisOptions } from \"../models/tail-risk.ts\";\nimport { getNetPl } from \"../utils/equity-curve.ts\";\nimport { formatDateKey } from \"./trade-matching.ts\";\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\nconst DEFAULT_MIN_IN_SAMPLE_TRADES = 10;\nconst DEFAULT_MIN_OUT_SAMPLE_TRADES = 3;\nconst DEFAULT_FIXED_FRACTION_PCT = 2;\nconst MAX_PARAMETER_COMBINATIONS = 20000;\nconst YIELD_EVERY = 50;\n\ninterface AnalyzeOptions {\n trades: Trade[];\n /**\n * Daily portfolio logs. Reserved for future use to enable more accurate\n * equity curve calculations during walk-forward periods. Currently unused.\n */\n dailyLogs?: DailyLogEntry[];\n config: WalkForwardConfig;\n signal?: AbortSignal;\n onProgress?: (event: WalkForwardProgressEvent) => void;\n}\n\ninterface ScalingBaseline {\n baseKellyFraction: number;\n avgContracts: number;\n}\n\ninterface CombinationIterator {\n values: Array<Record<string, number>>;\n count: number;\n}\n\nexport class WalkForwardAnalyzer {\n // Cache for trade timestamps to avoid repeated Date parsing\n private tradeTimestampCache = new Map<Trade, number>();\n\n private getTradeTimestamp(trade: Trade): number {\n let ts = this.tradeTimestampCache.get(trade);\n if (ts === undefined) {\n ts = new Date(trade.dateOpened).getTime();\n this.tradeTimestampCache.set(trade, ts);\n }\n return ts;\n }\n\n async analyze(options: AnalyzeOptions): Promise<WalkForwardComputation> {\n this.ensureValidConfig(options.config);\n\n // Clear cache for new analysis\n this.tradeTimestampCache.clear();\n\n const sortedTrades = this.sortTrades(options.trades);\n const calculator = new PortfolioStatsCalculator();\n const startedAt = new Date();\n\n if (sortedTrades.length === 0) {\n const emptyResults = this.buildResults(\n [],\n options.config,\n 0,\n 0,\n sortedTrades.length,\n startedAt,\n );\n return {\n config: options.config,\n results: emptyResults,\n startedAt,\n completedAt: new Date(),\n };\n }\n\n const skippedWindows: SkippedWindow[] = [];\n const windows = this.buildWindows(sortedTrades, options.config, skippedWindows);\n options.onProgress?.({\n phase: \"segmenting\",\n currentPeriod: 0,\n totalPeriods: windows.length,\n message: `Prepared ${windows.length} optimization windows`,\n });\n\n const periods: WalkForwardPeriodResult[] = [];\n let totalParameterTests = 0;\n\n for (let index = 0; index < windows.length; index++) {\n this.throwIfAborted(options.signal);\n\n const window = windows[index];\n const inSampleTrades = this.filterTrades(\n sortedTrades,\n window.inSampleStart,\n window.inSampleEnd,\n );\n const outSampleTrades = this.filterTrades(\n sortedTrades,\n window.outOfSampleStart,\n window.outOfSampleEnd,\n );\n\n const minInSample = options.config.minInSampleTrades ?? DEFAULT_MIN_IN_SAMPLE_TRADES;\n const minOutSample = options.config.minOutOfSampleTrades ?? DEFAULT_MIN_OUT_SAMPLE_TRADES;\n\n if (inSampleTrades.length < minInSample || outSampleTrades.length < minOutSample) {\n const reason =\n inSampleTrades.length < minInSample\n ? (\"insufficient_is_trades\" as const)\n : (\"insufficient_oos_trades\" as const);\n const detail =\n inSampleTrades.length < minInSample\n ? `${inSampleTrades.length} IS trades < min ${minInSample}`\n : `${outSampleTrades.length} OOS trades < min ${minOutSample}`;\n skippedWindows.push({ ...window, reason, detail });\n continue;\n }\n\n const combinationIterator = this.buildCombinationIterator(\n options.config.parameterRanges || {},\n );\n if (combinationIterator.count > MAX_PARAMETER_COMBINATIONS) {\n throw new Error(\n `Walk-forward parameter grid too large (${combinationIterator.count.toLocaleString()} combinations). ` +\n `Reduce ranges or increase step sizes.`,\n );\n }\n\n options.onProgress?.({\n phase: \"optimizing\",\n currentPeriod: index + 1,\n totalPeriods: windows.length,\n totalCombinations: combinationIterator.count,\n testedCombinations: 0,\n window,\n });\n\n const baseline = this.buildScalingBaseline(inSampleTrades);\n const inSampleInitialCapital =\n PortfolioStatsCalculator.calculateInitialCapital(inSampleTrades);\n const outSampleInitialCapital =\n PortfolioStatsCalculator.calculateInitialCapital(outSampleTrades);\n\n let tested = 0;\n let bestCombo: {\n params: Record<string, number>;\n inSampleStats: PortfolioStats;\n score: number;\n } | null = null;\n\n // Check if diversification constraints need to be enforced during optimization\n const diversificationConfig = options.config.diversificationConfig;\n const enforceDiversificationConstraints =\n diversificationConfig?.enableCorrelationConstraint ||\n diversificationConfig?.enableTailRiskConstraint;\n\n for (const params of combinationIterator.values) {\n this.throwIfAborted(options.signal);\n tested++;\n\n const scaledInSampleTrades = this.applyScenario(\n inSampleTrades,\n params,\n baseline,\n inSampleInitialCapital,\n );\n const inSampleStats = calculator.calculatePortfolioStats(scaledInSampleTrades);\n\n if (\n !this.isRiskAcceptable(\n params,\n inSampleStats,\n scaledInSampleTrades,\n options.config.performanceFloor,\n )\n ) {\n continue;\n }\n\n // Check diversification constraints if enabled\n // This rejects parameter combinations where strategies are too correlated\n // or have excessive tail dependence during the in-sample period\n if (enforceDiversificationConstraints && diversificationConfig) {\n const inSampleDivMetrics = this.calculateDiversificationMetrics(\n scaledInSampleTrades,\n diversificationConfig,\n );\n if (\n inSampleDivMetrics &&\n !this.isDiversificationAcceptable(inSampleDivMetrics, diversificationConfig)\n ) {\n continue;\n }\n }\n\n const targetValue = this.getTargetMetricValue(\n inSampleStats,\n options.config.optimizationTarget,\n );\n if (!Number.isFinite(targetValue)) {\n continue;\n }\n\n if (!bestCombo || targetValue > bestCombo.score) {\n bestCombo = {\n params: { ...params },\n inSampleStats,\n score: targetValue,\n };\n }\n\n if (tested % YIELD_EVERY === 0) {\n await this.yieldToEventLoop();\n }\n\n options.onProgress?.({\n phase: \"optimizing\",\n currentPeriod: index + 1,\n totalPeriods: windows.length,\n totalCombinations: combinationIterator.count,\n testedCombinations: tested,\n window,\n });\n }\n\n totalParameterTests += tested;\n\n if (!bestCombo) {\n skippedWindows.push({\n ...window,\n reason: \"no_viable_params\",\n detail: `All ${combinationIterator.count} combo${combinationIterator.count === 1 ? \"\" : \"s\"} rejected`,\n });\n continue;\n }\n\n const scaledOutSampleTrades = this.applyScenario(\n outSampleTrades,\n bestCombo.params,\n baseline,\n outSampleInitialCapital,\n );\n const outSampleStats = calculator.calculatePortfolioStats(scaledOutSampleTrades);\n\n // Calculate diversification metrics for OOS period if enabled\n let diversificationMetrics: PeriodDiversificationMetrics | undefined;\n if (enforceDiversificationConstraints && diversificationConfig) {\n const metrics = this.calculateDiversificationMetrics(\n scaledOutSampleTrades,\n diversificationConfig,\n );\n if (metrics) {\n diversificationMetrics = metrics;\n }\n }\n\n const period: WalkForwardPeriodResult = {\n ...window,\n optimalParameters: bestCombo.params,\n inSampleMetrics: bestCombo.inSampleStats,\n outOfSampleMetrics: outSampleStats,\n targetMetricInSample: bestCombo.score,\n targetMetricOutOfSample: this.getTargetMetricValue(\n outSampleStats,\n options.config.optimizationTarget,\n ),\n diversificationMetrics,\n };\n\n periods.push(period);\n\n options.onProgress?.({\n phase: \"evaluating\",\n currentPeriod: index + 1,\n totalPeriods: windows.length,\n testedCombinations: tested,\n totalCombinations: combinationIterator.count,\n window,\n });\n }\n\n const completedAt = new Date();\n const results = this.buildResults(\n periods,\n options.config,\n windows.length + (skippedWindows[0]?.reason === \"truncated_oos_window\" ? 1 : 0),\n totalParameterTests,\n sortedTrades.length,\n startedAt,\n completedAt,\n skippedWindows,\n );\n\n options.onProgress?.({\n phase: \"completed\",\n currentPeriod: windows.length,\n totalPeriods: windows.length,\n message: \"Walk-forward analysis complete\",\n });\n\n return {\n config: options.config,\n results,\n startedAt,\n completedAt,\n };\n }\n\n private ensureValidConfig(config: WalkForwardConfig): void {\n if (config.inSampleDays <= 0) {\n throw new Error(\"inSampleDays must be greater than zero\");\n }\n if (config.outOfSampleDays <= 0) {\n throw new Error(\"outOfSampleDays must be greater than zero\");\n }\n if (config.stepSizeDays <= 0) {\n throw new Error(\"stepSizeDays must be greater than zero\");\n }\n }\n\n private sortTrades(trades: Trade[]): Trade[] {\n return [...trades].sort((a, b) => {\n const dateA = this.getTradeTimestamp(a);\n const dateB = this.getTradeTimestamp(b);\n if (dateA !== dateB) return dateA - dateB;\n return (a.timeOpened || \"\").localeCompare(b.timeOpened || \"\");\n });\n }\n\n private filterTrades(trades: Trade[], start: Date, end: Date): Trade[] {\n const startMs = start.getTime();\n const endMs = end.getTime();\n return trades.filter((trade) => {\n const tradeDate = this.floorToUTCDate(new Date(trade.dateOpened)).getTime();\n return tradeDate >= startMs && tradeDate <= endMs;\n });\n }\n\n private buildWindows(\n trades: Trade[],\n config: WalkForwardConfig,\n skippedWindows: SkippedWindow[],\n ): WalkForwardWindow[] {\n if (trades.length === 0) return [];\n\n const firstDate = this.floorToUTCDate(new Date(trades[0].dateOpened));\n const lastDate = this.floorToUTCDate(new Date(trades[trades.length - 1].dateOpened));\n const windows: WalkForwardWindow[] = [];\n\n let cursor = firstDate.getTime();\n\n while (cursor < lastDate.getTime()) {\n const inSampleStart = new Date(cursor);\n const inSampleEnd = new Date(cursor + (config.inSampleDays - 1) * DAY_MS);\n const outOfSampleStart = new Date(inSampleEnd.getTime() + DAY_MS);\n const outOfSampleEnd = new Date(\n outOfSampleStart.getTime() + (config.outOfSampleDays - 1) * DAY_MS,\n );\n\n if (outOfSampleEnd > lastDate) {\n if (outOfSampleStart <= lastDate) {\n skippedWindows.push({\n inSampleStart,\n inSampleEnd,\n outOfSampleStart,\n outOfSampleEnd,\n reason: \"truncated_oos_window\",\n detail: `OOS end exceeds last trade date (${formatDateKey(new Date(trades[trades.length - 1].dateOpened))})`,\n });\n }\n break;\n }\n\n windows.push({\n inSampleStart,\n inSampleEnd,\n outOfSampleStart,\n outOfSampleEnd,\n });\n\n cursor += config.stepSizeDays * DAY_MS;\n }\n\n return windows;\n }\n\n private floorToUTCDate(date: Date): Date {\n return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));\n }\n\n private buildCombinationIterator(\n parameterRanges: WalkForwardParameterRanges,\n ): CombinationIterator {\n const entries = Object.entries(parameterRanges || {});\n if (entries.length === 0) {\n return { values: [{}], count: 1 };\n }\n\n const values = entries.map(([key, [min, max, step]]) => ({\n key,\n values: this.buildRangeValues(min, max, step),\n }));\n\n const combinations: Array<Record<string, number>> = [];\n\n const recurse = (index: number, current: Record<string, number>) => {\n if (index === values.length) {\n combinations.push({ ...current });\n return;\n }\n\n const entry = values[index];\n entry.values.forEach((value) => {\n current[entry.key] = value;\n recurse(index + 1, current);\n });\n };\n\n recurse(0, {});\n\n return { values: combinations, count: combinations.length };\n }\n\n private buildRangeValues(min: number, max: number, step: number): number[] {\n if (max < min) {\n throw new Error(`Invalid parameter range: max (${max}) must be >= min (${min}).`);\n }\n if (step <= 0) {\n throw new Error(`Invalid parameter step size (${step}). Step must be positive.`);\n }\n\n const values: number[] = [];\n const totalSteps = Math.floor((max - min) / step);\n for (let i = 0; i <= totalSteps; i++) {\n const value = min + i * step;\n values.push(Number(value.toFixed(6)));\n }\n\n if (!values.includes(Number(max.toFixed(6)))) {\n values.push(Number(max.toFixed(6)));\n }\n\n return values;\n }\n\n private buildScalingBaseline(trades: Trade[]): ScalingBaseline {\n const kellyMetrics = calculateKellyMetrics(trades);\n const avgContracts =\n trades.length > 0\n ? trades.reduce((sum, trade) => sum + Math.abs(trade.numContracts || 0), 0) / trades.length\n : 1;\n\n return {\n baseKellyFraction: kellyMetrics.fraction || 0,\n avgContracts: avgContracts > 0 ? avgContracts : 1,\n };\n }\n\n private applyScenario(\n trades: Trade[],\n params: Record<string, number>,\n baseline: ScalingBaseline,\n initialCapitalOverride?: number,\n ): Trade[] {\n if (trades.length === 0) return [];\n\n const initialCapital =\n typeof initialCapitalOverride === \"number\"\n ? initialCapitalOverride\n : PortfolioStatsCalculator.calculateInitialCapital(trades);\n\n const positionMultiplier = this.calculatePositionMultiplier(params, baseline);\n const strategyWeights = this.buildStrategyWeights(params);\n const hasStrategyWeights = Object.keys(strategyWeights).length > 0;\n\n // trades are already sorted from filterTrades() which preserves sortedTrades order\n let runningEquity = initialCapital;\n const scaledTrades: Trade[] = [];\n\n for (const trade of trades) {\n const strategyWeight = strategyWeights[this.normalizeStrategyKey(trade.strategy)] ?? 1;\n\n // Skip trades from strategies with zero weight (excluded from this combination)\n // This prevents zero-P/L trades from inflating trade counts and diluting metrics\n if (hasStrategyWeights && strategyWeight === 0) {\n continue;\n }\n\n const scale = positionMultiplier * strategyWeight;\n const scaledPl = trade.pl * scale;\n const scaledOpeningCommissions = trade.openingCommissionsFees * Math.abs(scale);\n const scaledClosingCommissions = trade.closingCommissionsFees * Math.abs(scale);\n const scaledNetPl = getNetPl({\n pl: scaledPl,\n plBasis: trade.plBasis,\n openingCommissionsFees: scaledOpeningCommissions,\n closingCommissionsFees: scaledClosingCommissions,\n });\n\n runningEquity += scaledNetPl;\n\n // Only include fields used by PortfolioStatsCalculator to reduce object copy overhead\n scaledTrades.push({\n pl: scaledPl,\n plBasis: trade.plBasis,\n dateOpened: trade.dateOpened,\n timeOpened: trade.timeOpened,\n dateClosed: trade.dateClosed,\n timeClosed: trade.timeClosed,\n fundsAtClose: runningEquity,\n openingCommissionsFees: scaledOpeningCommissions,\n closingCommissionsFees: scaledClosingCommissions,\n strategy: trade.strategy,\n } as Trade);\n }\n\n return scaledTrades;\n }\n\n private calculatePositionMultiplier(\n params: Record<string, number>,\n baseline: ScalingBaseline,\n ): number {\n let multiplier = 1;\n\n if (typeof params.kellyMultiplier === \"number\" && params.kellyMultiplier > 0) {\n multiplier *= params.kellyMultiplier;\n }\n\n if (typeof params.fixedFractionPct === \"number\" && params.fixedFractionPct > 0) {\n multiplier *= params.fixedFractionPct / DEFAULT_FIXED_FRACTION_PCT;\n }\n\n if (typeof params.fixedContracts === \"number\" && params.fixedContracts > 0) {\n const baseContracts = baseline.avgContracts > 0 ? baseline.avgContracts : 1;\n multiplier *= params.fixedContracts / baseContracts;\n }\n\n return Math.max(multiplier, 0);\n }\n\n private buildStrategyWeights(params: Record<string, number>): Record<string, number> {\n const weights: Record<string, number> = {};\n Object.entries(params).forEach(([key, value]) => {\n if (key.startsWith(\"strategy:\")) {\n const strategyName = key.slice(\"strategy:\".length);\n weights[this.normalizeStrategyKey(strategyName)] = Math.max(0, value);\n }\n });\n return weights;\n }\n\n private normalizeStrategyKey(strategy?: string): string {\n return (strategy || \"Unknown\").toLowerCase();\n }\n\n private isRiskAcceptable(\n params: Record<string, number>,\n stats: PortfolioStats,\n scaledTrades: Trade[],\n performanceFloor?: PerformanceFloorConfig,\n ): boolean {\n // Parameter-based risk constraints\n if (typeof params.maxDrawdownPct === \"number\" && stats.maxDrawdown > params.maxDrawdownPct) {\n return false;\n }\n\n if (typeof params.consecutiveLossLimit === \"number\") {\n const maxLosses = this.calculateMaxConsecutiveLosses(scaledTrades);\n if (maxLosses > params.consecutiveLossLimit) {\n return false;\n }\n }\n\n if (typeof params.maxDailyLossPct === \"number\") {\n const initialCapital = PortfolioStatsCalculator.calculateInitialCapital(scaledTrades);\n const maxDailyLoss = this.calculateMaxDailyLossPct(scaledTrades, initialCapital);\n if (maxDailyLoss > params.maxDailyLossPct) {\n return false;\n }\n }\n\n // Performance floor checks (Phase 2)\n if (performanceFloor) {\n if (performanceFloor.enableMinSharpe && performanceFloor.minSharpeRatio > 0) {\n const sharpe = stats.sharpeRatio ?? Number.NEGATIVE_INFINITY;\n if (sharpe < performanceFloor.minSharpeRatio) {\n return false;\n }\n }\n\n if (performanceFloor.enableMinProfitFactor && performanceFloor.minProfitFactor > 0) {\n const pf = stats.profitFactor ?? 0;\n if (pf < performanceFloor.minProfitFactor) {\n return false;\n }\n }\n\n if (performanceFloor.enablePositiveNetPl) {\n const netPl = stats.netPl ?? 0;\n if (netPl <= 0) {\n return false;\n }\n }\n }\n\n return true;\n }\n\n /**\n * Calculate diversification metrics for a set of trades\n * Returns null if there aren't enough strategies for meaningful analysis\n */\n private calculateDiversificationMetrics(\n trades: Trade[],\n config: DiversificationConfig,\n ): PeriodDiversificationMetrics | null {\n // Need at least 2 strategies for correlation/diversification analysis\n const strategies = new Set(trades.map((t) => t.strategy).filter(Boolean));\n if (strategies.size < 2) {\n return null;\n }\n\n // Build correlation options from config\n const correlationOptions: CorrelationOptions = {\n method: config.correlationMethod,\n normalization: config.normalization,\n dateBasis: config.dateBasis,\n alignment: \"shared\",\n timePeriod: \"daily\",\n };\n\n // Calculate correlation matrix\n const correlationMatrix = calculateCorrelationMatrix(trades, correlationOptions);\n const correlationAnalytics = calculateCorrelationAnalytics(correlationMatrix);\n\n // Calculate tail risk if enabled\n let tailRiskResult = null;\n if (config.enableTailRiskConstraint) {\n const tailRiskOptions: TailRiskAnalysisOptions = {\n tailThreshold: config.tailThreshold,\n normalization: config.normalization,\n dateBasis: config.dateBasis,\n };\n tailRiskResult = performTailRiskAnalysis(trades, tailRiskOptions);\n }\n\n // Handle NaN values for strongest correlation (occurs when no valid pairs)\n const maxCorrelation = Number.isNaN(correlationAnalytics.strongest.value)\n ? 0\n : correlationAnalytics.strongest.value;\n const maxCorrelationPair = correlationAnalytics.strongest.pair[0]\n ? correlationAnalytics.strongest.pair\n : ([\"\", \"\"] as [string, string]);\n\n // Calculate total pairs for this period\n const numStrategies = correlationMatrix.strategies.length;\n const totalPairs = (numStrategies * (numStrategies - 1)) / 2;\n\n return {\n avgCorrelation: Number.isNaN(correlationAnalytics.averageCorrelation)\n ? 0\n : correlationAnalytics.averageCorrelation,\n maxCorrelation,\n maxCorrelationPair,\n avgTailDependence: tailRiskResult?.analytics.averageJointTailRisk ?? 0,\n maxTailDependence: tailRiskResult?.analytics.highestJointTailRisk.value ?? 0,\n maxTailDependencePair: (tailRiskResult?.analytics.highestJointTailRisk.pair ?? [\"\", \"\"]) as [\n string,\n string,\n ],\n effectiveFactors: tailRiskResult?.effectiveFactors ?? correlationMatrix.strategies.length,\n highRiskPairsPct: tailRiskResult?.analytics.highRiskPairsPct ?? 0,\n // Track insufficient tail data for UI display\n insufficientTailDataPairs: tailRiskResult?.insufficientDataPairs ?? totalPairs,\n totalPairs,\n };\n }\n\n /**\n * Check if diversification constraints are met\n */\n private isDiversificationAcceptable(\n metrics: PeriodDiversificationMetrics,\n config: DiversificationConfig,\n ): boolean {\n // Check correlation constraint\n if (config.enableCorrelationConstraint) {\n if (metrics.maxCorrelation > config.maxCorrelationThreshold) {\n return false;\n }\n }\n\n // Check tail risk constraint\n if (config.enableTailRiskConstraint) {\n if (metrics.maxTailDependence > config.maxTailDependenceThreshold) {\n return false;\n }\n }\n\n return true;\n }\n\n private calculateMaxConsecutiveLosses(trades: Trade[]): number {\n let maxLosses = 0;\n let currentLosses = 0;\n\n // trades are already sorted from applyScenario()\n trades.forEach((trade) => {\n if (trade.pl < 0) {\n currentLosses++;\n maxLosses = Math.max(maxLosses, currentLosses);\n } else {\n currentLosses = 0;\n }\n });\n\n return maxLosses;\n }\n\n private calculateMaxDailyLossPct(trades: Trade[], initialCapital: number): number {\n if (initialCapital === 0) return 0;\n\n const lossesByDay = new Map<string, number>();\n\n trades.forEach((trade) => {\n const dateKey = this.normalizeDateKey(trade.dateClosed || trade.dateOpened);\n lossesByDay.set(dateKey, (lossesByDay.get(dateKey) || 0) + trade.pl);\n });\n\n let maxLossPct = 0;\n\n lossesByDay.forEach((pl) => {\n if (pl < 0) {\n const lossPct = (Math.abs(pl) / initialCapital) * 100;\n maxLossPct = Math.max(maxLossPct, lossPct);\n }\n });\n\n return maxLossPct;\n }\n\n private normalizeDateKey(date: Date | string): string {\n return formatDateKey(new Date(date));\n }\n\n private getTargetMetricValue(\n stats: PortfolioStats,\n target: WalkForwardConfig[\"optimizationTarget\"],\n ): number {\n switch (target) {\n case \"profitFactor\":\n return stats.profitFactor ?? Number.NEGATIVE_INFINITY;\n case \"sharpeRatio\":\n return stats.sharpeRatio ?? Number.NEGATIVE_INFINITY;\n case \"sortinoRatio\":\n return stats.sortinoRatio ?? Number.NEGATIVE_INFINITY;\n case \"calmarRatio\":\n return stats.calmarRatio ?? Number.NEGATIVE_INFINITY;\n case \"cagr\":\n return stats.cagr ?? Number.NEGATIVE_INFINITY;\n case \"avgDailyPl\":\n return stats.avgDailyPl ?? Number.NEGATIVE_INFINITY;\n case \"winRate\":\n return stats.winRate ?? Number.NEGATIVE_INFINITY;\n // Diversification targets are not yet supported for optimization\n // They require computing correlation/tail risk for EACH parameter combination\n // which is expensive. For now, they're used as constraints, not targets.\n case \"minAvgCorrelation\":\n case \"minTailRisk\":\n case \"maxEffectiveFactors\":\n return Number.NEGATIVE_INFINITY;\n case \"netPl\":\n default:\n return stats.netPl ?? Number.NEGATIVE_INFINITY;\n }\n }\n\n private async yieldToEventLoop(): Promise<void> {\n await new Promise((resolve) => setTimeout(resolve, 0));\n }\n\n private throwIfAborted(signal?: AbortSignal): void {\n if (signal?.aborted) {\n throw new Error(\"Walk-forward analysis aborted\");\n }\n }\n\n private buildResults(\n periods: WalkForwardPeriodResult[],\n config: WalkForwardConfig,\n totalPeriods: number,\n totalParameterTests: number,\n analyzedTrades: number,\n startedAt: Date,\n completedAt: Date = new Date(),\n skippedWindows: SkippedWindow[] = [],\n ): WalkForwardResults {\n const summary = this.calculateSummary(periods);\n const stats = {\n totalPeriods,\n evaluatedPeriods: periods.length,\n skippedPeriods: skippedWindows.length,\n totalParameterTests,\n analyzedTrades,\n durationMs: completedAt.getTime() - startedAt.getTime(),\n consistencyScore: this.calculateConsistencyScore(periods),\n averagePerformanceDelta: this.calculateAveragePerformanceDelta(periods),\n };\n\n const robustnessScore = this.calculateRobustnessScore(summary, stats.consistencyScore);\n\n return {\n periods,\n skippedWindows,\n summary: { ...summary, robustnessScore },\n stats,\n };\n }\n\n /**\n * Calculates summary metrics for walk-forward analysis results.\n *\n * The `degradationFactor` (efficiency ratio) compares out-of-sample to in-sample performance.\n * This is equivalent to Walk Forward Efficiency (WFE) from Pardo's methodology.\n *\n * **Why we don't annualize:** Unlike raw return comparisons, we compare the same target metric\n * (e.g., Sharpe Ratio to Sharpe Ratio, or Net P&L to Net P&L) across IS and OOS periods.\n * Ratio metrics like Sharpe already normalize for time. Annualization would be appropriate\n * for comparing raw dollar returns across different period lengths, but our optimization\n * targets are typically normalized metrics. The Pardo annualization formula applies to\n * raw profit comparisons, not ratio-based target metrics.\n *\n * Formula: `degradationFactor = avgOutOfSamplePerformance / avgInSamplePerformance`\n * - 1.0 = OOS matches IS perfectly (rare)\n * - 0.8 = OOS retains 80% of IS performance (good)\n * - 0.5 = OOS retains 50% of IS performance (concerning)\n *\n * @see Pardo, Robert. \"The Evaluation and Optimization of Trading Strategies\" (2008)\n */\n private calculateSummary(periods: WalkForwardPeriodResult[]): WalkForwardSummary {\n if (periods.length === 0) {\n return {\n avgInSamplePerformance: 0,\n avgOutOfSamplePerformance: 0,\n degradationFactor: 0,\n parameterStability: 0,\n robustnessScore: 0,\n };\n }\n\n const inSampleValues = periods\n .map((p) => p.targetMetricInSample)\n .filter((value) => Number.isFinite(value));\n const outSampleValues = periods\n .map((p) => p.targetMetricOutOfSample)\n .filter((value) => Number.isFinite(value));\n\n const avgInSample =\n inSampleValues.length > 0\n ? inSampleValues.reduce((sum, value) => sum + value, 0) / inSampleValues.length\n : 0;\n const avgOutSample =\n outSampleValues.length > 0\n ? outSampleValues.reduce((sum, value) => sum + value, 0) / outSampleValues.length\n : 0;\n\n const degradationFactor = avgInSample !== 0 ? avgOutSample / avgInSample : 0;\n const parameterStability = this.calculateParameterStability(periods);\n\n const summary: WalkForwardSummary = {\n avgInSamplePerformance: avgInSample,\n avgOutOfSamplePerformance: avgOutSample,\n degradationFactor,\n parameterStability,\n robustnessScore: 0,\n };\n\n // Aggregate diversification metrics across periods\n const periodsWithDiversification = periods.filter((p) => p.diversificationMetrics);\n if (periodsWithDiversification.length > 0) {\n summary.avgCorrelationAcrossPeriods =\n periodsWithDiversification.reduce(\n (sum, p) => sum + (p.diversificationMetrics?.avgCorrelation ?? 0),\n 0,\n ) / periodsWithDiversification.length;\n\n summary.avgTailDependenceAcrossPeriods =\n periodsWithDiversification.reduce(\n (sum, p) => sum + (p.diversificationMetrics?.avgTailDependence ?? 0),\n 0,\n ) / periodsWithDiversification.length;\n\n summary.avgEffectiveFactors =\n periodsWithDiversification.reduce(\n (sum, p) => sum + (p.diversificationMetrics?.effectiveFactors ?? 0),\n 0,\n ) / periodsWithDiversification.length;\n }\n\n return summary;\n }\n\n /**\n * Calculates parameter stability across walk-forward periods using coefficient of variation.\n *\n * For each optimized parameter, we calculate how much the optimal value varied\n * across periods. Lower variance = higher stability = more robust parameters.\n *\n * **Statistical approach:**\n * - Uses sample variance (N-1 denominator) rather than population variance (N)\n * - Sample variance is preferred for small samples (N<30) per standard statistical practice\n * - The coefficient of variation (CV = stdDev/mean) normalizes across different parameter scales\n * - CV is inverted to produce a 0-1 stability score (1 = perfectly stable, 0 = highly variable)\n *\n * **Interpretation:**\n * - CV < 0.3 (30%): Parameter is stable across periods\n * - CV >= 0.3: Parameter shows meaningful variation (potential over-optimization risk)\n *\n * @returns Stability score between 0 and 1, where 1 indicates perfectly stable parameters\n */\n private calculateParameterStability(periods: WalkForwardPeriodResult[]): number {\n if (periods.length <= 1) return 1;\n\n const parameterKeys = new Set<string>();\n periods.forEach((period) => {\n Object.keys(period.optimalParameters).forEach((key) => parameterKeys.add(key));\n });\n\n if (parameterKeys.size === 0) return 1;\n\n const stabilityScores: number[] = [];\n\n parameterKeys.forEach((key) => {\n const values = periods\n .map((period) => period.optimalParameters[key])\n .filter((value): value is number => typeof value === \"number\");\n\n if (values.length <= 1) {\n stabilityScores.push(1);\n return;\n }\n\n const mean = values.reduce((sum, value) => sum + value, 0) / values.length;\n // Use sample variance (N-1) for small sample accuracy\n // Population variance (N) underestimates true variability for small samples\n const variance =\n values.reduce((sum, value) => sum + Math.pow(value - mean, 2), 0) / (values.length - 1);\n const stdDev = Math.sqrt(variance);\n\n // Normalize by mean to avoid requiring parameter ranges here\n const normalizedStd = mean !== 0 ? Math.min(Math.abs(stdDev / mean), 1) : Math.min(stdDev, 1);\n stabilityScores.push(1 - normalizedStd);\n });\n\n const avgStability =\n stabilityScores.reduce((sum, value) => sum + value, 0) / stabilityScores.length;\n return Math.min(Math.max(avgStability, 0), 1);\n }\n\n private calculateConsistencyScore(periods: WalkForwardPeriodResult[]): number {\n if (periods.length === 0) return 0;\n const profitable = periods.filter((period) => period.targetMetricOutOfSample >= 0);\n return profitable.length / periods.length;\n }\n\n private calculateAveragePerformanceDelta(periods: WalkForwardPeriodResult[]): number {\n if (periods.length === 0) return 0;\n const deltas = periods.map(\n (period) => period.targetMetricOutOfSample - period.targetMetricInSample,\n );\n return deltas.reduce((sum, delta) => sum + delta, 0) / deltas.length;\n }\n\n /**\n * Calculates a composite robustness score combining efficiency, stability, and consistency.\n *\n * **IMPORTANT:** This is a TradeBlocks-specific composite metric, NOT an industry-standard formula.\n * Individual platforms (MultiCharts, TradeStation, AmiBroker) use configurable weights and\n * thresholds rather than a single composite score. This metric provides a quick overview\n * but users should examine individual components for detailed analysis.\n *\n * **Components (equally weighted):**\n * 1. **Efficiency Score** (normalized degradation factor): How well OOS matched IS performance\n * - Degradation factor of 1.0 (100% retention) = efficiency score of 0.5\n * - Degradation factor of 2.0+ = efficiency score of 1.0 (capped)\n * - Based on Pardo's Walk Forward Efficiency concept\n *\n * 2. **Stability Score** (parameter stability): How consistent optimal parameters were\n * - Uses coefficient of variation (CV) per standard statistical practice\n * - Lower CV = higher stability\n *\n * 3. **Consistency Score**: Percentage of periods with non-negative OOS performance\n * - Similar to MultiCharts \"% Profitable Runs\" metric\n * - 70%+ considered good per MultiCharts robustness criteria\n *\n * Formula: `robustnessScore = (efficiencyScore + stabilityScore + consistencyScore) / 3`\n *\n * @returns Score between 0 and 1, where higher indicates more robust strategy\n */\n private calculateRobustnessScore(summary: WalkForwardSummary, consistencyScore: number): number {\n const efficiencyScore = this.normalize(summary.degradationFactor, 0, 2);\n const stabilityScore = Math.min(Math.max(summary.parameterStability, 0), 1);\n const consistency = Math.min(Math.max(consistencyScore, 0), 1);\n\n const score = (efficiencyScore + stabilityScore + consistency) / 3;\n return Math.min(Math.max(score, 0), 1);\n }\n\n private normalize(value: number, min: number, max: number): number {\n if (max === min) return 0;\n const clamped = Math.max(Math.min(value, max), min);\n return (clamped - min) / (max - min);\n }\n}\n","import { resolveSofrRateByKey, resolveTreasuryRateByKey } from \"@tradeblocks/lib\";\nimport type { PutContentObjectResult } from \"./content-object-store.ts\";\nimport type { ContentObjectStore } from \"./content-object-store.ts\";\nimport { isXnysSessionDate } from \"./xnys-session-calendar.ts\";\n\nexport const CANONICAL_RATE_SLICE_KIND = \"tradeblocks.market-data.rate-slice\" as const;\nexport const CANONICAL_RATE_SLICE_VERSION = 1 as const;\n\nexport type CanonicalRateDataClass = \"sofr_rates\" | \"treasury_rates\";\nexport type CanonicalRateSeries = \"sofr\" | \"treasury_3m\";\n\nexport interface CanonicalRateSliceV1 {\n kind: typeof CANONICAL_RATE_SLICE_KIND;\n version: typeof CANONICAL_RATE_SLICE_VERSION;\n series: CanonicalRateSeries;\n requestedDate: string;\n effectiveDate: string;\n annualRateBasisPoints: number;\n resolution: \"exact\" | \"prior\" | \"clamped-earliest\";\n}\n\nexport async function publishCanonicalRateSlice(\n objects: ContentObjectStore,\n dataClass: CanonicalRateDataClass,\n requestedDate: string,\n): Promise<PutContentObjectResult<CanonicalRateSliceV1>> {\n if (dataClass !== \"sofr_rates\" && dataClass !== \"treasury_rates\") {\n throw new TypeError(`Unsupported canonical rate data class: ${JSON.stringify(dataClass)}`);\n }\n if (!isXnysSessionDate(requestedDate)) {\n throw new TypeError(\n `Canonical rate slice date is not an XNYS session: ${JSON.stringify(requestedDate)}`,\n );\n }\n const resolved =\n dataClass === \"sofr_rates\"\n ? resolveSofrRateByKey(requestedDate)\n : resolveTreasuryRateByKey(requestedDate);\n if (resolved.resolution === \"clamped-earliest\") {\n throw new Error(\n `Canonical ${dataClass} input starts at ${resolved.effectiveDate}; ` +\n `refusing lookahead-shaped request for earlier session ${requestedDate}`,\n );\n }\n if (resolved.resolution === \"stale-after-latest\") {\n throw new Error(\n `Canonical ${dataClass} input is stale after ${resolved.effectiveDate}; ` +\n `refusing requested session ${requestedDate}`,\n );\n }\n return objects.put({\n kind: CANONICAL_RATE_SLICE_KIND,\n version: CANONICAL_RATE_SLICE_VERSION,\n series: dataClass === \"sofr_rates\" ? \"sofr\" : \"treasury_3m\",\n requestedDate: resolved.requestedDate,\n effectiveDate: resolved.effectiveDate,\n annualRateBasisPoints: resolved.annualRateBasisPoints,\n resolution: resolved.resolution,\n });\n}\n"],"mappings":"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","names":["address","fs","path","stat","address","createHash","randomUUID","fs","path","path","relativePath","stat","createHash","snapshot","randomUUID","ticket","resolve","address","stat","compareCodePoints","address","existsSync","path","path","path","createHash","fs","path","createHash","escapeSqlLiteral","syncDirectory","relativePath","escapeSqlLiteral","existsSync","constants","fs","path","observedKeys","relative","path","z","z","compareCodePoints","compareCodePoints","compareCodePoints","compareCodePoints","normalized","compareCodePoints","relativePath","resolverClass","stat","constants"]}
|