@secondlayer/shared 11.7.1 → 11.8.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.
Files changed (161) hide show
  1. package/dist/src/archive/copy-loader.d.ts +1 -1
  2. package/dist/src/archive/copy-loader.js +4 -20
  3. package/dist/src/archive/copy-loader.js.map +2 -2
  4. package/dist/src/archive/derived-stage-report.d.ts +1 -1
  5. package/dist/src/archive/derived-stage-report.js +3 -19
  6. package/dist/src/archive/derived-stage-report.js.map +2 -2
  7. package/dist/src/archive/disk-guard.d.ts +1 -1
  8. package/dist/src/archive/disk-guard.js +3 -19
  9. package/dist/src/archive/disk-guard.js.map +2 -2
  10. package/dist/src/archive/instance-diagnosis.d.ts +1 -1
  11. package/dist/src/archive/instance-diagnosis.js +6 -22
  12. package/dist/src/archive/instance-diagnosis.js.map +2 -2
  13. package/dist/src/archive/key-registry.d.ts +1 -1
  14. package/dist/src/archive/key-registry.js +12 -12
  15. package/dist/src/archive/key-registry.js.map +1 -1
  16. package/dist/src/archive/per-height-digest.d.ts +1 -1
  17. package/dist/src/archive/per-height-digest.js +3 -17
  18. package/dist/src/archive/per-height-digest.js.map +5 -5
  19. package/dist/src/archive/progress.d.ts +1 -1
  20. package/dist/src/archive/progress.js +4 -20
  21. package/dist/src/archive/progress.js.map +2 -2
  22. package/dist/src/archive/range-digest.d.ts +2 -3
  23. package/dist/src/archive/range-digest.js +4 -20
  24. package/dist/src/archive/range-digest.js.map +2 -2
  25. package/dist/src/archive/reference.d.ts +1 -1
  26. package/dist/src/archive/reference.js +14 -12
  27. package/dist/src/archive/reference.js.map +5 -5
  28. package/dist/src/archive/root-key.d.ts +1 -1
  29. package/dist/src/archive/root-key.js +3 -19
  30. package/dist/src/archive/root-key.js.map +2 -2
  31. package/dist/src/archive/semantic-digest-builder.d.ts +2 -3
  32. package/dist/src/archive/semantic-digest-builder.js +5 -19
  33. package/dist/src/archive/semantic-digest-builder.js.map +5 -5
  34. package/dist/src/archive/semantic-digest.d.ts +1 -1
  35. package/dist/src/archive/semantic-digest.js +4 -20
  36. package/dist/src/archive/semantic-digest.js.map +2 -2
  37. package/dist/src/archive/status.d.ts +1 -1
  38. package/dist/src/archive/status.js +4 -20
  39. package/dist/src/archive/status.js.map +2 -2
  40. package/dist/src/coverage/index.d.ts +1 -2
  41. package/dist/src/coverage/index.js +80 -96
  42. package/dist/src/coverage/index.js.map +2 -2
  43. package/dist/src/crypto/ed25519.d.ts +1 -1
  44. package/dist/src/crypto/ed25519.js +13 -13
  45. package/dist/src/crypto/ed25519.js.map +1 -1
  46. package/dist/src/crypto/hmac.d.ts +1 -1
  47. package/dist/src/crypto/hmac.js +9 -9
  48. package/dist/src/crypto/hmac.js.map +1 -1
  49. package/dist/src/crypto/secondlayer-webhook.d.ts +1 -1
  50. package/dist/src/crypto/secondlayer-webhook.js +14 -14
  51. package/dist/src/crypto/secondlayer-webhook.js.map +2 -2
  52. package/dist/src/crypto/secrets.d.ts +1 -1
  53. package/dist/src/crypto/secrets.js +15 -29
  54. package/dist/src/crypto/secrets.js.map +5 -5
  55. package/dist/src/crypto/standard-webhooks.d.ts +1 -1
  56. package/dist/src/crypto/standard-webhooks.js +3 -19
  57. package/dist/src/crypto/standard-webhooks.js.map +2 -2
  58. package/dist/src/db/index.d.ts +18 -19
  59. package/dist/src/db/index.js +40 -55
  60. package/dist/src/db/index.js.map +5 -5
  61. package/dist/src/db/jsonb.d.ts +1 -1
  62. package/dist/src/db/jsonb.js +3 -19
  63. package/dist/src/db/jsonb.js.map +2 -2
  64. package/dist/src/db/queries/chain-reorgs.d.ts +1 -2
  65. package/dist/src/db/queries/chain-reorgs.js +27 -42
  66. package/dist/src/db/queries/chain-reorgs.js.map +5 -5
  67. package/dist/src/db/queries/contracts.d.ts +1 -2
  68. package/dist/src/db/queries/contracts.js +9 -23
  69. package/dist/src/db/queries/contracts.js.map +5 -5
  70. package/dist/src/db/queries/instance.d.ts +1 -2
  71. package/dist/src/db/queries/instance.js +7 -23
  72. package/dist/src/db/queries/instance.js.map +2 -2
  73. package/dist/src/db/queries/integrity.d.ts +1 -2
  74. package/dist/src/db/queries/integrity.js +5 -21
  75. package/dist/src/db/queries/integrity.js.map +2 -2
  76. package/dist/src/db/queries/subgraph-gaps.d.ts +1 -2
  77. package/dist/src/db/queries/subgraph-gaps.js +5 -21
  78. package/dist/src/db/queries/subgraph-gaps.js.map +2 -2
  79. package/dist/src/db/queries/subgraph-operations.d.ts +1 -2
  80. package/dist/src/db/queries/subgraph-operations.js +17 -33
  81. package/dist/src/db/queries/subgraph-operations.js.map +2 -2
  82. package/dist/src/db/queries/subgraphs.d.ts +2 -14
  83. package/dist/src/db/queries/subgraphs.js +15 -37
  84. package/dist/src/db/queries/subgraphs.js.map +5 -5
  85. package/dist/src/db/queries/sync-scope.d.ts +1 -2
  86. package/dist/src/db/queries/sync-scope.js +6 -22
  87. package/dist/src/db/queries/sync-scope.js.map +2 -2
  88. package/dist/src/db/queries/webhooks.d.ts +1 -2
  89. package/dist/src/db/queries/webhooks.js +54 -50
  90. package/dist/src/db/queries/webhooks.js.map +5 -5
  91. package/dist/src/db/schema.d.ts +1 -2
  92. package/dist/src/env.d.ts +1 -1
  93. package/dist/src/env.js +7 -23
  94. package/dist/src/env.js.map +2 -2
  95. package/dist/src/errors.d.ts +1 -1
  96. package/dist/src/errors.js +15 -31
  97. package/dist/src/errors.js.map +2 -2
  98. package/dist/src/index-http.d.ts +1 -1
  99. package/dist/src/index-http.js +3 -19
  100. package/dist/src/index-http.js.map +2 -2
  101. package/dist/src/index-internal-auth.d.ts +1 -1
  102. package/dist/src/index-internal-auth.js +7 -23
  103. package/dist/src/index-internal-auth.js.map +2 -2
  104. package/dist/src/index.d.ts +136 -149
  105. package/dist/src/index.js +259 -313
  106. package/dist/src/index.js.map +12 -12
  107. package/dist/src/leader.d.ts +1 -1
  108. package/dist/src/leader.js +7 -21
  109. package/dist/src/leader.js.map +5 -5
  110. package/dist/src/logger.js +1 -17
  111. package/dist/src/logger.js.map +2 -2
  112. package/dist/src/mode.d.ts +1 -1
  113. package/dist/src/mode.js +5 -21
  114. package/dist/src/mode.js.map +2 -2
  115. package/dist/src/node/archive-client.d.ts +1 -1
  116. package/dist/src/node/archive-client.js +9 -23
  117. package/dist/src/node/archive-client.js.map +5 -5
  118. package/dist/src/node/client.d.ts +1 -1
  119. package/dist/src/node/client.js +4 -18
  120. package/dist/src/node/client.js.map +5 -5
  121. package/dist/src/node/consensus.d.ts +1 -1
  122. package/dist/src/node/consensus.js +5 -21
  123. package/dist/src/node/consensus.js.map +2 -2
  124. package/dist/src/node/hiro-client.d.ts +1 -1
  125. package/dist/src/node/hiro-client.js +1 -17
  126. package/dist/src/node/hiro-client.js.map +2 -2
  127. package/dist/src/node/hiro-pg-client.js +1 -17
  128. package/dist/src/node/hiro-pg-client.js.map +2 -2
  129. package/dist/src/node/local-client.d.ts +1 -2
  130. package/dist/src/node/local-client.js +3 -19
  131. package/dist/src/node/local-client.js.map +2 -2
  132. package/dist/src/node/nakamoto.d.ts +1 -1
  133. package/dist/src/node/nakamoto.js +12 -28
  134. package/dist/src/node/nakamoto.js.map +2 -2
  135. package/dist/src/queue/listener.d.ts +1 -1
  136. package/dist/src/queue/listener.js +4 -20
  137. package/dist/src/queue/listener.js.map +2 -2
  138. package/dist/src/runtime/index.d.ts +1 -1
  139. package/dist/src/runtime/index.js +51 -67
  140. package/dist/src/runtime/index.js.map +2 -2
  141. package/dist/src/schemas/index.d.ts +1 -4
  142. package/dist/src/schemas/index.js +19 -37
  143. package/dist/src/schemas/index.js.map +3 -3
  144. package/dist/src/schemas/subgraphs.d.ts +1 -4
  145. package/dist/src/schemas/subgraphs.js +1 -18
  146. package/dist/src/schemas/subgraphs.js.map +3 -3
  147. package/dist/src/schemas/webhooks.d.ts +1 -1
  148. package/dist/src/schemas/webhooks.js +21 -37
  149. package/dist/src/schemas/webhooks.js.map +2 -2
  150. package/dist/src/streams-bulk-manifest.d.ts +1 -1
  151. package/dist/src/streams-bulk-manifest.js +9 -9
  152. package/dist/src/streams-bulk-manifest.js.map +1 -1
  153. package/dist/src/streams-rows/index.d.ts +1 -1
  154. package/dist/src/streams-rows/index.js +32 -48
  155. package/dist/src/streams-rows/index.js.map +2 -2
  156. package/dist/src/subgraphs/spec.d.ts +1 -11
  157. package/dist/src/subgraphs/spec.js +27 -93
  158. package/dist/src/subgraphs/spec.js.map +3 -3
  159. package/dist/src/types.d.ts +1 -1
  160. package/migrations/0136_drop_subgraph_visibility.ts +34 -0
  161. package/package.json +1 -1
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/archive/semantic-digest.ts", "../src/archive/semantic-digest-builder.ts"],
3
+ "sources": ["../src/archive/semantic-digest-builder.ts", "../src/archive/semantic-digest.ts"],
4
4
  "sourcesContent": [
5
- "import { createHash } from \"node:crypto\";\n\n/**\n * v1 canonical byte encoding for chain identity — the shape that lets\n * independently-run runtimes agree on the same block.\n *\n * The exact-body digest (`sha256:parquet-object`) proves capture fidelity to one\n * source: replay the same bytes, get the same rows. It cannot prove two nodes\n * observed the same chain, because their Parquet encoders legally differ in\n * column padding, compression, JSON key order, and null placement — two\n * operators processing the same block can ship byte-different Parquets that\n * carry identical content.\n *\n * The semantic digest is the shape that lets independent runtimes agree. Every\n * value on a block/transaction/event is normalized into a canonical byte string\n * by rules that MUST NOT change without a version bump. Two v1 computations\n * over the same range agree, or one is wrong about the chain — never about\n * formatting.\n *\n * Encoding rules (v1):\n * - Fields join with `\\x1f` (ASCII US, unit separator — cannot legally\n * appear in any chain value; a printable delimiter risks collision with\n * contract-emitted strings).\n * - Null encodes as `\\x00` (single NUL). Distinct from empty string `\"\"`.\n * - Integers encode as their base-10 string. bigint → decimal string.\n * - JSON payload columns (function_args, event data) encode as canonical\n * JSON: object keys sorted lexicographically, no whitespace, bigint →\n * quoted decimal string, non-finite numbers rejected.\n * - Field order per record type is fixed and never reordered.\n * - Digest = sha256(bytes), lowercase hex.\n *\n * Rollup rules (v1) — order MUST match the archive's stream order or an\n * honest re-export will disagree with the manifest:\n * - blocks: (height asc)\n * - transactions: (block_height asc, tx_index asc, tx_id asc)\n * - events: (block_height asc, event_index asc, tx_id asc)\n * Per-partition rollup is `sha256(concat(row_digest_bytes))` in stream order.\n *\n * Test vectors under `packages/shared/src/archive/__fixtures__/semantic-digest/`\n * pin the encoding. Any change to bytes must bump the spec version.\n */\n\nexport const SEMANTIC_DIGEST_SPEC_V1 = \"sha256:semantic-v1\" as const;\nexport type SemanticDigestSpec = typeof SEMANTIC_DIGEST_SPEC_V1;\n\nconst FIELD_SEP = \"\\x1f\";\nconst NULL_MARKER = \"\\x00\";\n\nconst textEncoder = new TextEncoder();\n\n/**\n * Stable JSON — sorted keys, no whitespace, bigint → decimal string. Distinct\n * from `JSON.stringify(x)` which respects insertion order and rejects bigints.\n * Also rejects non-finite numbers, since NaN/Infinity have no on-chain meaning\n * and would silently hash as `null` under `JSON.stringify`.\n */\nexport function canonicalJson(value: unknown): string {\n\tif (value === null) return \"null\";\n\tif (typeof value === \"string\" || typeof value === \"boolean\") {\n\t\treturn JSON.stringify(value);\n\t}\n\tif (typeof value === \"number\") {\n\t\tif (!Number.isFinite(value)) {\n\t\t\tthrow new Error(\"canonicalJson: non-finite number\");\n\t\t}\n\t\treturn JSON.stringify(value);\n\t}\n\tif (typeof value === \"bigint\") return JSON.stringify(value.toString());\n\tif (Array.isArray(value)) {\n\t\treturn `[${value.map((item) => canonicalJson(item)).join(\",\")}]`;\n\t}\n\tif (typeof value === \"object\") {\n\t\tconst object = value as Record<string, unknown>;\n\t\treturn `{${Object.keys(object)\n\t\t\t.sort()\n\t\t\t.map((key) => `${JSON.stringify(key)}:${canonicalJson(object[key])}`)\n\t\t\t.join(\",\")}}`;\n\t}\n\t// undefined / function / symbol — never present in decoded chain rows.\n\t// Fall through as null so tests catch unexpected shapes.\n\treturn \"null\";\n}\n\nfunction scalar(value: string | number | bigint | null | undefined): string {\n\tif (value === null || value === undefined) return NULL_MARKER;\n\tif (typeof value === \"number\") {\n\t\tif (!Number.isFinite(value)) {\n\t\t\tthrow new Error(\"semanticDigest: non-finite number\");\n\t\t}\n\t\tif (!Number.isInteger(value)) {\n\t\t\t// Chain heights, indexes, timestamps are all integer; a fractional\n\t\t\t// value here is a schema bug we want to surface loudly, not silently\n\t\t\t// serialize with float precision that varies by runtime.\n\t\t\tthrow new Error(`semanticDigest: non-integer scalar ${value}`);\n\t\t}\n\t\treturn String(value);\n\t}\n\tif (typeof value === \"bigint\") return value.toString();\n\treturn value;\n}\n\nfunction jsonScalar(value: unknown): string {\n\treturn value === null || value === undefined\n\t\t? NULL_MARKER\n\t\t: canonicalJson(value);\n}\n\nfunction sha256Hex(input: Uint8Array | string): string {\n\treturn createHash(\"sha256\").update(input).digest(\"hex\");\n}\n\nexport interface BlockDigestInput {\n\theight: number | bigint;\n\thash: string;\n\tparent_hash: string;\n\tburn_block_height: number | bigint;\n\tburn_block_hash: string | null;\n\tindex_block_hash: string | null;\n\ttimestamp: number | bigint;\n}\n\nexport interface TransactionDigestInput {\n\ttx_id: string;\n\tblock_height: number | bigint;\n\ttx_index: number;\n\ttype: string;\n\tsender: string;\n\tstatus: string;\n\tcontract_id: string | null;\n\tfunction_name: string | null;\n\tfunction_args: unknown;\n\traw_result: string | null;\n\traw_tx: string;\n}\n\nexport interface EventDigestInput {\n\ttx_id: string;\n\tblock_height: number | bigint;\n\tevent_index: number;\n\ttype: string;\n\tdata: unknown;\n}\n\nfunction encodeBlock(row: BlockDigestInput): string {\n\treturn [\n\t\tscalar(row.height),\n\t\tscalar(row.hash),\n\t\tscalar(row.parent_hash),\n\t\tscalar(row.burn_block_height),\n\t\tscalar(row.burn_block_hash),\n\t\tscalar(row.index_block_hash),\n\t\tscalar(row.timestamp),\n\t].join(FIELD_SEP);\n}\n\nfunction encodeTransaction(row: TransactionDigestInput): string {\n\treturn [\n\t\tscalar(row.tx_id),\n\t\tscalar(row.block_height),\n\t\tscalar(row.tx_index),\n\t\tscalar(row.type),\n\t\tscalar(row.sender),\n\t\tscalar(row.status),\n\t\tscalar(row.contract_id),\n\t\tscalar(row.function_name),\n\t\tjsonScalar(row.function_args),\n\t\tscalar(row.raw_result),\n\t\tscalar(row.raw_tx),\n\t].join(FIELD_SEP);\n}\n\nfunction encodeEvent(row: EventDigestInput): string {\n\treturn [\n\t\tscalar(row.tx_id),\n\t\tscalar(row.block_height),\n\t\tscalar(row.event_index),\n\t\tscalar(row.type),\n\t\tjsonScalar(row.data),\n\t].join(FIELD_SEP);\n}\n\n/**\n * v1 per-row digests. Each is `sha256(encoded_row_bytes)` in lowercase hex.\n * The encoded byte form is stable across runtimes; the sha256 is stable\n * across CPU architectures. Never mutate an encoder without a v-bump.\n */\nexport interface SemanticDigestV1 {\n\treadonly spec: SemanticDigestSpec;\n\treadonly encodeBlock: (row: BlockDigestInput) => string;\n\treadonly encodeTransaction: (row: TransactionDigestInput) => string;\n\treadonly encodeEvent: (row: EventDigestInput) => string;\n\treadonly block: (row: BlockDigestInput) => string;\n\treadonly transaction: (row: TransactionDigestInput) => string;\n\treadonly event: (row: EventDigestInput) => string;\n}\n\nexport interface SemanticDigestApi {\n\treadonly v1: SemanticDigestV1;\n}\n\nexport const semanticDigest: SemanticDigestApi = {\n\tv1: {\n\t\tspec: SEMANTIC_DIGEST_SPEC_V1,\n\t\tencodeBlock,\n\t\tencodeTransaction,\n\t\tencodeEvent,\n\t\tblock: (row: BlockDigestInput): string =>\n\t\t\tsha256Hex(textEncoder.encode(encodeBlock(row))),\n\t\ttransaction: (row: TransactionDigestInput): string =>\n\t\t\tsha256Hex(textEncoder.encode(encodeTransaction(row))),\n\t\tevent: (row: EventDigestInput): string =>\n\t\t\tsha256Hex(textEncoder.encode(encodeEvent(row))),\n\t},\n};\n\n/**\n * Streaming rollup — feed rows one at a time in their declared order, read the\n * rolled digest at the end. Two callers passing the same rows in the same order\n * produce the same rollup, regardless of batching.\n *\n * The rollup composes: partition_digest = sha256(concat(row_digest_bytes)),\n * where each row_digest_bytes = sha256(encode(row)). This is why the streaming\n * implementation can be constant-memory — the outer sha256 accepts row digests\n * incrementally.\n */\nexport class SemanticDigestRollup {\n\tprivate readonly hasher = createHash(\"sha256\");\n\tprivate count = 0;\n\n\tstatic forDataset(\n\t\t_dataset: \"blocks\" | \"transactions\" | \"events\",\n\t): SemanticDigestRollup {\n\t\treturn new SemanticDigestRollup();\n\t}\n\n\tappendRowDigest(rowDigestHex: string): void {\n\t\tthis.hasher.update(Buffer.from(rowDigestHex, \"hex\"));\n\t\tthis.count += 1;\n\t}\n\n\trowCount(): number {\n\t\treturn this.count;\n\t}\n\n\t/** Empty rollups return `null`, not the sha256 of nothing, so an empty\n\t * range never compares equal to another empty range on a different\n\t * dataset. Callers assign `null` semantics deliberately. */\n\tdigest(): string | null {\n\t\treturn this.count === 0 ? null : this.hasher.copy().digest(\"hex\");\n\t}\n\n\tspec(): SemanticDigestSpec {\n\t\treturn SEMANTIC_DIGEST_SPEC_V1;\n\t}\n}\n\n/**\n * Per-partition digest record — the shape that lands in the snapshot manifest.\n * Complements the existing `sha256:parquet-object` per-partition digest by\n * proving semantic identity independent of file encoding.\n */\nexport interface PartitionSemanticDigest {\n\tdataset: \"blocks\" | \"transactions\" | \"events\";\n\tfrom_block: number;\n\tto_block: number;\n\trow_count: number;\n\tdigest: string | null;\n\tdigest_spec: SemanticDigestSpec;\n}\n",
6
- "import { type Kysely, sql } from \"kysely\";\nimport type { Database } from \"../db/schema.ts\";\nimport {\n\ttype PartitionSemanticDigest,\n\tSEMANTIC_DIGEST_SPEC_V1,\n\tSemanticDigestRollup,\n\tsemanticDigest,\n} from \"./semantic-digest.ts\";\n\n/**\n * Compute per-partition semantic-v1 digests directly from a database — the same\n * bytes an exporter would produce, without writing Parquet. Callers: the CLI\n * verifier's `--semantic` pass, and (in future) the node replay auditor.\n *\n * SQL and ordering MUST match the archive exporter's stream (see\n * `packages/indexer/src/archive/export-snapshot.ts`). If either drifts, an\n * honest re-computation will disagree with the manifest even though both are\n * correct — and there is no way to tell which is wrong. Any change here needs\n * a matching change there.\n */\n\nexport type CanonicalDataset = \"blocks\" | \"transactions\" | \"events\";\n\nconst DEFAULT_BATCH_ROWS = 20_000;\n\ninterface StreamOptions {\n\tbatchRows?: number;\n}\n\nasync function* streamBlockDigests(\n\tdb: Kysely<Database>,\n\tfromBlock: number,\n\ttoBlock: number,\n\tbatchRows: number,\n): AsyncGenerator<string> {\n\tlet last = fromBlock - 1;\n\twhile (true) {\n\t\tconst rows = await db\n\t\t\t.selectFrom(\"blocks\")\n\t\t\t.select([\n\t\t\t\t\"height\",\n\t\t\t\t\"hash\",\n\t\t\t\t\"parent_hash\",\n\t\t\t\t\"burn_block_height\",\n\t\t\t\t\"burn_block_hash\",\n\t\t\t\t\"index_block_hash\",\n\t\t\t\t\"timestamp\",\n\t\t\t])\n\t\t\t.where(\"canonical\", \"=\", true)\n\t\t\t.where(\"height\", \">\", last)\n\t\t\t.where(\"height\", \"<=\", toBlock)\n\t\t\t.orderBy(\"height\", \"asc\")\n\t\t\t.limit(batchRows)\n\t\t\t.execute();\n\t\tif (rows.length === 0) return;\n\t\tfor (const row of rows) {\n\t\t\tyield semanticDigest.v1.block({\n\t\t\t\theight: Number(row.height),\n\t\t\t\thash: row.hash,\n\t\t\t\tparent_hash: row.parent_hash,\n\t\t\t\tburn_block_height: Number(row.burn_block_height),\n\t\t\t\tburn_block_hash: row.burn_block_hash ?? null,\n\t\t\t\tindex_block_hash: row.index_block_hash ?? null,\n\t\t\t\ttimestamp: Number(row.timestamp),\n\t\t\t});\n\t\t}\n\t\tlast = Number(rows[rows.length - 1]?.height);\n\t}\n}\n\nasync function* streamTransactionDigests(\n\tdb: Kysely<Database>,\n\tfromBlock: number,\n\ttoBlock: number,\n\tbatchRows: number,\n): AsyncGenerator<string> {\n\ttype TxRow = {\n\t\ttx_id: string;\n\t\tblock_height: string | number;\n\t\ttx_index: number;\n\t\ttype: string;\n\t\tsender: string;\n\t\tstatus: string;\n\t\tcontract_id: string | null;\n\t\tfunction_name: string | null;\n\t\tfunction_args: unknown;\n\t\traw_result: string | null;\n\t\traw_tx: string;\n\t};\n\tlet cursor: { height: number; txIndex: number; txId: string } | null = null;\n\twhile (true) {\n\t\tconst result = await sql<TxRow>`\n\t\t\tSELECT t.tx_id, t.block_height, t.tx_index, t.type, t.sender, t.status,\n\t\t\t t.contract_id, t.function_name, t.function_args, t.raw_result, t.raw_tx\n\t\t\t FROM transactions t\n\t\t\t JOIN blocks b ON b.height = t.block_height AND b.canonical = true\n\t\t\t WHERE t.block_height >= ${fromBlock} AND t.block_height <= ${toBlock}\n\t\t\t AND (${cursor === null} OR (t.block_height, t.tx_index, t.tx_id) >\n\t\t\t (${cursor?.height ?? 0}, ${cursor?.txIndex ?? 0}, ${cursor?.txId ?? \"\"}))\n\t\t\t ORDER BY t.block_height, t.tx_index, t.tx_id\n\t\t\t LIMIT ${batchRows}\n\t\t`.execute(db);\n\t\tconst rows: TxRow[] = result.rows;\n\t\tif (rows.length === 0) return;\n\t\tfor (const row of rows) {\n\t\t\tyield semanticDigest.v1.transaction({\n\t\t\t\ttx_id: row.tx_id,\n\t\t\t\tblock_height: Number(row.block_height),\n\t\t\t\ttx_index: row.tx_index,\n\t\t\t\ttype: row.type,\n\t\t\t\tsender: row.sender,\n\t\t\t\tstatus: row.status,\n\t\t\t\tcontract_id: row.contract_id,\n\t\t\t\tfunction_name: row.function_name,\n\t\t\t\tfunction_args: row.function_args ?? null,\n\t\t\t\traw_result: row.raw_result,\n\t\t\t\traw_tx: row.raw_tx,\n\t\t\t});\n\t\t}\n\t\tconst tail = rows[rows.length - 1];\n\t\tif (tail) {\n\t\t\tcursor = {\n\t\t\t\theight: Number(tail.block_height),\n\t\t\t\ttxIndex: tail.tx_index,\n\t\t\t\ttxId: tail.tx_id,\n\t\t\t};\n\t\t}\n\t}\n}\n\nasync function* streamEventDigests(\n\tdb: Kysely<Database>,\n\tfromBlock: number,\n\ttoBlock: number,\n\tbatchRows: number,\n): AsyncGenerator<string> {\n\ttype EventRow = {\n\t\ttx_id: string;\n\t\tblock_height: string | number;\n\t\tevent_index: number;\n\t\ttype: string;\n\t\tdata: unknown;\n\t};\n\tlet cursor: { height: number; eventIndex: number; txId: string } | null =\n\t\tnull;\n\twhile (true) {\n\t\tconst result = await sql<EventRow>`\n\t\t\tSELECT e.tx_id, e.block_height, e.event_index, e.type, e.data\n\t\t\t FROM events e\n\t\t\t JOIN blocks b ON b.height = e.block_height AND b.canonical = true\n\t\t\t WHERE e.block_height >= ${fromBlock} AND e.block_height <= ${toBlock}\n\t\t\t AND (${cursor === null} OR (e.block_height, e.event_index, e.tx_id) >\n\t\t\t (${cursor?.height ?? 0}, ${cursor?.eventIndex ?? 0}, ${cursor?.txId ?? \"\"}))\n\t\t\t ORDER BY e.block_height, e.event_index, e.tx_id\n\t\t\t LIMIT ${batchRows}\n\t\t`.execute(db);\n\t\tconst rows: EventRow[] = result.rows;\n\t\tif (rows.length === 0) return;\n\t\tfor (const row of rows) {\n\t\t\tyield semanticDigest.v1.event({\n\t\t\t\ttx_id: row.tx_id,\n\t\t\t\tblock_height: Number(row.block_height),\n\t\t\t\tevent_index: row.event_index,\n\t\t\t\ttype: row.type,\n\t\t\t\tdata: row.data ?? null,\n\t\t\t});\n\t\t}\n\t\tconst tail = rows[rows.length - 1];\n\t\tif (tail) {\n\t\t\tcursor = {\n\t\t\t\theight: Number(tail.block_height),\n\t\t\t\teventIndex: tail.event_index,\n\t\t\t\ttxId: tail.tx_id,\n\t\t\t};\n\t\t}\n\t}\n}\n\nfunction digestStream(\n\tdb: Kysely<Database>,\n\tdataset: CanonicalDataset,\n\tfromBlock: number,\n\ttoBlock: number,\n\tbatchRows: number,\n): AsyncGenerator<string> {\n\tif (dataset === \"blocks\") {\n\t\treturn streamBlockDigests(db, fromBlock, toBlock, batchRows);\n\t}\n\tif (dataset === \"transactions\") {\n\t\treturn streamTransactionDigests(db, fromBlock, toBlock, batchRows);\n\t}\n\treturn streamEventDigests(db, fromBlock, toBlock, batchRows);\n}\n\n/**\n * Compute one partition's semantic-v1 digest. Empty ranges return `null` — an\n * empty range has no digest, distinct from \"digest of zero rows\" which would\n * compare equal across datasets.\n */\nexport async function computePartitionSemanticDigest(\n\tdb: Kysely<Database>,\n\tdataset: CanonicalDataset,\n\tfromBlock: number,\n\ttoBlock: number,\n\toptions: StreamOptions = {},\n): Promise<PartitionSemanticDigest> {\n\tconst rollup = SemanticDigestRollup.forDataset(dataset);\n\tfor await (const rowDigest of digestStream(\n\t\tdb,\n\t\tdataset,\n\t\tfromBlock,\n\t\ttoBlock,\n\t\toptions.batchRows ?? DEFAULT_BATCH_ROWS,\n\t)) {\n\t\trollup.appendRowDigest(rowDigest);\n\t}\n\treturn {\n\t\tdataset,\n\t\tfrom_block: fromBlock,\n\t\tto_block: toBlock,\n\t\trow_count: rollup.rowCount(),\n\t\tdigest: rollup.digest(),\n\t\tdigest_spec: SEMANTIC_DIGEST_SPEC_V1,\n\t};\n}\n\nexport type PartitionSemanticComparison = {\n\tdataset: CanonicalDataset;\n\tfrom_block: number;\n\tto_block: number;\n\tstatus: \"match\" | \"digest-mismatch\" | \"count-mismatch\" | \"missing-locally\";\n\texpected_digest: string | null;\n\tactual_digest: string | null;\n\texpected_rows: number;\n\tactual_rows: number;\n};\n\nexport function comparePartitionSemanticDigests(\n\tlocal: readonly PartitionSemanticDigest[],\n\treference: readonly PartitionSemanticDigest[],\n): PartitionSemanticComparison[] {\n\tconst localByKey = new Map(\n\t\tlocal.map((d) => [`${d.dataset}:${d.from_block}-${d.to_block}`, d]),\n\t);\n\treturn reference.map((expected) => {\n\t\tconst key = `${expected.dataset}:${expected.from_block}-${expected.to_block}`;\n\t\tconst actual = localByKey.get(key);\n\t\tconst base = {\n\t\t\tdataset: expected.dataset,\n\t\t\tfrom_block: expected.from_block,\n\t\t\tto_block: expected.to_block,\n\t\t\texpected_digest: expected.digest,\n\t\t\texpected_rows: expected.row_count,\n\t\t};\n\t\tif (!actual) {\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\tstatus: \"missing-locally\" as const,\n\t\t\t\tactual_digest: null,\n\t\t\t\tactual_rows: 0,\n\t\t\t};\n\t\t}\n\t\tconst status =\n\t\t\tactual.row_count !== expected.row_count\n\t\t\t\t? (\"count-mismatch\" as const)\n\t\t\t\t: actual.digest === expected.digest\n\t\t\t\t\t? (\"match\" as const)\n\t\t\t\t\t: (\"digest-mismatch\" as const);\n\t\treturn {\n\t\t\t...base,\n\t\t\tstatus,\n\t\t\tactual_digest: actual.digest,\n\t\t\tactual_rows: actual.row_count,\n\t\t};\n\t});\n}\n"
5
+ "import { type Kysely, sql } from \"kysely\";\nimport type { Database } from \"../db/schema.ts\";\nimport {\n\ttype PartitionSemanticDigest,\n\tSEMANTIC_DIGEST_SPEC_V1,\n\tSemanticDigestRollup,\n\tsemanticDigest,\n} from \"./semantic-digest.ts\";\n\n/**\n * Compute per-partition semantic-v1 digests directly from a database — the same\n * bytes an exporter would produce, without writing Parquet. Callers: the CLI\n * verifier's `--semantic` pass, and (in future) the node replay auditor.\n *\n * SQL and ordering MUST match the archive exporter's stream (see\n * `packages/indexer/src/archive/export-snapshot.ts`). If either drifts, an\n * honest re-computation will disagree with the manifest even though both are\n * correct — and there is no way to tell which is wrong. Any change here needs\n * a matching change there.\n */\n\nexport type CanonicalDataset = \"blocks\" | \"transactions\" | \"events\";\n\nconst DEFAULT_BATCH_ROWS = 20_000;\n\ninterface StreamOptions {\n\tbatchRows?: number;\n}\n\nasync function* streamBlockDigests(\n\tdb: Kysely<Database>,\n\tfromBlock: number,\n\ttoBlock: number,\n\tbatchRows: number,\n): AsyncGenerator<string> {\n\tlet last = fromBlock - 1;\n\twhile (true) {\n\t\tconst rows = await db\n\t\t\t.selectFrom(\"blocks\")\n\t\t\t.select([\n\t\t\t\t\"height\",\n\t\t\t\t\"hash\",\n\t\t\t\t\"parent_hash\",\n\t\t\t\t\"burn_block_height\",\n\t\t\t\t\"burn_block_hash\",\n\t\t\t\t\"index_block_hash\",\n\t\t\t\t\"timestamp\",\n\t\t\t])\n\t\t\t.where(\"canonical\", \"=\", true)\n\t\t\t.where(\"height\", \">\", last)\n\t\t\t.where(\"height\", \"<=\", toBlock)\n\t\t\t.orderBy(\"height\", \"asc\")\n\t\t\t.limit(batchRows)\n\t\t\t.execute();\n\t\tif (rows.length === 0) return;\n\t\tfor (const row of rows) {\n\t\t\tyield semanticDigest.v1.block({\n\t\t\t\theight: Number(row.height),\n\t\t\t\thash: row.hash,\n\t\t\t\tparent_hash: row.parent_hash,\n\t\t\t\tburn_block_height: Number(row.burn_block_height),\n\t\t\t\tburn_block_hash: row.burn_block_hash ?? null,\n\t\t\t\tindex_block_hash: row.index_block_hash ?? null,\n\t\t\t\ttimestamp: Number(row.timestamp),\n\t\t\t});\n\t\t}\n\t\tlast = Number(rows[rows.length - 1]?.height);\n\t}\n}\n\nasync function* streamTransactionDigests(\n\tdb: Kysely<Database>,\n\tfromBlock: number,\n\ttoBlock: number,\n\tbatchRows: number,\n): AsyncGenerator<string> {\n\ttype TxRow = {\n\t\ttx_id: string;\n\t\tblock_height: string | number;\n\t\ttx_index: number;\n\t\ttype: string;\n\t\tsender: string;\n\t\tstatus: string;\n\t\tcontract_id: string | null;\n\t\tfunction_name: string | null;\n\t\tfunction_args: unknown;\n\t\traw_result: string | null;\n\t\traw_tx: string;\n\t};\n\tlet cursor: { height: number; txIndex: number; txId: string } | null = null;\n\twhile (true) {\n\t\tconst result = await sql<TxRow>`\n\t\t\tSELECT t.tx_id, t.block_height, t.tx_index, t.type, t.sender, t.status,\n\t\t\t t.contract_id, t.function_name, t.function_args, t.raw_result, t.raw_tx\n\t\t\t FROM transactions t\n\t\t\t JOIN blocks b ON b.height = t.block_height AND b.canonical = true\n\t\t\t WHERE t.block_height >= ${fromBlock} AND t.block_height <= ${toBlock}\n\t\t\t AND (${cursor === null} OR (t.block_height, t.tx_index, t.tx_id) >\n\t\t\t (${cursor?.height ?? 0}, ${cursor?.txIndex ?? 0}, ${cursor?.txId ?? \"\"}))\n\t\t\t ORDER BY t.block_height, t.tx_index, t.tx_id\n\t\t\t LIMIT ${batchRows}\n\t\t`.execute(db);\n\t\tconst rows: TxRow[] = result.rows;\n\t\tif (rows.length === 0) return;\n\t\tfor (const row of rows) {\n\t\t\tyield semanticDigest.v1.transaction({\n\t\t\t\ttx_id: row.tx_id,\n\t\t\t\tblock_height: Number(row.block_height),\n\t\t\t\ttx_index: row.tx_index,\n\t\t\t\ttype: row.type,\n\t\t\t\tsender: row.sender,\n\t\t\t\tstatus: row.status,\n\t\t\t\tcontract_id: row.contract_id,\n\t\t\t\tfunction_name: row.function_name,\n\t\t\t\tfunction_args: row.function_args ?? null,\n\t\t\t\traw_result: row.raw_result,\n\t\t\t\traw_tx: row.raw_tx,\n\t\t\t});\n\t\t}\n\t\tconst tail = rows[rows.length - 1];\n\t\tif (tail) {\n\t\t\tcursor = {\n\t\t\t\theight: Number(tail.block_height),\n\t\t\t\ttxIndex: tail.tx_index,\n\t\t\t\ttxId: tail.tx_id,\n\t\t\t};\n\t\t}\n\t}\n}\n\nasync function* streamEventDigests(\n\tdb: Kysely<Database>,\n\tfromBlock: number,\n\ttoBlock: number,\n\tbatchRows: number,\n): AsyncGenerator<string> {\n\ttype EventRow = {\n\t\ttx_id: string;\n\t\tblock_height: string | number;\n\t\tevent_index: number;\n\t\ttype: string;\n\t\tdata: unknown;\n\t};\n\tlet cursor: { height: number; eventIndex: number; txId: string } | null =\n\t\tnull;\n\twhile (true) {\n\t\tconst result = await sql<EventRow>`\n\t\t\tSELECT e.tx_id, e.block_height, e.event_index, e.type, e.data\n\t\t\t FROM events e\n\t\t\t JOIN blocks b ON b.height = e.block_height AND b.canonical = true\n\t\t\t WHERE e.block_height >= ${fromBlock} AND e.block_height <= ${toBlock}\n\t\t\t AND (${cursor === null} OR (e.block_height, e.event_index, e.tx_id) >\n\t\t\t (${cursor?.height ?? 0}, ${cursor?.eventIndex ?? 0}, ${cursor?.txId ?? \"\"}))\n\t\t\t ORDER BY e.block_height, e.event_index, e.tx_id\n\t\t\t LIMIT ${batchRows}\n\t\t`.execute(db);\n\t\tconst rows: EventRow[] = result.rows;\n\t\tif (rows.length === 0) return;\n\t\tfor (const row of rows) {\n\t\t\tyield semanticDigest.v1.event({\n\t\t\t\ttx_id: row.tx_id,\n\t\t\t\tblock_height: Number(row.block_height),\n\t\t\t\tevent_index: row.event_index,\n\t\t\t\ttype: row.type,\n\t\t\t\tdata: row.data ?? null,\n\t\t\t});\n\t\t}\n\t\tconst tail = rows[rows.length - 1];\n\t\tif (tail) {\n\t\t\tcursor = {\n\t\t\t\theight: Number(tail.block_height),\n\t\t\t\teventIndex: tail.event_index,\n\t\t\t\ttxId: tail.tx_id,\n\t\t\t};\n\t\t}\n\t}\n}\n\nfunction digestStream(\n\tdb: Kysely<Database>,\n\tdataset: CanonicalDataset,\n\tfromBlock: number,\n\ttoBlock: number,\n\tbatchRows: number,\n): AsyncGenerator<string> {\n\tif (dataset === \"blocks\") {\n\t\treturn streamBlockDigests(db, fromBlock, toBlock, batchRows);\n\t}\n\tif (dataset === \"transactions\") {\n\t\treturn streamTransactionDigests(db, fromBlock, toBlock, batchRows);\n\t}\n\treturn streamEventDigests(db, fromBlock, toBlock, batchRows);\n}\n\n/**\n * Compute one partition's semantic-v1 digest. Empty ranges return `null` — an\n * empty range has no digest, distinct from \"digest of zero rows\" which would\n * compare equal across datasets.\n */\nexport async function computePartitionSemanticDigest(\n\tdb: Kysely<Database>,\n\tdataset: CanonicalDataset,\n\tfromBlock: number,\n\ttoBlock: number,\n\toptions: StreamOptions = {},\n): Promise<PartitionSemanticDigest> {\n\tconst rollup = SemanticDigestRollup.forDataset(dataset);\n\tfor await (const rowDigest of digestStream(\n\t\tdb,\n\t\tdataset,\n\t\tfromBlock,\n\t\ttoBlock,\n\t\toptions.batchRows ?? DEFAULT_BATCH_ROWS,\n\t)) {\n\t\trollup.appendRowDigest(rowDigest);\n\t}\n\treturn {\n\t\tdataset,\n\t\tfrom_block: fromBlock,\n\t\tto_block: toBlock,\n\t\trow_count: rollup.rowCount(),\n\t\tdigest: rollup.digest(),\n\t\tdigest_spec: SEMANTIC_DIGEST_SPEC_V1,\n\t};\n}\n\nexport type PartitionSemanticComparison = {\n\tdataset: CanonicalDataset;\n\tfrom_block: number;\n\tto_block: number;\n\tstatus: \"match\" | \"digest-mismatch\" | \"count-mismatch\" | \"missing-locally\";\n\texpected_digest: string | null;\n\tactual_digest: string | null;\n\texpected_rows: number;\n\tactual_rows: number;\n};\n\nexport function comparePartitionSemanticDigests(\n\tlocal: readonly PartitionSemanticDigest[],\n\treference: readonly PartitionSemanticDigest[],\n): PartitionSemanticComparison[] {\n\tconst localByKey = new Map(\n\t\tlocal.map((d) => [`${d.dataset}:${d.from_block}-${d.to_block}`, d]),\n\t);\n\treturn reference.map((expected) => {\n\t\tconst key = `${expected.dataset}:${expected.from_block}-${expected.to_block}`;\n\t\tconst actual = localByKey.get(key);\n\t\tconst base = {\n\t\t\tdataset: expected.dataset,\n\t\t\tfrom_block: expected.from_block,\n\t\t\tto_block: expected.to_block,\n\t\t\texpected_digest: expected.digest,\n\t\t\texpected_rows: expected.row_count,\n\t\t};\n\t\tif (!actual) {\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\tstatus: \"missing-locally\" as const,\n\t\t\t\tactual_digest: null,\n\t\t\t\tactual_rows: 0,\n\t\t\t};\n\t\t}\n\t\tconst status =\n\t\t\tactual.row_count !== expected.row_count\n\t\t\t\t? (\"count-mismatch\" as const)\n\t\t\t\t: actual.digest === expected.digest\n\t\t\t\t\t? (\"match\" as const)\n\t\t\t\t\t: (\"digest-mismatch\" as const);\n\t\treturn {\n\t\t\t...base,\n\t\t\tstatus,\n\t\t\tactual_digest: actual.digest,\n\t\t\tactual_rows: actual.row_count,\n\t\t};\n\t});\n}\n",
6
+ "import { createHash } from \"node:crypto\";\n\n/**\n * v1 canonical byte encoding for chain identity — the shape that lets\n * independently-run runtimes agree on the same block.\n *\n * The exact-body digest (`sha256:parquet-object`) proves capture fidelity to one\n * source: replay the same bytes, get the same rows. It cannot prove two nodes\n * observed the same chain, because their Parquet encoders legally differ in\n * column padding, compression, JSON key order, and null placement — two\n * operators processing the same block can ship byte-different Parquets that\n * carry identical content.\n *\n * The semantic digest is the shape that lets independent runtimes agree. Every\n * value on a block/transaction/event is normalized into a canonical byte string\n * by rules that MUST NOT change without a version bump. Two v1 computations\n * over the same range agree, or one is wrong about the chain — never about\n * formatting.\n *\n * Encoding rules (v1):\n * - Fields join with `\\x1f` (ASCII US, unit separator — cannot legally\n * appear in any chain value; a printable delimiter risks collision with\n * contract-emitted strings).\n * - Null encodes as `\\x00` (single NUL). Distinct from empty string `\"\"`.\n * - Integers encode as their base-10 string. bigint → decimal string.\n * - JSON payload columns (function_args, event data) encode as canonical\n * JSON: object keys sorted lexicographically, no whitespace, bigint →\n * quoted decimal string, non-finite numbers rejected.\n * - Field order per record type is fixed and never reordered.\n * - Digest = sha256(bytes), lowercase hex.\n *\n * Rollup rules (v1) — order MUST match the archive's stream order or an\n * honest re-export will disagree with the manifest:\n * - blocks: (height asc)\n * - transactions: (block_height asc, tx_index asc, tx_id asc)\n * - events: (block_height asc, event_index asc, tx_id asc)\n * Per-partition rollup is `sha256(concat(row_digest_bytes))` in stream order.\n *\n * Test vectors under `packages/shared/src/archive/__fixtures__/semantic-digest/`\n * pin the encoding. Any change to bytes must bump the spec version.\n */\n\nexport const SEMANTIC_DIGEST_SPEC_V1 = \"sha256:semantic-v1\" as const;\nexport type SemanticDigestSpec = typeof SEMANTIC_DIGEST_SPEC_V1;\n\nconst FIELD_SEP = \"\\x1f\";\nconst NULL_MARKER = \"\\x00\";\n\nconst textEncoder = new TextEncoder();\n\n/**\n * Stable JSON — sorted keys, no whitespace, bigint → decimal string. Distinct\n * from `JSON.stringify(x)` which respects insertion order and rejects bigints.\n * Also rejects non-finite numbers, since NaN/Infinity have no on-chain meaning\n * and would silently hash as `null` under `JSON.stringify`.\n */\nexport function canonicalJson(value: unknown): string {\n\tif (value === null) return \"null\";\n\tif (typeof value === \"string\" || typeof value === \"boolean\") {\n\t\treturn JSON.stringify(value);\n\t}\n\tif (typeof value === \"number\") {\n\t\tif (!Number.isFinite(value)) {\n\t\t\tthrow new Error(\"canonicalJson: non-finite number\");\n\t\t}\n\t\treturn JSON.stringify(value);\n\t}\n\tif (typeof value === \"bigint\") return JSON.stringify(value.toString());\n\tif (Array.isArray(value)) {\n\t\treturn `[${value.map((item) => canonicalJson(item)).join(\",\")}]`;\n\t}\n\tif (typeof value === \"object\") {\n\t\tconst object = value as Record<string, unknown>;\n\t\treturn `{${Object.keys(object)\n\t\t\t.sort()\n\t\t\t.map((key) => `${JSON.stringify(key)}:${canonicalJson(object[key])}`)\n\t\t\t.join(\",\")}}`;\n\t}\n\t// undefined / function / symbol — never present in decoded chain rows.\n\t// Fall through as null so tests catch unexpected shapes.\n\treturn \"null\";\n}\n\nfunction scalar(value: string | number | bigint | null | undefined): string {\n\tif (value === null || value === undefined) return NULL_MARKER;\n\tif (typeof value === \"number\") {\n\t\tif (!Number.isFinite(value)) {\n\t\t\tthrow new Error(\"semanticDigest: non-finite number\");\n\t\t}\n\t\tif (!Number.isInteger(value)) {\n\t\t\t// Chain heights, indexes, timestamps are all integer; a fractional\n\t\t\t// value here is a schema bug we want to surface loudly, not silently\n\t\t\t// serialize with float precision that varies by runtime.\n\t\t\tthrow new Error(`semanticDigest: non-integer scalar ${value}`);\n\t\t}\n\t\treturn String(value);\n\t}\n\tif (typeof value === \"bigint\") return value.toString();\n\treturn value;\n}\n\nfunction jsonScalar(value: unknown): string {\n\treturn value === null || value === undefined\n\t\t? NULL_MARKER\n\t\t: canonicalJson(value);\n}\n\nfunction sha256Hex(input: Uint8Array | string): string {\n\treturn createHash(\"sha256\").update(input).digest(\"hex\");\n}\n\nexport interface BlockDigestInput {\n\theight: number | bigint;\n\thash: string;\n\tparent_hash: string;\n\tburn_block_height: number | bigint;\n\tburn_block_hash: string | null;\n\tindex_block_hash: string | null;\n\ttimestamp: number | bigint;\n}\n\nexport interface TransactionDigestInput {\n\ttx_id: string;\n\tblock_height: number | bigint;\n\ttx_index: number;\n\ttype: string;\n\tsender: string;\n\tstatus: string;\n\tcontract_id: string | null;\n\tfunction_name: string | null;\n\tfunction_args: unknown;\n\traw_result: string | null;\n\traw_tx: string;\n}\n\nexport interface EventDigestInput {\n\ttx_id: string;\n\tblock_height: number | bigint;\n\tevent_index: number;\n\ttype: string;\n\tdata: unknown;\n}\n\nfunction encodeBlock(row: BlockDigestInput): string {\n\treturn [\n\t\tscalar(row.height),\n\t\tscalar(row.hash),\n\t\tscalar(row.parent_hash),\n\t\tscalar(row.burn_block_height),\n\t\tscalar(row.burn_block_hash),\n\t\tscalar(row.index_block_hash),\n\t\tscalar(row.timestamp),\n\t].join(FIELD_SEP);\n}\n\nfunction encodeTransaction(row: TransactionDigestInput): string {\n\treturn [\n\t\tscalar(row.tx_id),\n\t\tscalar(row.block_height),\n\t\tscalar(row.tx_index),\n\t\tscalar(row.type),\n\t\tscalar(row.sender),\n\t\tscalar(row.status),\n\t\tscalar(row.contract_id),\n\t\tscalar(row.function_name),\n\t\tjsonScalar(row.function_args),\n\t\tscalar(row.raw_result),\n\t\tscalar(row.raw_tx),\n\t].join(FIELD_SEP);\n}\n\nfunction encodeEvent(row: EventDigestInput): string {\n\treturn [\n\t\tscalar(row.tx_id),\n\t\tscalar(row.block_height),\n\t\tscalar(row.event_index),\n\t\tscalar(row.type),\n\t\tjsonScalar(row.data),\n\t].join(FIELD_SEP);\n}\n\n/**\n * v1 per-row digests. Each is `sha256(encoded_row_bytes)` in lowercase hex.\n * The encoded byte form is stable across runtimes; the sha256 is stable\n * across CPU architectures. Never mutate an encoder without a v-bump.\n */\nexport interface SemanticDigestV1 {\n\treadonly spec: SemanticDigestSpec;\n\treadonly encodeBlock: (row: BlockDigestInput) => string;\n\treadonly encodeTransaction: (row: TransactionDigestInput) => string;\n\treadonly encodeEvent: (row: EventDigestInput) => string;\n\treadonly block: (row: BlockDigestInput) => string;\n\treadonly transaction: (row: TransactionDigestInput) => string;\n\treadonly event: (row: EventDigestInput) => string;\n}\n\nexport interface SemanticDigestApi {\n\treadonly v1: SemanticDigestV1;\n}\n\nexport const semanticDigest: SemanticDigestApi = {\n\tv1: {\n\t\tspec: SEMANTIC_DIGEST_SPEC_V1,\n\t\tencodeBlock,\n\t\tencodeTransaction,\n\t\tencodeEvent,\n\t\tblock: (row: BlockDigestInput): string =>\n\t\t\tsha256Hex(textEncoder.encode(encodeBlock(row))),\n\t\ttransaction: (row: TransactionDigestInput): string =>\n\t\t\tsha256Hex(textEncoder.encode(encodeTransaction(row))),\n\t\tevent: (row: EventDigestInput): string =>\n\t\t\tsha256Hex(textEncoder.encode(encodeEvent(row))),\n\t},\n};\n\n/**\n * Streaming rollup — feed rows one at a time in their declared order, read the\n * rolled digest at the end. Two callers passing the same rows in the same order\n * produce the same rollup, regardless of batching.\n *\n * The rollup composes: partition_digest = sha256(concat(row_digest_bytes)),\n * where each row_digest_bytes = sha256(encode(row)). This is why the streaming\n * implementation can be constant-memory — the outer sha256 accepts row digests\n * incrementally.\n */\nexport class SemanticDigestRollup {\n\tprivate readonly hasher = createHash(\"sha256\");\n\tprivate count = 0;\n\n\tstatic forDataset(\n\t\t_dataset: \"blocks\" | \"transactions\" | \"events\",\n\t): SemanticDigestRollup {\n\t\treturn new SemanticDigestRollup();\n\t}\n\n\tappendRowDigest(rowDigestHex: string): void {\n\t\tthis.hasher.update(Buffer.from(rowDigestHex, \"hex\"));\n\t\tthis.count += 1;\n\t}\n\n\trowCount(): number {\n\t\treturn this.count;\n\t}\n\n\t/** Empty rollups return `null`, not the sha256 of nothing, so an empty\n\t * range never compares equal to another empty range on a different\n\t * dataset. Callers assign `null` semantics deliberately. */\n\tdigest(): string | null {\n\t\treturn this.count === 0 ? null : this.hasher.copy().digest(\"hex\");\n\t}\n\n\tspec(): SemanticDigestSpec {\n\t\treturn SEMANTIC_DIGEST_SPEC_V1;\n\t}\n}\n\n/**\n * Per-partition digest record — the shape that lands in the snapshot manifest.\n * Complements the existing `sha256:parquet-object` per-partition digest by\n * proving semantic identity independent of file encoding.\n */\nexport interface PartitionSemanticDigest {\n\tdataset: \"blocks\" | \"transactions\" | \"events\";\n\tfrom_block: number;\n\tto_block: number;\n\trow_count: number;\n\tdigest: string | null;\n\tdigest_spec: SemanticDigestSpec;\n}\n"
7
7
  ],
8
- "mappings": "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",
9
- "debugId": "DAABB1E8285EB5FE64756E2164756E21",
8
+ "mappings": ";AAAA;;;ACAA;AA0CO,IAAM,0BAA0B;AAGvC,IAAM,YAAY;AAClB,IAAM,cAAc;AAEpB,IAAM,cAAc,IAAI;AAQjB,SAAS,aAAa,CAAC,OAAwB;AAAA,EACrD,IAAI,UAAU;AAAA,IAAM,OAAO;AAAA,EAC3B,IAAI,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW;AAAA,IAC5D,OAAO,KAAK,UAAU,KAAK;AAAA,EAC5B;AAAA,EACA,IAAI,OAAO,UAAU,UAAU;AAAA,IAC9B,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG;AAAA,MAC5B,MAAM,IAAI,MAAM,kCAAkC;AAAA,IACnD;AAAA,IACA,OAAO,KAAK,UAAU,KAAK;AAAA,EAC5B;AAAA,EACA,IAAI,OAAO,UAAU;AAAA,IAAU,OAAO,KAAK,UAAU,MAAM,SAAS,CAAC;AAAA,EACrE,IAAI,MAAM,QAAQ,KAAK,GAAG;AAAA,IACzB,OAAO,IAAI,MAAM,IAAI,CAAC,SAAS,cAAc,IAAI,CAAC,EAAE,KAAK,GAAG;AAAA,EAC7D;AAAA,EACA,IAAI,OAAO,UAAU,UAAU;AAAA,IAC9B,MAAM,SAAS;AAAA,IACf,OAAO,IAAI,OAAO,KAAK,MAAM,EAC3B,KAAK,EACL,IAAI,CAAC,QAAQ,GAAG,KAAK,UAAU,GAAG,KAAK,cAAc,OAAO,IAAI,GAAG,EACnE,KAAK,GAAG;AAAA,EACX;AAAA,EAGA,OAAO;AAAA;AAGR,SAAS,MAAM,CAAC,OAA4D;AAAA,EAC3E,IAAI,UAAU,QAAQ,UAAU;AAAA,IAAW,OAAO;AAAA,EAClD,IAAI,OAAO,UAAU,UAAU;AAAA,IAC9B,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG;AAAA,MAC5B,MAAM,IAAI,MAAM,mCAAmC;AAAA,IACpD;AAAA,IACA,IAAI,CAAC,OAAO,UAAU,KAAK,GAAG;AAAA,MAI7B,MAAM,IAAI,MAAM,sCAAsC,OAAO;AAAA,IAC9D;AAAA,IACA,OAAO,OAAO,KAAK;AAAA,EACpB;AAAA,EACA,IAAI,OAAO,UAAU;AAAA,IAAU,OAAO,MAAM,SAAS;AAAA,EACrD,OAAO;AAAA;AAGR,SAAS,UAAU,CAAC,OAAwB;AAAA,EAC3C,OAAO,UAAU,QAAQ,UAAU,YAChC,cACA,cAAc,KAAK;AAAA;AAGvB,SAAS,SAAS,CAAC,OAAoC;AAAA,EACtD,OAAO,WAAW,QAAQ,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK;AAAA;AAmCvD,SAAS,WAAW,CAAC,KAA+B;AAAA,EACnD,OAAO;AAAA,IACN,OAAO,IAAI,MAAM;AAAA,IACjB,OAAO,IAAI,IAAI;AAAA,IACf,OAAO,IAAI,WAAW;AAAA,IACtB,OAAO,IAAI,iBAAiB;AAAA,IAC5B,OAAO,IAAI,eAAe;AAAA,IAC1B,OAAO,IAAI,gBAAgB;AAAA,IAC3B,OAAO,IAAI,SAAS;AAAA,EACrB,EAAE,KAAK,SAAS;AAAA;AAGjB,SAAS,iBAAiB,CAAC,KAAqC;AAAA,EAC/D,OAAO;AAAA,IACN,OAAO,IAAI,KAAK;AAAA,IAChB,OAAO,IAAI,YAAY;AAAA,IACvB,OAAO,IAAI,QAAQ;AAAA,IACnB,OAAO,IAAI,IAAI;AAAA,IACf,OAAO,IAAI,MAAM;AAAA,IACjB,OAAO,IAAI,MAAM;AAAA,IACjB,OAAO,IAAI,WAAW;AAAA,IACtB,OAAO,IAAI,aAAa;AAAA,IACxB,WAAW,IAAI,aAAa;AAAA,IAC5B,OAAO,IAAI,UAAU;AAAA,IACrB,OAAO,IAAI,MAAM;AAAA,EAClB,EAAE,KAAK,SAAS;AAAA;AAGjB,SAAS,WAAW,CAAC,KAA+B;AAAA,EACnD,OAAO;AAAA,IACN,OAAO,IAAI,KAAK;AAAA,IAChB,OAAO,IAAI,YAAY;AAAA,IACvB,OAAO,IAAI,WAAW;AAAA,IACtB,OAAO,IAAI,IAAI;AAAA,IACf,WAAW,IAAI,IAAI;AAAA,EACpB,EAAE,KAAK,SAAS;AAAA;AAsBV,IAAM,iBAAoC;AAAA,EAChD,IAAI;AAAA,IACH,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,CAAC,QACP,UAAU,YAAY,OAAO,YAAY,GAAG,CAAC,CAAC;AAAA,IAC/C,aAAa,CAAC,QACb,UAAU,YAAY,OAAO,kBAAkB,GAAG,CAAC,CAAC;AAAA,IACrD,OAAO,CAAC,QACP,UAAU,YAAY,OAAO,YAAY,GAAG,CAAC,CAAC;AAAA,EAChD;AACD;AAAA;AAYO,MAAM,qBAAqB;AAAA,EAChB,SAAS,WAAW,QAAQ;AAAA,EACrC,QAAQ;AAAA,SAET,UAAU,CAChB,UACuB;AAAA,IACvB,OAAO,IAAI;AAAA;AAAA,EAGZ,eAAe,CAAC,cAA4B;AAAA,IAC3C,KAAK,OAAO,OAAO,OAAO,KAAK,cAAc,KAAK,CAAC;AAAA,IACnD,KAAK,SAAS;AAAA;AAAA,EAGf,QAAQ,GAAW;AAAA,IAClB,OAAO,KAAK;AAAA;AAAA,EAMb,MAAM,GAAkB;AAAA,IACvB,OAAO,KAAK,UAAU,IAAI,OAAO,KAAK,OAAO,KAAK,EAAE,OAAO,KAAK;AAAA;AAAA,EAGjE,IAAI,GAAuB;AAAA,IAC1B,OAAO;AAAA;AAET;;;ADvOA,IAAM,qBAAqB;AAM3B,gBAAgB,kBAAkB,CACjC,IACA,WACA,SACA,WACyB;AAAA,EACzB,IAAI,OAAO,YAAY;AAAA,EACvB,OAAO,MAAM;AAAA,IACZ,MAAM,OAAO,MAAM,GACjB,WAAW,QAAQ,EACnB,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD,CAAC,EACA,MAAM,aAAa,KAAK,IAAI,EAC5B,MAAM,UAAU,KAAK,IAAI,EACzB,MAAM,UAAU,MAAM,OAAO,EAC7B,QAAQ,UAAU,KAAK,EACvB,MAAM,SAAS,EACf,QAAQ;AAAA,IACV,IAAI,KAAK,WAAW;AAAA,MAAG;AAAA,IACvB,WAAW,OAAO,MAAM;AAAA,MACvB,MAAM,eAAe,GAAG,MAAM;AAAA,QAC7B,QAAQ,OAAO,IAAI,MAAM;AAAA,QACzB,MAAM,IAAI;AAAA,QACV,aAAa,IAAI;AAAA,QACjB,mBAAmB,OAAO,IAAI,iBAAiB;AAAA,QAC/C,iBAAiB,IAAI,mBAAmB;AAAA,QACxC,kBAAkB,IAAI,oBAAoB;AAAA,QAC1C,WAAW,OAAO,IAAI,SAAS;AAAA,MAChC,CAAC;AAAA,IACF;AAAA,IACA,OAAO,OAAO,KAAK,KAAK,SAAS,IAAI,MAAM;AAAA,EAC5C;AAAA;AAGD,gBAAgB,wBAAwB,CACvC,IACA,WACA,SACA,WACyB;AAAA,EAczB,IAAI,SAAmE;AAAA,EACvE,OAAO,MAAM;AAAA,IACZ,MAAM,SAAS,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,8BAKO,mCAAmC;AAAA,aACpD,WAAW;AAAA,cACV,QAAQ,UAAU,MAAM,QAAQ,WAAW,MAAM,QAAQ,QAAQ;AAAA;AAAA,YAEnE;AAAA,IACR,QAAQ,EAAE;AAAA,IACZ,MAAM,OAAgB,OAAO;AAAA,IAC7B,IAAI,KAAK,WAAW;AAAA,MAAG;AAAA,IACvB,WAAW,OAAO,MAAM;AAAA,MACvB,MAAM,eAAe,GAAG,YAAY;AAAA,QACnC,OAAO,IAAI;AAAA,QACX,cAAc,OAAO,IAAI,YAAY;AAAA,QACrC,UAAU,IAAI;AAAA,QACd,MAAM,IAAI;AAAA,QACV,QAAQ,IAAI;AAAA,QACZ,QAAQ,IAAI;AAAA,QACZ,aAAa,IAAI;AAAA,QACjB,eAAe,IAAI;AAAA,QACnB,eAAe,IAAI,iBAAiB;AAAA,QACpC,YAAY,IAAI;AAAA,QAChB,QAAQ,IAAI;AAAA,MACb,CAAC;AAAA,IACF;AAAA,IACA,MAAM,OAAO,KAAK,KAAK,SAAS;AAAA,IAChC,IAAI,MAAM;AAAA,MACT,SAAS;AAAA,QACR,QAAQ,OAAO,KAAK,YAAY;AAAA,QAChC,SAAS,KAAK;AAAA,QACd,MAAM,KAAK;AAAA,MACZ;AAAA,IACD;AAAA,EACD;AAAA;AAGD,gBAAgB,kBAAkB,CACjC,IACA,WACA,SACA,WACyB;AAAA,EAQzB,IAAI,SACH;AAAA,EACD,OAAO,MAAM;AAAA,IACZ,MAAM,SAAS,MAAM;AAAA;AAAA;AAAA;AAAA,8BAIO,mCAAmC;AAAA,aACpD,WAAW;AAAA,cACV,QAAQ,UAAU,MAAM,QAAQ,cAAc,MAAM,QAAQ,QAAQ;AAAA;AAAA,YAEtE;AAAA,IACR,QAAQ,EAAE;AAAA,IACZ,MAAM,OAAmB,OAAO;AAAA,IAChC,IAAI,KAAK,WAAW;AAAA,MAAG;AAAA,IACvB,WAAW,OAAO,MAAM;AAAA,MACvB,MAAM,eAAe,GAAG,MAAM;AAAA,QAC7B,OAAO,IAAI;AAAA,QACX,cAAc,OAAO,IAAI,YAAY;AAAA,QACrC,aAAa,IAAI;AAAA,QACjB,MAAM,IAAI;AAAA,QACV,MAAM,IAAI,QAAQ;AAAA,MACnB,CAAC;AAAA,IACF;AAAA,IACA,MAAM,OAAO,KAAK,KAAK,SAAS;AAAA,IAChC,IAAI,MAAM;AAAA,MACT,SAAS;AAAA,QACR,QAAQ,OAAO,KAAK,YAAY;AAAA,QAChC,YAAY,KAAK;AAAA,QACjB,MAAM,KAAK;AAAA,MACZ;AAAA,IACD;AAAA,EACD;AAAA;AAGD,SAAS,YAAY,CACpB,IACA,SACA,WACA,SACA,WACyB;AAAA,EACzB,IAAI,YAAY,UAAU;AAAA,IACzB,OAAO,mBAAmB,IAAI,WAAW,SAAS,SAAS;AAAA,EAC5D;AAAA,EACA,IAAI,YAAY,gBAAgB;AAAA,IAC/B,OAAO,yBAAyB,IAAI,WAAW,SAAS,SAAS;AAAA,EAClE;AAAA,EACA,OAAO,mBAAmB,IAAI,WAAW,SAAS,SAAS;AAAA;AAQ5D,eAAsB,8BAA8B,CACnD,IACA,SACA,WACA,SACA,UAAyB,CAAC,GACS;AAAA,EACnC,MAAM,SAAS,qBAAqB,WAAW,OAAO;AAAA,EACtD,iBAAiB,aAAa,aAC7B,IACA,SACA,WACA,SACA,QAAQ,aAAa,kBACtB,GAAG;AAAA,IACF,OAAO,gBAAgB,SAAS;AAAA,EACjC;AAAA,EACA,OAAO;AAAA,IACN;AAAA,IACA,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,WAAW,OAAO,SAAS;AAAA,IAC3B,QAAQ,OAAO,OAAO;AAAA,IACtB,aAAa;AAAA,EACd;AAAA;AAcM,SAAS,+BAA+B,CAC9C,OACA,WACgC;AAAA,EAChC,MAAM,aAAa,IAAI,IACtB,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC,CACnE;AAAA,EACA,OAAO,UAAU,IAAI,CAAC,aAAa;AAAA,IAClC,MAAM,MAAM,GAAG,SAAS,WAAW,SAAS,cAAc,SAAS;AAAA,IACnE,MAAM,SAAS,WAAW,IAAI,GAAG;AAAA,IACjC,MAAM,OAAO;AAAA,MACZ,SAAS,SAAS;AAAA,MAClB,YAAY,SAAS;AAAA,MACrB,UAAU,SAAS;AAAA,MACnB,iBAAiB,SAAS;AAAA,MAC1B,eAAe,SAAS;AAAA,IACzB;AAAA,IACA,IAAI,CAAC,QAAQ;AAAA,MACZ,OAAO;AAAA,WACH;AAAA,QACH,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,aAAa;AAAA,MACd;AAAA,IACD;AAAA,IACA,MAAM,SACL,OAAO,cAAc,SAAS,YAC1B,mBACD,OAAO,WAAW,SAAS,SACzB,UACA;AAAA,IACN,OAAO;AAAA,SACH;AAAA,MACH;AAAA,MACA,eAAe,OAAO;AAAA,MACtB,aAAa,OAAO;AAAA,IACrB;AAAA,GACA;AAAA;",
9
+ "debugId": "0559E7178C9550A164756E2164756E21",
10
10
  "names": []
11
11
  }
@@ -128,4 +128,4 @@ interface PartitionSemanticDigest {
128
128
  digest: string | null;
129
129
  digest_spec: SemanticDigestSpec;
130
130
  }
131
- export { semanticDigest, canonicalJson, TransactionDigestInput, SemanticDigestV1, SemanticDigestSpec, SemanticDigestRollup, SemanticDigestApi, SEMANTIC_DIGEST_SPEC_V1, PartitionSemanticDigest, EventDigestInput, BlockDigestInput };
131
+ export { BlockDigestInput, EventDigestInput, PartitionSemanticDigest, SEMANTIC_DIGEST_SPEC_V1, SemanticDigestApi, SemanticDigestRollup, SemanticDigestSpec, SemanticDigestV1, TransactionDigestInput, canonicalJson, semanticDigest };
@@ -1,19 +1,3 @@
1
- import { createRequire } from "node:module";
2
- var __defProp = Object.defineProperty;
3
- var __returnValue = (v) => v;
4
- function __exportSetter(name, newValue) {
5
- this[name] = __returnValue.bind(null, newValue);
6
- }
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, {
10
- get: all[name],
11
- enumerable: true,
12
- configurable: true,
13
- set: __exportSetter.bind(all, name)
14
- });
15
- };
16
-
17
1
  // src/archive/semantic-digest.ts
18
2
  import { createHash } from "node:crypto";
19
3
  var SEMANTIC_DIGEST_SPEC_V1 = "sha256:semantic-v1";
@@ -133,11 +117,11 @@ class SemanticDigestRollup {
133
117
  }
134
118
  }
135
119
  export {
136
- semanticDigest,
137
- canonicalJson,
120
+ SEMANTIC_DIGEST_SPEC_V1,
138
121
  SemanticDigestRollup,
139
- SEMANTIC_DIGEST_SPEC_V1
122
+ canonicalJson,
123
+ semanticDigest
140
124
  };
141
125
 
142
- //# debugId=85768A1D774EC06C64756E2164756E21
126
+ //# debugId=875B24339EB4B9CB64756E2164756E21
143
127
  //# sourceMappingURL=semantic-digest.js.map
@@ -4,7 +4,7 @@
4
4
  "sourcesContent": [
5
5
  "import { createHash } from \"node:crypto\";\n\n/**\n * v1 canonical byte encoding for chain identity — the shape that lets\n * independently-run runtimes agree on the same block.\n *\n * The exact-body digest (`sha256:parquet-object`) proves capture fidelity to one\n * source: replay the same bytes, get the same rows. It cannot prove two nodes\n * observed the same chain, because their Parquet encoders legally differ in\n * column padding, compression, JSON key order, and null placement — two\n * operators processing the same block can ship byte-different Parquets that\n * carry identical content.\n *\n * The semantic digest is the shape that lets independent runtimes agree. Every\n * value on a block/transaction/event is normalized into a canonical byte string\n * by rules that MUST NOT change without a version bump. Two v1 computations\n * over the same range agree, or one is wrong about the chain — never about\n * formatting.\n *\n * Encoding rules (v1):\n * - Fields join with `\\x1f` (ASCII US, unit separator — cannot legally\n * appear in any chain value; a printable delimiter risks collision with\n * contract-emitted strings).\n * - Null encodes as `\\x00` (single NUL). Distinct from empty string `\"\"`.\n * - Integers encode as their base-10 string. bigint → decimal string.\n * - JSON payload columns (function_args, event data) encode as canonical\n * JSON: object keys sorted lexicographically, no whitespace, bigint →\n * quoted decimal string, non-finite numbers rejected.\n * - Field order per record type is fixed and never reordered.\n * - Digest = sha256(bytes), lowercase hex.\n *\n * Rollup rules (v1) — order MUST match the archive's stream order or an\n * honest re-export will disagree with the manifest:\n * - blocks: (height asc)\n * - transactions: (block_height asc, tx_index asc, tx_id asc)\n * - events: (block_height asc, event_index asc, tx_id asc)\n * Per-partition rollup is `sha256(concat(row_digest_bytes))` in stream order.\n *\n * Test vectors under `packages/shared/src/archive/__fixtures__/semantic-digest/`\n * pin the encoding. Any change to bytes must bump the spec version.\n */\n\nexport const SEMANTIC_DIGEST_SPEC_V1 = \"sha256:semantic-v1\" as const;\nexport type SemanticDigestSpec = typeof SEMANTIC_DIGEST_SPEC_V1;\n\nconst FIELD_SEP = \"\\x1f\";\nconst NULL_MARKER = \"\\x00\";\n\nconst textEncoder = new TextEncoder();\n\n/**\n * Stable JSON — sorted keys, no whitespace, bigint → decimal string. Distinct\n * from `JSON.stringify(x)` which respects insertion order and rejects bigints.\n * Also rejects non-finite numbers, since NaN/Infinity have no on-chain meaning\n * and would silently hash as `null` under `JSON.stringify`.\n */\nexport function canonicalJson(value: unknown): string {\n\tif (value === null) return \"null\";\n\tif (typeof value === \"string\" || typeof value === \"boolean\") {\n\t\treturn JSON.stringify(value);\n\t}\n\tif (typeof value === \"number\") {\n\t\tif (!Number.isFinite(value)) {\n\t\t\tthrow new Error(\"canonicalJson: non-finite number\");\n\t\t}\n\t\treturn JSON.stringify(value);\n\t}\n\tif (typeof value === \"bigint\") return JSON.stringify(value.toString());\n\tif (Array.isArray(value)) {\n\t\treturn `[${value.map((item) => canonicalJson(item)).join(\",\")}]`;\n\t}\n\tif (typeof value === \"object\") {\n\t\tconst object = value as Record<string, unknown>;\n\t\treturn `{${Object.keys(object)\n\t\t\t.sort()\n\t\t\t.map((key) => `${JSON.stringify(key)}:${canonicalJson(object[key])}`)\n\t\t\t.join(\",\")}}`;\n\t}\n\t// undefined / function / symbol — never present in decoded chain rows.\n\t// Fall through as null so tests catch unexpected shapes.\n\treturn \"null\";\n}\n\nfunction scalar(value: string | number | bigint | null | undefined): string {\n\tif (value === null || value === undefined) return NULL_MARKER;\n\tif (typeof value === \"number\") {\n\t\tif (!Number.isFinite(value)) {\n\t\t\tthrow new Error(\"semanticDigest: non-finite number\");\n\t\t}\n\t\tif (!Number.isInteger(value)) {\n\t\t\t// Chain heights, indexes, timestamps are all integer; a fractional\n\t\t\t// value here is a schema bug we want to surface loudly, not silently\n\t\t\t// serialize with float precision that varies by runtime.\n\t\t\tthrow new Error(`semanticDigest: non-integer scalar ${value}`);\n\t\t}\n\t\treturn String(value);\n\t}\n\tif (typeof value === \"bigint\") return value.toString();\n\treturn value;\n}\n\nfunction jsonScalar(value: unknown): string {\n\treturn value === null || value === undefined\n\t\t? NULL_MARKER\n\t\t: canonicalJson(value);\n}\n\nfunction sha256Hex(input: Uint8Array | string): string {\n\treturn createHash(\"sha256\").update(input).digest(\"hex\");\n}\n\nexport interface BlockDigestInput {\n\theight: number | bigint;\n\thash: string;\n\tparent_hash: string;\n\tburn_block_height: number | bigint;\n\tburn_block_hash: string | null;\n\tindex_block_hash: string | null;\n\ttimestamp: number | bigint;\n}\n\nexport interface TransactionDigestInput {\n\ttx_id: string;\n\tblock_height: number | bigint;\n\ttx_index: number;\n\ttype: string;\n\tsender: string;\n\tstatus: string;\n\tcontract_id: string | null;\n\tfunction_name: string | null;\n\tfunction_args: unknown;\n\traw_result: string | null;\n\traw_tx: string;\n}\n\nexport interface EventDigestInput {\n\ttx_id: string;\n\tblock_height: number | bigint;\n\tevent_index: number;\n\ttype: string;\n\tdata: unknown;\n}\n\nfunction encodeBlock(row: BlockDigestInput): string {\n\treturn [\n\t\tscalar(row.height),\n\t\tscalar(row.hash),\n\t\tscalar(row.parent_hash),\n\t\tscalar(row.burn_block_height),\n\t\tscalar(row.burn_block_hash),\n\t\tscalar(row.index_block_hash),\n\t\tscalar(row.timestamp),\n\t].join(FIELD_SEP);\n}\n\nfunction encodeTransaction(row: TransactionDigestInput): string {\n\treturn [\n\t\tscalar(row.tx_id),\n\t\tscalar(row.block_height),\n\t\tscalar(row.tx_index),\n\t\tscalar(row.type),\n\t\tscalar(row.sender),\n\t\tscalar(row.status),\n\t\tscalar(row.contract_id),\n\t\tscalar(row.function_name),\n\t\tjsonScalar(row.function_args),\n\t\tscalar(row.raw_result),\n\t\tscalar(row.raw_tx),\n\t].join(FIELD_SEP);\n}\n\nfunction encodeEvent(row: EventDigestInput): string {\n\treturn [\n\t\tscalar(row.tx_id),\n\t\tscalar(row.block_height),\n\t\tscalar(row.event_index),\n\t\tscalar(row.type),\n\t\tjsonScalar(row.data),\n\t].join(FIELD_SEP);\n}\n\n/**\n * v1 per-row digests. Each is `sha256(encoded_row_bytes)` in lowercase hex.\n * The encoded byte form is stable across runtimes; the sha256 is stable\n * across CPU architectures. Never mutate an encoder without a v-bump.\n */\nexport interface SemanticDigestV1 {\n\treadonly spec: SemanticDigestSpec;\n\treadonly encodeBlock: (row: BlockDigestInput) => string;\n\treadonly encodeTransaction: (row: TransactionDigestInput) => string;\n\treadonly encodeEvent: (row: EventDigestInput) => string;\n\treadonly block: (row: BlockDigestInput) => string;\n\treadonly transaction: (row: TransactionDigestInput) => string;\n\treadonly event: (row: EventDigestInput) => string;\n}\n\nexport interface SemanticDigestApi {\n\treadonly v1: SemanticDigestV1;\n}\n\nexport const semanticDigest: SemanticDigestApi = {\n\tv1: {\n\t\tspec: SEMANTIC_DIGEST_SPEC_V1,\n\t\tencodeBlock,\n\t\tencodeTransaction,\n\t\tencodeEvent,\n\t\tblock: (row: BlockDigestInput): string =>\n\t\t\tsha256Hex(textEncoder.encode(encodeBlock(row))),\n\t\ttransaction: (row: TransactionDigestInput): string =>\n\t\t\tsha256Hex(textEncoder.encode(encodeTransaction(row))),\n\t\tevent: (row: EventDigestInput): string =>\n\t\t\tsha256Hex(textEncoder.encode(encodeEvent(row))),\n\t},\n};\n\n/**\n * Streaming rollup — feed rows one at a time in their declared order, read the\n * rolled digest at the end. Two callers passing the same rows in the same order\n * produce the same rollup, regardless of batching.\n *\n * The rollup composes: partition_digest = sha256(concat(row_digest_bytes)),\n * where each row_digest_bytes = sha256(encode(row)). This is why the streaming\n * implementation can be constant-memory — the outer sha256 accepts row digests\n * incrementally.\n */\nexport class SemanticDigestRollup {\n\tprivate readonly hasher = createHash(\"sha256\");\n\tprivate count = 0;\n\n\tstatic forDataset(\n\t\t_dataset: \"blocks\" | \"transactions\" | \"events\",\n\t): SemanticDigestRollup {\n\t\treturn new SemanticDigestRollup();\n\t}\n\n\tappendRowDigest(rowDigestHex: string): void {\n\t\tthis.hasher.update(Buffer.from(rowDigestHex, \"hex\"));\n\t\tthis.count += 1;\n\t}\n\n\trowCount(): number {\n\t\treturn this.count;\n\t}\n\n\t/** Empty rollups return `null`, not the sha256 of nothing, so an empty\n\t * range never compares equal to another empty range on a different\n\t * dataset. Callers assign `null` semantics deliberately. */\n\tdigest(): string | null {\n\t\treturn this.count === 0 ? null : this.hasher.copy().digest(\"hex\");\n\t}\n\n\tspec(): SemanticDigestSpec {\n\t\treturn SEMANTIC_DIGEST_SPEC_V1;\n\t}\n}\n\n/**\n * Per-partition digest record — the shape that lands in the snapshot manifest.\n * Complements the existing `sha256:parquet-object` per-partition digest by\n * proving semantic identity independent of file encoding.\n */\nexport interface PartitionSemanticDigest {\n\tdataset: \"blocks\" | \"transactions\" | \"events\";\n\tfrom_block: number;\n\tto_block: number;\n\trow_count: number;\n\tdigest: string | null;\n\tdigest_spec: SemanticDigestSpec;\n}\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "85768A1D774EC06C64756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "875B24339EB4B9CB64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -114,4 +114,4 @@ declare function nextScheduledArchivePublish(now: Date): Date;
114
114
  declare function deriveArchiveStatus(inputs: StatusInputs): ArchiveStatus;
115
115
  /** States a consumer should refuse to restore from. */
116
116
  declare function isRestorable(state: ArchiveState): boolean;
117
- export { nextScheduledArchivePublish, isRestorable, deriveArchiveStatus, StatusInputs, ArchiveStatus, ArchiveState, ARCHIVE_STATUS_SCHEMA_VERSION };
117
+ export { ARCHIVE_STATUS_SCHEMA_VERSION, ArchiveState, ArchiveStatus, StatusInputs, deriveArchiveStatus, isRestorable, nextScheduledArchivePublish };
@@ -1,19 +1,3 @@
1
- import { createRequire } from "node:module";
2
- var __defProp = Object.defineProperty;
3
- var __returnValue = (v) => v;
4
- function __exportSetter(name, newValue) {
5
- this[name] = __returnValue.bind(null, newValue);
6
- }
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, {
10
- get: all[name],
11
- enumerable: true,
12
- configurable: true,
13
- set: __exportSetter.bind(all, name)
14
- });
15
- };
16
-
17
1
  // src/archive/status.ts
18
2
  var ARCHIVE_STATUS_SCHEMA_VERSION = 1;
19
3
  var DEFAULT_MAX_BLOCKS_BEHIND_FINALIZED = 60000;
@@ -121,11 +105,11 @@ function isRestorable(state) {
121
105
  return state === "fresh" || state === "lagging";
122
106
  }
123
107
  export {
124
- nextScheduledArchivePublish,
125
- isRestorable,
108
+ ARCHIVE_STATUS_SCHEMA_VERSION,
126
109
  deriveArchiveStatus,
127
- ARCHIVE_STATUS_SCHEMA_VERSION
110
+ isRestorable,
111
+ nextScheduledArchivePublish
128
112
  };
129
113
 
130
- //# debugId=C18B5116B1FC55FB64756E2164756E21
114
+ //# debugId=779DB5C9B354565F64756E2164756E21
131
115
  //# sourceMappingURL=status.js.map
@@ -4,7 +4,7 @@
4
4
  "sourcesContent": [
5
5
  "/**\n * `status.json` — the archive's operational truth, published short-cache from\n * verified state only.\n *\n * Everything else in the tree is immutable and signed, which makes it durable\n * but silent: a consumer holding a valid manifest cannot tell whether it is\n * current, three days behind, or the last thing published before an incident.\n * This object answers that, and it is the only object allowed to say something\n * unflattering.\n *\n * The distinction this file exists to protect:\n *\n * lagging → the archive trails the chain tip. This is CORRECT and permanent.\n * Two expected causes: twice-weekly publish (Wednesday and Sunday)\n * and the finality boundary. Cadence is the bulk of the gap;\n * finality is hours, not days. An archive that reported `stale`\n * for its own expected lag would be crying wolf forever, and\n * consumers would learn to ignore it.\n * stale → publishing stopped. The lag exceeds what cadence and the\n * finality rule can explain, so something is broken.\n *\n * `state` is derived from measurements, never asserted by the publisher, and\n * every unhealthy state is reachable — an archive that can only report health\n * is decoration.\n */\n\n/**\n * v1 is additive. `source.decoder_head` joined the object without a bump:\n * it does not change the meaning of any existing field, and readers already\n * ignore unknown keys. Bump only if a field is renamed, removed, or\n * re-interpreted.\n */\nexport const ARCHIVE_STATUS_SCHEMA_VERSION = 1;\n\nexport type ArchiveState =\n\t| \"fresh\"\n\t| \"lagging\"\n\t| \"stale\"\n\t| \"gap\"\n\t| \"failed-audit\"\n\t| \"source-unavailable\";\n\nexport type ArchiveStatus = {\n\tschema_version: typeof ARCHIVE_STATUS_SCHEMA_VERSION;\n\tnetwork: string;\n\tstate: ArchiveState;\n\t/** Human-facing one-liner explaining the state, including WHY. */\n\tdetail: string;\n\tgenerated_at: string;\n\tarchive: {\n\t\tsnapshot_digest: string | null;\n\t\tcoverage_to_block: number | null;\n\t\tpromoted_at: string | null;\n\t\tsigning_key_id: string | null;\n\t};\n\tsource: {\n\t\t/** Chain tip as the publisher last observed it. Null when unreachable. */\n\t\ttip_height: number | null;\n\t\t/** Highest height eligible to publish under the finality rule. */\n\t\tfinalized_height: number | null;\n\t\t/**\n\t\t * Highest height the Index decoder (`decode.ft_transfer.v1`) has\n\t\t * committed. Null when the checkpoint cannot be read. Distinct from\n\t\t * `archive.coverage_to_block`, which is the last signed publish.\n\t\t */\n\t\tdecoder_head: number | null;\n\t};\n\tlag: {\n\t\t/** Behind the FINALIZED height — the number that indicates a problem. */\n\t\tblocks_behind_finalized: number | null;\n\t\t/** Behind the raw chain tip — expected to be non-zero forever. */\n\t\tblocks_behind_tip: number | null;\n\t\tseconds_since_promotion: number | null;\n\t};\n\taudit: {\n\t\tcomplete: boolean;\n\t\tchecked_at: string;\n\t} | null;\n\tsignature?: string;\n\tkey_id?: string;\n};\n\nexport type StatusInputs = {\n\tnetwork: string;\n\tsnapshotDigest: string | null;\n\tcoverageToBlock: number | null;\n\tpromotedAt: string | null;\n\tsigningKeyId: string | null;\n\t/** Null when the source could not be reached. */\n\tsourceTipHeight: number | null;\n\tfinalizedHeight: number | null;\n\t/**\n\t * Index decoder checkpoint height. Null when unread or unreachable.\n\t * Reported, never used to derive `state`.\n\t */\n\tdecoderHead?: number | null;\n\taudit: { complete: boolean; checkedAt: string } | null;\n\tnow: Date;\n\t/**\n\t * How far behind the FINALIZED height the archive may fall before it is\n\t * stale rather than merely lagging. Publishing one partition covers 50k\n\t * blocks, so a healthy archive sits well inside this.\n\t */\n\tmaxBlocksBehindFinalized?: number;\n\t/** How long since the last promotion before staleness, regardless of height. */\n\tmaxSecondsSincePromotion?: number;\n};\n\nconst DEFAULT_MAX_BLOCKS_BEHIND_FINALIZED = 60_000;\n/**\n * Must exceed the publish cadence, or the archive reports `stale` on every\n * healthy cycle and the signal means nothing.\n *\n * The publisher runs Wed + Sun, so the longest gap between promotions in a\n * healthy week is 4 days. Five days leaves a day of grace for a slow export or\n * timer jitter, and still fires two days before the next scheduled attempt\n * whenever a cycle is actually missed.\n *\n * It also lands just inside the height rule: at the observed ~7–9k blocks/day\n * the archive is ~45k blocks behind finalized at the five-day mark, so age\n * trips first and reports the more diagnostic message (\"publishing stopped\")\n * rather than the symptom.\n */\nconst DEFAULT_MAX_SECONDS_SINCE_PROMOTION = 5 * 24 * 3_600;\n\n/** systemd `OnCalendar=Wed,Sun *-*-* 08:00:00`. Host is UTC. Job start, not promotion landing. */\nconst PUBLISH_HOUR_UTC = 8;\nconst PUBLISH_WEEKDAYS_UTC = new Set([0, 3]);\n\n/**\n * Next twice-weekly publish fire strictly after `now`. Matches\n * `secondlayer-archive-publish.timer`. Export duration means the promotion\n * lands hours later; this is the scheduled start.\n */\nexport function nextScheduledArchivePublish(now: Date): Date {\n\tfor (let i = 0; i <= 7; i++) {\n\t\tconst candidate = new Date(\n\t\t\tDate.UTC(\n\t\t\t\tnow.getUTCFullYear(),\n\t\t\t\tnow.getUTCMonth(),\n\t\t\t\tnow.getUTCDate() + i,\n\t\t\t\tPUBLISH_HOUR_UTC,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t),\n\t\t);\n\t\tif (PUBLISH_WEEKDAYS_UTC.has(candidate.getUTCDay()) && candidate > now) {\n\t\t\treturn candidate;\n\t\t}\n\t}\n\tthrow new Error(\"nextScheduledArchivePublish: no fire in 7 days\");\n}\n\nfunction publishWeekdayName(date: Date): \"Sunday\" | \"Wednesday\" {\n\treturn date.getUTCDay() === 0 ? \"Sunday\" : \"Wednesday\";\n}\n\n/**\n * Durations here run to days, and \"beyond the 120h objective\" makes a reader do\n * arithmetic before they can tell whether that is alarming.\n */\nfunction formatAge(seconds: number): string {\n\tconst hours = seconds / 3_600;\n\tif (hours < 48) return `${Math.round(hours)}h`;\n\tconst days = hours / 24;\n\t// One decimal only when it changes the reading: 4d and 4.5d are different\n\t// facts during an incident, 5.0d is noise.\n\tconst rounded = Math.round(days * 10) / 10;\n\treturn `${Number.isInteger(rounded) ? rounded : rounded.toFixed(1)}d`;\n}\n\n/**\n * Derive status from measurements. Pure, so every state below is reachable in\n * a test rather than only in production at 3am.\n *\n * Order matters: a failing audit outranks freshness, because an archive that\n * is current and wrong is worse than one that is behind and correct.\n */\nexport function deriveArchiveStatus(inputs: StatusInputs): ArchiveStatus {\n\tconst maxBehind =\n\t\tinputs.maxBlocksBehindFinalized ?? DEFAULT_MAX_BLOCKS_BEHIND_FINALIZED;\n\tconst maxAge =\n\t\tinputs.maxSecondsSincePromotion ?? DEFAULT_MAX_SECONDS_SINCE_PROMOTION;\n\n\tconst secondsSincePromotion = inputs.promotedAt\n\t\t? Math.max(\n\t\t\t\t0,\n\t\t\t\tMath.round(\n\t\t\t\t\t(inputs.now.getTime() - Date.parse(inputs.promotedAt)) / 1000,\n\t\t\t\t),\n\t\t\t)\n\t\t: null;\n\n\tconst behindFinalized =\n\t\tinputs.finalizedHeight !== null && inputs.coverageToBlock !== null\n\t\t\t? Math.max(0, inputs.finalizedHeight - inputs.coverageToBlock)\n\t\t\t: null;\n\tconst behindTip =\n\t\tinputs.sourceTipHeight !== null && inputs.coverageToBlock !== null\n\t\t\t? Math.max(0, inputs.sourceTipHeight - inputs.coverageToBlock)\n\t\t\t: null;\n\n\tconst base = {\n\t\tschema_version:\n\t\t\tARCHIVE_STATUS_SCHEMA_VERSION as typeof ARCHIVE_STATUS_SCHEMA_VERSION,\n\t\tnetwork: inputs.network,\n\t\tgenerated_at: inputs.now.toISOString(),\n\t\tarchive: {\n\t\t\tsnapshot_digest: inputs.snapshotDigest,\n\t\t\tcoverage_to_block: inputs.coverageToBlock,\n\t\t\tpromoted_at: inputs.promotedAt,\n\t\t\tsigning_key_id: inputs.signingKeyId,\n\t\t},\n\t\tsource: {\n\t\t\ttip_height: inputs.sourceTipHeight,\n\t\t\tfinalized_height: inputs.finalizedHeight,\n\t\t\tdecoder_head: inputs.decoderHead ?? null,\n\t\t},\n\t\tlag: {\n\t\t\tblocks_behind_finalized: behindFinalized,\n\t\t\tblocks_behind_tip: behindTip,\n\t\t\tseconds_since_promotion: secondsSincePromotion,\n\t\t},\n\t\taudit: inputs.audit\n\t\t\t? { complete: inputs.audit.complete, checked_at: inputs.audit.checkedAt }\n\t\t\t: null,\n\t};\n\n\t// A failed audit is the loudest signal: current-and-wrong beats behind-and-right.\n\tif (inputs.audit && !inputs.audit.complete) {\n\t\treturn {\n\t\t\t...base,\n\t\t\tstate: \"failed-audit\",\n\t\t\tdetail: `the canonical audit did not pass at ${inputs.audit.checkedAt}; this archive is not safe to restore from`,\n\t\t};\n\t}\n\n\tif (!inputs.snapshotDigest || inputs.coverageToBlock === null) {\n\t\treturn {\n\t\t\t...base,\n\t\t\tstate: \"gap\",\n\t\t\tdetail: \"no snapshot is currently promoted\",\n\t\t};\n\t}\n\n\t// Source unreachable: report the gap in KNOWLEDGE rather than guessing. The\n\t// archive may be perfectly healthy; we cannot currently say so.\n\tif (inputs.sourceTipHeight === null || inputs.finalizedHeight === null) {\n\t\treturn {\n\t\t\t...base,\n\t\t\tstate: \"source-unavailable\",\n\t\t\tdetail:\n\t\t\t\t\"the chain source could not be reached, so freshness cannot be determined\",\n\t\t};\n\t}\n\n\tif (secondsSincePromotion !== null && secondsSincePromotion > maxAge) {\n\t\treturn {\n\t\t\t...base,\n\t\t\tstate: \"stale\",\n\t\t\tdetail: `last promotion was ${formatAge(secondsSincePromotion)} ago, beyond the ${formatAge(maxAge)} freshness objective`,\n\t\t};\n\t}\n\n\tif (behindFinalized !== null && behindFinalized > maxBehind) {\n\t\treturn {\n\t\t\t...base,\n\t\t\tstate: \"stale\",\n\t\t\tdetail: `${behindFinalized} blocks behind the finalized height, beyond the ${maxBehind} threshold`,\n\t\t};\n\t}\n\n\t// Behind the tip. CORRECT and permanent: twice-weekly publish plus the\n\t// finality boundary. Cadence is the bulk of the gap. Do not call this stale.\n\tif (behindTip !== null && behindTip > 0) {\n\t\tconst nextDay = publishWeekdayName(nextScheduledArchivePublish(inputs.now));\n\t\treturn {\n\t\t\t...base,\n\t\t\tstate: \"lagging\",\n\t\t\tdetail: `${behindTip} blocks behind the chain tip, which is expected: publishing is twice weekly (Wednesday and Sunday, next ${nextDay}) and stops at the finality boundary`,\n\t\t};\n\t}\n\n\treturn {\n\t\t...base,\n\t\tstate: \"fresh\",\n\t\tdetail: \"published through the finalized height\",\n\t};\n}\n\n/** States a consumer should refuse to restore from. */\nexport function isRestorable(state: ArchiveState): boolean {\n\treturn state === \"fresh\" || state === \"lagging\";\n}\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "C18B5116B1FC55FB64756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "779DB5C9B354565F64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -470,7 +470,6 @@ interface SubgraphsTable {
470
470
  handler_code: string | null;
471
471
  source_code: string | null;
472
472
  project_id: string | null;
473
- visibility: Generated<string>;
474
473
  /** Paid (wallet-ghost) deploys expire unless renewed or claimed; NULL = no expiry. */
475
474
  expires_at: Date | null;
476
475
  /** (event type, contract) probe pairs persisted at deploy for weight classification. */
@@ -1496,4 +1495,4 @@ declare function reportVerify(opts: {
1496
1495
  diverged?: boolean
1497
1496
  detail?: string
1498
1497
  }): VerifyReport;
1499
- export { versionsEqual, topoSort, sparseDigests, sequentialDigests, segmentsSurviveReorg, segmentsOverlap, sealFinalizedRange, runSubgraphCommitSteps, runDecoderCommitSteps, reportVerify, receiptsAfterReorg, receiptRetentionHolds, rangeIsOrdered, rangeDigestOf, queueCaughtUp, proofsAgree, planRepair, planDecoderReceipts, parseVerifyTarget, mergeRanges, manifestsEqual, lookupTransition, isStageKind, isRunStatus, isRetryState, isRepairMode, isNonNegativeInt, isNativeClock, isFailureUnit, isFailureClass, inputDigest, hashEffectManifest, findRangeGaps, finalRowDigest, failureRetentionHolds, failureRangeHolds, expectedAckHeight, evaluateCoverage, emptyQueueState, defaultRetainUntil, deepVerify, datasetMatchesTarget, cursorIsBeforeBlock, cursorIsAfterBlock, cursorHeight, createRunnerState, contiguousThrough, commitSubgraphAdapter, commitDecoderAdapter, canonicalizeMutations, applyRunnerEvent, applyQueueEvent, applyMutations, applyDecoderReceipts, VerifyTarget, VerifyReport, VerifyMode, VerifyExit, VERIFY_EXIT, TransitionRule, SyncScope, SubgraphCommitStep, SubgraphCommitInput, SubgraphAdapterCrash, StageRunView, StageKind, StageEvidence, StageDeclaration, StageCoverage, SourceClock, SealedSegment, SealableReceipt, SealResult, SUBGRAPH_COMMIT_STEPS, STAGE_KINDS, SAFE_REPAIR_MODES, RunnerVersion, RunnerStatus, RunnerState, RunnerResult, RunnerFailure, RunnerEventType, RunnerEvent, RunnerEffect, RunStatus, RowSnapshot, RetryState, RepairPlan, RepairMode, RepairDefect, ReceiptRow, RUN_STATUSES, RUNNER_TRANSITION_TABLE, RUNNER_STATUSES, RUNNER_EVENT_TYPES, RETRY_STATES, REPAIR_MODES, QueueState, QueueStage, QueueEvent, QueueCounters, QueueApply, QUEUE_STAGES, OpenFailure, NativeClock, NATIVE_CLOCKS, FailureUnit, FailureRow, FailureClass, FAILURE_UNITS, FAILURE_RETENTION_DAYS, FAILURE_CLASSES, EvaluatorOptions, EvaluatorInput, EffectOp, EffectMutation, DeepVerifyResult, DecoderCommitStep, DecoderClockResult, DecoderClockReceipt, DecoderClockInput, DecoderClockEvent, DecoderAdapterReceipt, DecoderAdapterFailure, DecoderAdapterCrash, DecoderAdapterCommit, DEFAULT_MAX_RETRIES, DECODER_COMMIT_STEPS, CoverageState, CoverageReport, CoverageRange, CanonicalBlock, COVERAGE_STATES, COVERAGE_REPORT_SCHEMA_VERSION, BootstrapSource };
1498
+ export { BootstrapSource, COVERAGE_REPORT_SCHEMA_VERSION, COVERAGE_STATES, CanonicalBlock, CoverageRange, CoverageReport, CoverageState, DECODER_COMMIT_STEPS, DEFAULT_MAX_RETRIES, DecoderAdapterCommit, DecoderAdapterCrash, DecoderAdapterFailure, DecoderAdapterReceipt, DecoderClockEvent, DecoderClockInput, DecoderClockReceipt, DecoderClockResult, DecoderCommitStep, DeepVerifyResult, EffectMutation, EffectOp, EvaluatorInput, EvaluatorOptions, FAILURE_CLASSES, FAILURE_RETENTION_DAYS, FAILURE_UNITS, FailureClass, FailureRow, FailureUnit, NATIVE_CLOCKS, NativeClock, OpenFailure, QUEUE_STAGES, QueueApply, QueueCounters, QueueEvent, QueueStage, QueueState, REPAIR_MODES, RETRY_STATES, RUNNER_EVENT_TYPES, RUNNER_STATUSES, RUNNER_TRANSITION_TABLE, RUN_STATUSES, ReceiptRow, RepairDefect, RepairMode, RepairPlan, RetryState, RowSnapshot, RunStatus, RunnerEffect, RunnerEvent, RunnerEventType, RunnerFailure, RunnerResult, RunnerState, RunnerStatus, RunnerVersion, SAFE_REPAIR_MODES, STAGE_KINDS, SUBGRAPH_COMMIT_STEPS, SealResult, SealableReceipt, SealedSegment, SourceClock, StageCoverage, StageDeclaration, StageEvidence, StageKind, StageRunView, SubgraphAdapterCrash, SubgraphCommitInput, SubgraphCommitStep, SyncScope, TransitionRule, VERIFY_EXIT, VerifyExit, VerifyMode, VerifyReport, VerifyTarget, applyDecoderReceipts, applyMutations, applyQueueEvent, applyRunnerEvent, canonicalizeMutations, commitDecoderAdapter, commitSubgraphAdapter, contiguousThrough, createRunnerState, cursorHeight, cursorIsAfterBlock, cursorIsBeforeBlock, datasetMatchesTarget, deepVerify, defaultRetainUntil, emptyQueueState, evaluateCoverage, expectedAckHeight, failureRangeHolds, failureRetentionHolds, finalRowDigest, findRangeGaps, hashEffectManifest, inputDigest, isFailureClass, isFailureUnit, isNativeClock, isNonNegativeInt, isRepairMode, isRetryState, isRunStatus, isStageKind, lookupTransition, manifestsEqual, mergeRanges, parseVerifyTarget, planDecoderReceipts, planRepair, proofsAgree, queueCaughtUp, rangeDigestOf, rangeIsOrdered, receiptRetentionHolds, receiptsAfterReorg, reportVerify, runDecoderCommitSteps, runSubgraphCommitSteps, sealFinalizedRange, segmentsOverlap, segmentsSurviveReorg, sequentialDigests, sparseDigests, topoSort, versionsEqual };
@@ -1,19 +1,3 @@
1
- import { createRequire } from "node:module";
2
- var __defProp = Object.defineProperty;
3
- var __returnValue = (v) => v;
4
- function __exportSetter(name, newValue) {
5
- this[name] = __returnValue.bind(null, newValue);
6
- }
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, {
10
- get: all[name],
11
- enumerable: true,
12
- configurable: true,
13
- set: __exportSetter.bind(all, name)
14
- });
15
- };
16
-
17
1
  // src/coverage/constraints.ts
18
2
  var STAGE_KINDS = ["raw", "decode", "subgraph", "queue"];
19
3
  var NATIVE_CLOCKS = ["block", "cursor", "queue"];
@@ -347,13 +331,13 @@ function evaluateOne(stage, input, run, evidence, dep, missingDep, inCycle) {
347
331
  recorded_target: recordedTarget
348
332
  };
349
333
  const done = (state, detail, extra = {}) => {
350
- const completeThrough2 = extra.complete_through ?? null;
351
- const caughtUp = extra.caught_up ?? (state !== "disabled" && state !== "failed" && state !== "gap" && state !== "out_of_scope" && state !== "unverified_import" && state !== "unanchored" && state !== "source_unavailable" && completeThrough2 !== null && finalized !== null && completeThrough2 >= finalized && sourceFresh);
334
+ const completeThrough = extra.complete_through ?? null;
335
+ const caughtUp = extra.caught_up ?? (state !== "disabled" && state !== "failed" && state !== "gap" && state !== "out_of_scope" && state !== "unverified_import" && state !== "unanchored" && state !== "source_unavailable" && completeThrough !== null && finalized !== null && completeThrough >= finalized && sourceFresh);
352
336
  return {
353
337
  ...base,
354
338
  state,
355
339
  detail,
356
- complete_through: completeThrough2,
340
+ complete_through: completeThrough,
357
341
  declared_range: extra.declared_range ?? null,
358
342
  gaps: extra.gaps ?? [],
359
343
  caught_up: caughtUp,
@@ -638,8 +622,8 @@ function rewind(state, forkPoint) {
638
622
  }
639
623
  function applyRetry(state, maxRetries) {
640
624
  if (state.retry_count >= maxRetries) {
641
- const failure2 = state.open_failure ? { ...state.open_failure, retry_state: "halted" } : null;
642
- return ok(clone(state, { status: "halted", open_failure: failure2 }));
625
+ const failure = state.open_failure ? { ...state.open_failure, retry_state: "halted" } : null;
626
+ return ok(clone(state, { status: "halted", open_failure: failure }));
643
627
  }
644
628
  const failure = state.open_failure ? { ...state.open_failure, retry_state: "retrying" } : null;
645
629
  return ok(clone(state, {
@@ -1392,82 +1376,82 @@ function reportVerify(opts) {
1392
1376
  };
1393
1377
  }
1394
1378
  export {
1395
- versionsEqual,
1396
- topoSort,
1397
- sparseDigests,
1398
- sequentialDigests,
1399
- segmentsSurviveReorg,
1400
- segmentsOverlap,
1401
- sealFinalizedRange,
1402
- runSubgraphCommitSteps,
1403
- runDecoderCommitSteps,
1404
- reportVerify,
1405
- receiptsAfterReorg,
1406
- receiptRetentionHolds,
1407
- rangeIsOrdered,
1408
- rangeDigestOf,
1409
- queueCaughtUp,
1410
- proofsAgree,
1411
- planRepair,
1412
- planDecoderReceipts,
1413
- parseVerifyTarget,
1414
- mergeRanges,
1415
- manifestsEqual,
1416
- lookupTransition,
1417
- isStageKind,
1418
- isRunStatus,
1419
- isRetryState,
1420
- isRepairMode,
1421
- isNonNegativeInt,
1422
- isNativeClock,
1423
- isFailureUnit,
1424
- isFailureClass,
1425
- inputDigest,
1426
- hashEffectManifest,
1427
- findRangeGaps,
1428
- finalRowDigest,
1429
- failureRetentionHolds,
1430
- failureRangeHolds,
1431
- expectedAckHeight,
1432
- evaluateCoverage,
1433
- emptyQueueState,
1434
- defaultRetainUntil,
1435
- deepVerify,
1436
- datasetMatchesTarget,
1437
- cursorIsBeforeBlock,
1438
- cursorIsAfterBlock,
1439
- cursorHeight,
1440
- createRunnerState,
1441
- contiguousThrough,
1442
- commitSubgraphAdapter,
1443
- commitDecoderAdapter,
1444
- canonicalizeMutations,
1445
- applyRunnerEvent,
1446
- applyQueueEvent,
1447
- applyMutations,
1448
- applyDecoderReceipts,
1449
- VERIFY_EXIT,
1450
- SubgraphAdapterCrash,
1451
- SUBGRAPH_COMMIT_STEPS,
1452
- STAGE_KINDS,
1453
- SAFE_REPAIR_MODES,
1454
- RUN_STATUSES,
1455
- RUNNER_TRANSITION_TABLE,
1456
- RUNNER_STATUSES,
1457
- RUNNER_EVENT_TYPES,
1458
- RETRY_STATES,
1459
- REPAIR_MODES,
1460
- QUEUE_STAGES,
1461
- NATIVE_CLOCKS,
1462
- FAILURE_UNITS,
1463
- FAILURE_RETENTION_DAYS,
1464
- FAILURE_CLASSES,
1465
- DecoderAdapterCrash,
1466
- DEFAULT_MAX_RETRIES,
1467
- DECODER_COMMIT_STEPS,
1379
+ COVERAGE_REPORT_SCHEMA_VERSION,
1468
1380
  COVERAGE_STATES,
1469
- COVERAGE_REPORT_SCHEMA_VERSION
1381
+ DECODER_COMMIT_STEPS,
1382
+ DEFAULT_MAX_RETRIES,
1383
+ DecoderAdapterCrash,
1384
+ FAILURE_CLASSES,
1385
+ FAILURE_RETENTION_DAYS,
1386
+ FAILURE_UNITS,
1387
+ NATIVE_CLOCKS,
1388
+ QUEUE_STAGES,
1389
+ REPAIR_MODES,
1390
+ RETRY_STATES,
1391
+ RUNNER_EVENT_TYPES,
1392
+ RUNNER_STATUSES,
1393
+ RUNNER_TRANSITION_TABLE,
1394
+ RUN_STATUSES,
1395
+ SAFE_REPAIR_MODES,
1396
+ STAGE_KINDS,
1397
+ SUBGRAPH_COMMIT_STEPS,
1398
+ SubgraphAdapterCrash,
1399
+ VERIFY_EXIT,
1400
+ applyDecoderReceipts,
1401
+ applyMutations,
1402
+ applyQueueEvent,
1403
+ applyRunnerEvent,
1404
+ canonicalizeMutations,
1405
+ commitDecoderAdapter,
1406
+ commitSubgraphAdapter,
1407
+ contiguousThrough,
1408
+ createRunnerState,
1409
+ cursorHeight,
1410
+ cursorIsAfterBlock,
1411
+ cursorIsBeforeBlock,
1412
+ datasetMatchesTarget,
1413
+ deepVerify,
1414
+ defaultRetainUntil,
1415
+ emptyQueueState,
1416
+ evaluateCoverage,
1417
+ expectedAckHeight,
1418
+ failureRangeHolds,
1419
+ failureRetentionHolds,
1420
+ finalRowDigest,
1421
+ findRangeGaps,
1422
+ hashEffectManifest,
1423
+ inputDigest,
1424
+ isFailureClass,
1425
+ isFailureUnit,
1426
+ isNativeClock,
1427
+ isNonNegativeInt,
1428
+ isRepairMode,
1429
+ isRetryState,
1430
+ isRunStatus,
1431
+ isStageKind,
1432
+ lookupTransition,
1433
+ manifestsEqual,
1434
+ mergeRanges,
1435
+ parseVerifyTarget,
1436
+ planDecoderReceipts,
1437
+ planRepair,
1438
+ proofsAgree,
1439
+ queueCaughtUp,
1440
+ rangeDigestOf,
1441
+ rangeIsOrdered,
1442
+ receiptRetentionHolds,
1443
+ receiptsAfterReorg,
1444
+ reportVerify,
1445
+ runDecoderCommitSteps,
1446
+ runSubgraphCommitSteps,
1447
+ sealFinalizedRange,
1448
+ segmentsOverlap,
1449
+ segmentsSurviveReorg,
1450
+ sequentialDigests,
1451
+ sparseDigests,
1452
+ topoSort,
1453
+ versionsEqual
1470
1454
  };
1471
1455
 
1472
- //# debugId=B315F53B23D43AA664756E2164756E21
1456
+ //# debugId=EA2A528F4821830864756E2164756E21
1473
1457
  //# sourceMappingURL=index.js.map