@cloudbitmaps/core 0.1.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/NOTICE +12 -0
- package/README.md +22 -0
- package/dist/azure/index.cjs +368 -0
- package/dist/azure/index.cjs.map +1 -0
- package/dist/azure/index.d.cts +48 -0
- package/dist/azure/index.d.ts +48 -0
- package/dist/azure/index.js +304 -0
- package/dist/azure/index.js.map +1 -0
- package/dist/cassandra/index.cjs +265 -0
- package/dist/cassandra/index.cjs.map +1 -0
- package/dist/cassandra/index.d.cts +52 -0
- package/dist/cassandra/index.d.ts +52 -0
- package/dist/cassandra/index.js +204 -0
- package/dist/cassandra/index.js.map +1 -0
- package/dist/chunk-2YDULGXS.js +203 -0
- package/dist/chunk-2YDULGXS.js.map +1 -0
- package/dist/chunk-7LMLYSVJ.js +43 -0
- package/dist/chunk-7LMLYSVJ.js.map +1 -0
- package/dist/chunk-AS6ODRLT.js +6 -0
- package/dist/chunk-AS6ODRLT.js.map +1 -0
- package/dist/chunk-NUIDEEFZ.js +91 -0
- package/dist/chunk-NUIDEEFZ.js.map +1 -0
- package/dist/chunk-SNJVZ227.js +35 -0
- package/dist/chunk-SNJVZ227.js.map +1 -0
- package/dist/dynamodb/index.cjs +731 -0
- package/dist/dynamodb/index.cjs.map +1 -0
- package/dist/dynamodb/index.d.cts +106 -0
- package/dist/dynamodb/index.d.ts +106 -0
- package/dist/dynamodb/index.js +460 -0
- package/dist/dynamodb/index.js.map +1 -0
- package/dist/gcs/index.cjs +343 -0
- package/dist/gcs/index.cjs.map +1 -0
- package/dist/gcs/index.d.cts +46 -0
- package/dist/gcs/index.d.ts +46 -0
- package/dist/gcs/index.js +279 -0
- package/dist/gcs/index.js.map +1 -0
- package/dist/index.cjs +4031 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1945 -0
- package/dist/index.d.ts +1945 -0
- package/dist/index.js +3642 -0
- package/dist/index.js.map +1 -0
- package/dist/mongodb/index.cjs +260 -0
- package/dist/mongodb/index.cjs.map +1 -0
- package/dist/mongodb/index.d.cts +45 -0
- package/dist/mongodb/index.d.ts +45 -0
- package/dist/mongodb/index.js +199 -0
- package/dist/mongodb/index.js.map +1 -0
- package/dist/mysql/index.cjs +281 -0
- package/dist/mysql/index.cjs.map +1 -0
- package/dist/mysql/index.d.cts +56 -0
- package/dist/mysql/index.d.ts +56 -0
- package/dist/mysql/index.js +211 -0
- package/dist/mysql/index.js.map +1 -0
- package/dist/ports-D3BrJ6ax.d.cts +357 -0
- package/dist/ports-D3BrJ6ax.d.ts +357 -0
- package/dist/postgres/index.cjs +273 -0
- package/dist/postgres/index.cjs.map +1 -0
- package/dist/postgres/index.d.cts +54 -0
- package/dist/postgres/index.d.ts +54 -0
- package/dist/postgres/index.js +203 -0
- package/dist/postgres/index.js.map +1 -0
- package/dist/redis/index.cjs +257 -0
- package/dist/redis/index.cjs.map +1 -0
- package/dist/redis/index.d.cts +42 -0
- package/dist/redis/index.d.ts +42 -0
- package/dist/redis/index.js +197 -0
- package/dist/redis/index.js.map +1 -0
- package/dist/s3/index.cjs +891 -0
- package/dist/s3/index.cjs.map +1 -0
- package/dist/s3/index.d.cts +112 -0
- package/dist/s3/index.d.ts +112 -0
- package/dist/s3/index.js +555 -0
- package/dist/s3/index.js.map +1 -0
- package/package.json +172 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/bit-route.ts","../src/core/chunk.ts","../src/core/budget.ts","../src/core/keys.ts","../src/core/metrics.ts","../src/core/retry.ts","../src/core/engine.ts","../src/core/lru.ts","../src/core/cost.ts","../src/core/audit.ts","../src/core/codec.ts","../src/core/crypto.ts","../src/core/crbm/crc32c.ts","../src/core/crbm/varint.ts","../src/core/crbm/format.ts","../src/core/crbm/reader.ts","../src/core/crbm/writer.ts","../src/core/crbm-cold-source.ts","../src/core/compaction.ts","../src/export/index.ts","../src/core/blob.ts","../src/drivers/memory.ts","../src/drivers/localfs/paths.ts","../src/drivers/localfs/fs-util.ts","../src/drivers/localfs/cold.ts","../src/drivers/localfs/warm.ts","../src/drivers/localfs/registry.ts","../src/drivers/crypto.ts","../src/core/erasure.ts","../src/core/consistency.ts","../src/drivers/retry/retrying-drivers.ts"],"names":["gen","total","DEFAULT_MAX_BITMAP_BYTES","FS","open","createHash","HEADER_BYTES","readdir","mkdir","dirname","randomUUID","unlink","DEFAULT_MAX_ROW_BYTES","rename","warmRowsDeleted"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * BitRouteSplitter — maps a 32-bit id to its chunk (top 16 bits) and remainder\n * (bottom 16 bits), per the data model.\n */\nimport { ValidationError } from './errors';\n\nexport const U32_MAX = 0xffff_ffff;\nexport const CHUNK_COUNT = 0x1_0000; // 65,536 possible chunk keys\nconst LOW_16 = 0xffff;\n\nexport interface BitRoute {\n /** Top 16 bits — the chunk key (0..65535). */\n readonly chunkKey: number;\n /** Bottom 16 bits — the value within the chunk (0..65535). */\n readonly remainder: number;\n}\n\n/** Split a u32 id into `{ chunkKey, remainder }`. Throws `ValidationError` for non-u32 input. */\nexport function splitId(id: number): BitRoute {\n if (!Number.isInteger(id) || id < 0 || id > U32_MAX) {\n throw new ValidationError(`id must be an integer in 0..${U32_MAX}; got ${id}`);\n }\n return { chunkKey: id >>> 16, remainder: id & LOW_16 };\n}\n\n/**\n * Recombine a chunk key + remainder back into the u32 id. Precondition: `chunkKey` is a validated\n * 16-bit value (tier-derived keys are validated upstream in the engine before reaching here, per\n * invariant 5); `remainder` is masked to 16 bits.\n */\nexport function joinId(chunkKey: number, remainder: number): number {\n return (((chunkKey & LOW_16) << 16) >>> 0) + (remainder & LOW_16);\n}\n","/**\n * Tombstone-aware chunk model + the effective-set merge.\n *\n * A chunk's Warm state is a delta over Cold: `{ adds, removes }`, kept **disjoint**.\n * The effective set is `(cold ∪ adds) \\ removes`. This module owns that logic plus the\n * (de)serialization of a delta to the opaque bytes a Warm driver stores.\n */\nimport type { CodecBitmap, CodecInterface } from './codec';\nimport { IntegrityError, UnsupportedError } from './errors';\n\nexport interface ChunkDelta {\n readonly adds: CodecBitmap;\n readonly removes: CodecBitmap;\n}\n\nexport function emptyDelta(codec: CodecInterface): ChunkDelta {\n return { adds: codec.empty(), removes: codec.empty() };\n}\n\n/** `add(x)`: x enters `adds`, leaves `removes` — preserving the disjoint invariant (I1). */\nexport function applyAdd(delta: ChunkDelta, remainder: number): void {\n delta.adds.add(remainder);\n delta.removes.remove(remainder);\n}\n\n/** `remove(x)`: x enters `removes`, leaves `adds` — preserving the disjoint invariant (I1). */\nexport function applyRemove(delta: ChunkDelta, remainder: number): void {\n delta.removes.add(remainder);\n delta.adds.remove(remainder);\n}\n\n/** The effective set of a chunk: `(cold ∪ adds) \\ removes`. Does not mutate its inputs. */\nexport function effective(cold: CodecBitmap, delta: ChunkDelta): CodecBitmap {\n const out = cold.clone();\n out.orInPlace(delta.adds);\n out.andNotInPlace(delta.removes);\n return out;\n}\n\n/**\n * Current Warm-row delta schema version — a pre-1.0 format-freeze prerequisite (Phase G, DECISIONS #41). The delta is\n * an internal cross-tier transport, not a user-facing format, but a **1-byte version prefix** lets a reader\n * fail-closed on bytes written by a future, incompatible writer instead of misparsing them — the pre-1.0\n * format-freeze guarantee. Bump only on a backward-incompatible layout change; a reader rejects any version\n * it doesn't recognize (`UnsupportedError`). The versioned on-disk Cold format is `.crbm` (Phase 2).\n */\nexport const WARM_DELTA_VERSION = 1;\nconst VERSION_BYTES = 1;\nconst HEADER_BYTES = 4; // u32 LE addsLen, after the version byte\n\n/** Encode a delta to bytes: `[u8 version][u32 LE addsLen][adds portable][removes portable]`. */\nexport function encodeDelta(delta: ChunkDelta): Uint8Array {\n const adds = delta.adds.serialize();\n const removes = delta.removes.serialize();\n const out = new Uint8Array(VERSION_BYTES + HEADER_BYTES + adds.length + removes.length);\n out[0] = WARM_DELTA_VERSION;\n new DataView(out.buffer).setUint32(VERSION_BYTES, adds.length, true);\n out.set(adds, VERSION_BYTES + HEADER_BYTES);\n out.set(removes, VERSION_BYTES + HEADER_BYTES + adds.length);\n return out;\n}\n\n/**\n * Decode a delta from bytes, size-capping each bitmap (S1). Rejects an unrecognized schema version with\n * `UnsupportedError` (fail-closed) and malformed bytes with `IntegrityError`.\n */\nexport function decodeDelta(\n bytes: Uint8Array,\n maxBitmapBytes: number,\n codec: CodecInterface,\n): ChunkDelta {\n if (bytes.length < VERSION_BYTES + HEADER_BYTES) {\n throw new IntegrityError(`delta too short: ${bytes.length}B`);\n }\n const version = bytes[0];\n if (version !== WARM_DELTA_VERSION) {\n throw new UnsupportedError(\n `Warm delta schema version ${version} is unsupported (this build reads v${WARM_DELTA_VERSION})`,\n );\n }\n // Cap the whole row, not just each half — a hostile Warm tier shouldn't be able to amplify a chunk\n // to ~2× the per-bitmap cap before the per-bitmap checks fire.\n const totalCap = 2 * maxBitmapBytes + VERSION_BYTES + HEADER_BYTES;\n if (bytes.length > totalCap) {\n throw new IntegrityError(`delta is ${bytes.length}B, exceeds cap ${totalCap}B`);\n }\n const addsStart = VERSION_BYTES + HEADER_BYTES;\n const addsLen = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(\n VERSION_BYTES,\n true,\n );\n const addsEnd = addsStart + addsLen;\n if (addsLen > bytes.length - addsStart) {\n throw new IntegrityError(\n `delta addsLen ${addsLen} exceeds payload ${bytes.length - addsStart}`,\n );\n }\n const adds = codec.safeDeserialize(bytes.subarray(addsStart, addsEnd), maxBitmapBytes);\n const removes = codec.safeDeserialize(bytes.subarray(addsEnd), maxBitmapBytes);\n return { adds, removes };\n}\n","/**\n * Per-op denial-of-wallet budget (Decision #3 / invariant T3). A read/admin op is refused\n * **before it fans out** if its projected fan-out would exceed `maxRequests` — so one runaway\n * `count`/`iterate`/`intersect`/`subjectReport`/`eraseSubject` can't drive unbounded RCU/GET cost on a shared\n * backend. The check is O(1) (a single comparison against the already-known fan-out size), so the hot path is\n * untouched. Each request's payload is separately size-capped (the safe-deserialize ceiling), so bounding the\n * fan-out count transitively bounds bytes — the budget is intentionally count-based, not a second byte\n * accumulator that would add per-chunk work.\n *\n * **What the count is.** For the read ops it is the number of Cold **chunk fetches** (`count`/`iterate`: one per\n * effective chunk; `intersect`: surviving keys × operands). For the admin scans it is the number of **segments\n * fanned out to** (`subjectReport`: one tier-merged `has()` each; `eraseSubject`: one force-compaction each) —\n * i.e. it bounds the *breadth* of the fan-out, not the request total of each segment's own compaction. That's\n * the right lever for a runaway (a million-segment sweep); it is not a byte/request meter.\n */\n\nimport { BudgetExceededError, ValidationError } from './errors';\n\nexport interface Budget {\n /** Max units of fan-out (Cold chunk fetches, or segments scanned) one op may issue before it is refused. */\n readonly maxRequests: number;\n}\n\n/**\n * Default: **on but generous** — even a full single-segment scan (≤ 65 536 chunks) or a large single-namespace\n * admin scan stays well under it; it exists to catch a true runaway (a million-segment scan, a pathological\n * intersection). Tune it down for tighter multi-tenant control, or set `budget: false` to disable.\n */\nexport const DEFAULT_BUDGET: Budget = { maxRequests: 1_000_000 };\n\n/** A store/per-op budget option: partial overrides, or `false` to disable entirely. */\nexport type BudgetOption = Partial<Budget> | false;\n\n/** Resolve a budget option against a fallback to a concrete `Budget`, or `null` when disabled. Validates. */\nexport function resolveBudget(opt: BudgetOption | undefined, fallback: Budget): Budget | null {\n if (opt === false) return null; // explicitly disabled\n const maxRequests = opt?.maxRequests ?? fallback.maxRequests;\n if (!Number.isInteger(maxRequests) || maxRequests < 1) {\n throw new ValidationError(`budget.maxRequests must be a positive integer; got ${maxRequests}`);\n }\n return { maxRequests };\n}\n\n/**\n * Resolve a **per-op** budget override against the store's own resolved budget (never the raw global default):\n * `undefined` inherits the store budget as-is (including a disabled `null`); a partial `{}` / omitted\n * `maxRequests` inherits the store's *tightening* (so a per-op passthrough of an absent config value can't\n * silently lift a tight tenant ceiling back to the generous default); `{ maxRequests }` replaces it; `false`\n * disables. Falls back to {@link DEFAULT_BUDGET} only when the store itself has no budget (disabled).\n */\nexport function resolvePerOpBudget(\n opt: BudgetOption | undefined,\n storeBudget: Budget | null,\n): Budget | null {\n if (opt === undefined) return storeBudget;\n return resolveBudget(opt, storeBudget ?? DEFAULT_BUDGET);\n}\n\n/**\n * Refuse an op whose projected fan-out exceeds the budget. **Call before fan-out**, with the exact fan-out size\n * the op is about to issue (Cold chunk fetches, or segments to scan). O(1). No-op when `budget` is `null`\n * (disabled).\n */\nexport function checkBudget(budget: Budget | null, projectedRequests: number, op: string): void {\n if (budget !== null && projectedRequests > budget.maxRequests) {\n throw new BudgetExceededError(\n `${op} would fan out to ${projectedRequests} units, over the per-op budget of ` +\n `${budget.maxRequests} — raise \\`budget.maxRequests\\`, override it per-op, or set \\`budget: false\\``,\n );\n }\n}\n","/**\n * Canonical key encoding for a segment / chunk — one source of truth, used by both the storage\n * drivers and the HOT cache (DRY). The encoding is collision-proof and injection-proof:\n *\n * - The field delimiter (a space) and the \"no namespace\" sentinel (`/`) are characters the name\n * grammar forbids in a namespace/segment — so they can never appear inside\n * a name, can't be injected across the delimiter, and the absent-namespace case (`undefined`) is\n * encoded distinctly from any real namespace (an empty string is rejected by the grammar anyway).\n */\nimport type { ChunkRef, SegmentRef } from './ports';\n\nconst FIELD = ' ';\nconst NO_NAMESPACE = '/';\n\nexport function segmentKey(ref: SegmentRef): string {\n return `${ref.namespace ?? NO_NAMESPACE}${FIELD}${ref.segment}`;\n}\n\nexport function segmentPrefix(ref: SegmentRef): string {\n return `${segmentKey(ref)}${FIELD}`;\n}\n\nexport function chunkRefKey(ref: ChunkRef): string {\n return `${segmentPrefix(ref)}${ref.chunkKey}`;\n}\n\n/**\n * HOT-cache key for a chunk scoped to a specific Cold **generation** — {@link chunkRefKey} plus the generation\n * (space-delimited, injection-proof exactly as above). Keying the decoded-chunk cache by generation means a\n * compaction bump naturally misses the cache instead of serving a stale pre-compaction chunk (gap #4); the\n * superseded-generation entries age out under the LRU ceiling (no active purge needed).\n */\nexport function chunkGenKey(ref: ChunkRef, generation: number): string {\n return `${chunkRefKey(ref)}${FIELD}${generation}`;\n}\n","/**\n * Metrics seam (Phase 5a) — an injected sink the engine pushes typed events\n * to, exactly like the `Clock`/`Rng`/driver seams keep `core/` pure and storage-agnostic.\n *\n * Design: the library emits **neutral domain events** and stays vendor-agnostic — you (or a ~12-line\n * adapter) map them to OpenTelemetry / Datadog / a log line. The default is a **no-op**, and emission is\n * skipped entirely when no sink is wired (near-zero overhead, no telemetry dependency). Events carry **raw\n * observations** (bytes, counts, ms); turning those into billable units / dollars is the cost model's job\n * (Phase 5b), which keeps rates pluggable.\n *\n * Two caveats for sink authors: `onEvent` runs **synchronously on the I/O path**, so keep it cheap and\n * non-blocking (offload batching/network to your own async queue); and `segment`/`namespace` are\n * caller-controlled strings that may be PII and are **unbounded-cardinality** — do not map them to\n * per-series metric labels unless they're known low-cardinality and PII-free. See the getting-started\n * \"Observability\" section.\n */\n\n/** The segment operations that emit an `op` latency event (timed with the injected clock, at the facade). */\nexport type MetricOpName =\n | 'add'\n | 'remove'\n | 'addMany'\n | 'removeMany'\n | 'has'\n | 'count'\n | 'intersectInto';\n\n/**\n * One observability event. A discriminated union on `kind` — new variants can be added over time without\n * breaking consumers (they switch on the kinds they care about). `namespace` is the segment's namespace\n * (absent ⇒ the default namespace). Segment names are identifiers, never bitmap contents (threat model:\n * never log PII / bitmap bits).\n */\nexport type MetricEvent =\n | {\n readonly kind: 'cold.get';\n readonly namespace?: string;\n readonly segment: string;\n /** Bytes returned (0 if the chunk was absent — a GET still happened). */\n readonly bytes: number;\n /**\n * Elapsed wall time of the read — includes any transient-retry backoff on the cold call. From the\n * injected clock, clamped to ≥ 0 (0 under the no-wait test clock).\n */\n readonly ms: number;\n }\n | { readonly kind: 'cache'; readonly hit: boolean }\n | {\n readonly kind: 'warm.read';\n readonly namespace?: string;\n readonly segment: string;\n /** Bytes read — a single-row get, or the summed rows of a list scan. */\n readonly bytes: number;\n }\n | {\n readonly kind: 'warm.write';\n readonly namespace?: string;\n readonly segment: string;\n /** Bytes of the committed delta row (emitted only on a successful conditional write). */\n readonly bytes: number;\n }\n | {\n readonly kind: 'retry';\n /** `occ` = optimistic-concurrency conflict backoff; `transient` = infrastructure-fault backoff. */\n readonly reason: 'occ' | 'transient';\n /** 1-based number of the attempt about to be retried. */\n readonly attempt: number;\n readonly delayMs: number;\n }\n | {\n readonly kind: 'intersect';\n readonly operands: number;\n /** Shared **distinct** chunk-keys selected to fetch (present in every operand). */\n readonly fetchedChunks: number;\n /**\n * **Distinct** chunk-keys pruned — never fetched (the chunk-skipping saving). Counts distinct keys,\n * not per-operand GETs, so it under-states the true GET saving when 3+ operands partially overlap.\n */\n readonly skippedChunks: number;\n }\n | {\n readonly kind: 'compaction';\n readonly namespace?: string;\n readonly segment: string;\n /** True iff this call committed a new generation. */\n readonly compacted: boolean;\n /** Why nothing was committed (when `compacted` is false) — the `CompactionResult.reason` (Phase D). */\n readonly reason?: string;\n /** Dirty Warm chunks pinned at scan time. */\n readonly dirtyChunks: number;\n /** Archived Warm rows actually purged (≤ dirtyChunks). */\n readonly purged: number;\n /** Elapsed wall time of the attempt (injected clock, ≥ 0; 0 under the no-wait test clock). */\n readonly ms: number;\n }\n | { readonly kind: 'op'; readonly name: MetricOpName; readonly ms: number };\n\n/**\n * The sink you plug in. One method, synchronous, fire-and-forget. It must never throw back into the\n * caller — `CloudRoaring` wraps a user sink with {@link safeMetrics} so a buggy sink can't break I/O.\n */\nexport interface IMetricsSink {\n onEvent(event: MetricEvent): void;\n}\n\n/** The default sink: discards everything, zero overhead. Used whenever no sink is wired. */\nexport const NOOP_METRICS: IMetricsSink = {\n onEvent(): void {\n /* discard */\n },\n};\n\n/**\n * Wrap a sink so a throwing/buggy `onEvent` can never break the data path — observability is strictly\n * best-effort. `CloudRoaring` applies this to the user-supplied sink at construction.\n */\nexport function safeMetrics(sink: IMetricsSink): IMetricsSink {\n if (sink === NOOP_METRICS) return sink;\n return {\n onEvent(event: MetricEvent): void {\n try {\n sink.onEvent(event);\n } catch {\n /* swallow — a metrics sink must never break a read/write */\n }\n },\n };\n}\n\n/** Accumulated totals — the shape returned by {@link CountingMetricsSink.snapshot}. */\nexport interface MetricsSnapshot {\n readonly cold: { readonly gets: number; readonly bytes: number; readonly totalMs: number };\n readonly warm: {\n readonly reads: number;\n readonly readBytes: number;\n readonly writes: number;\n readonly writeBytes: number;\n };\n readonly cache: { readonly hits: number; readonly misses: number };\n readonly retries: { readonly occ: number; readonly transient: number };\n readonly intersect: {\n readonly calls: number;\n readonly fetchedChunks: number;\n readonly skippedChunks: number;\n };\n readonly compaction: {\n readonly attempts: number;\n readonly committed: number;\n readonly dirtyChunks: number;\n readonly purged: number;\n readonly totalMs: number;\n };\n readonly ops: Readonly<\n Record<MetricOpName, { readonly count: number; readonly totalMs: number }>\n >;\n}\n\nconst OP_NAMES: readonly MetricOpName[] = [\n 'add',\n 'remove',\n 'addMany',\n 'removeMany',\n 'has',\n 'count',\n 'intersectInto',\n];\n\n/**\n * A ready-made sink that tallies events into a {@link MetricsSnapshot} — handy for tests, quick scripts,\n * and (Phase 5b) as the grounded-request-cost source behind `costReport()`. `snapshot()` returns an\n * independent copy; `reset()` zeroes the counters.\n */\nexport class CountingMetricsSink implements IMetricsSink {\n private cold = { gets: 0, bytes: 0, totalMs: 0 };\n private warm = { reads: 0, readBytes: 0, writes: 0, writeBytes: 0 };\n private cache = { hits: 0, misses: 0 };\n private retries = { occ: 0, transient: 0 };\n private intersect = { calls: 0, fetchedChunks: 0, skippedChunks: 0 };\n private compaction = { attempts: 0, committed: 0, dirtyChunks: 0, purged: 0, totalMs: 0 };\n private ops: Record<MetricOpName, { count: number; totalMs: number }> =\n CountingMetricsSink.zeroOps();\n\n private static zeroOps(): Record<MetricOpName, { count: number; totalMs: number }> {\n // null-proto so a type-violating event.name (e.g. '__proto__') can never reach Object.prototype\n const ops = Object.create(null) as Record<MetricOpName, { count: number; totalMs: number }>;\n for (const name of OP_NAMES) ops[name] = { count: 0, totalMs: 0 };\n return ops;\n }\n\n onEvent(event: MetricEvent): void {\n switch (event.kind) {\n case 'cold.get':\n this.cold.gets += 1;\n this.cold.bytes += event.bytes;\n this.cold.totalMs += event.ms;\n break;\n case 'cache':\n if (event.hit) this.cache.hits += 1;\n else this.cache.misses += 1;\n break;\n case 'warm.read':\n this.warm.reads += 1;\n this.warm.readBytes += event.bytes;\n break;\n case 'warm.write':\n this.warm.writes += 1;\n this.warm.writeBytes += event.bytes;\n break;\n case 'retry':\n if (event.reason === 'occ') this.retries.occ += 1;\n else this.retries.transient += 1;\n break;\n case 'intersect':\n this.intersect.calls += 1;\n this.intersect.fetchedChunks += event.fetchedChunks;\n this.intersect.skippedChunks += event.skippedChunks;\n break;\n case 'compaction':\n this.compaction.attempts += 1;\n if (event.compacted) this.compaction.committed += 1;\n this.compaction.dirtyChunks += event.dirtyChunks;\n this.compaction.purged += event.purged;\n this.compaction.totalMs += event.ms;\n break;\n case 'op': {\n const op = this.ops[event.name];\n op.count += 1;\n op.totalMs += event.ms;\n break;\n }\n default: {\n const exhaustive: never = event;\n return exhaustive;\n }\n }\n }\n\n snapshot(): MetricsSnapshot {\n const ops = Object.create(null) as Record<MetricOpName, { count: number; totalMs: number }>;\n for (const name of OP_NAMES) ops[name] = { ...this.ops[name] };\n return {\n cold: { ...this.cold },\n warm: { ...this.warm },\n cache: { ...this.cache },\n retries: { ...this.retries },\n intersect: { ...this.intersect },\n compaction: { ...this.compaction },\n ops,\n };\n }\n\n reset(): void {\n this.cold = { gets: 0, bytes: 0, totalMs: 0 };\n this.warm = { reads: 0, readBytes: 0, writes: 0, writeBytes: 0 };\n this.cache = { hits: 0, misses: 0 };\n this.retries = { occ: 0, transient: 0 };\n this.intersect = { calls: 0, fetchedChunks: 0, skippedChunks: 0 };\n this.compaction = { attempts: 0, committed: 0, dirtyChunks: 0, purged: 0, totalMs: 0 };\n this.ops = CountingMetricsSink.zeroOps();\n }\n}\n","/**\n * `withRetry` — the one retry/backoff primitive.\n *\n * A pure, storage-agnostic helper: it knows nothing about HTTP, AWS, or any SDK. It retries an operation\n * while the operation keeps failing with a **retryable** error (by default {@link TransientError}), waiting\n * a bounded, jittered, exponentially-growing delay between attempts. Time and randomness are **injected**\n * (the determinism seam) — production wires a `setTimeout`-backed clock + a real RNG; the\n * simulator wires virtual ones — so a backoff schedule is replayable from a seed and unit tests run with no\n * real sleeping.\n *\n * It deliberately does **not** retry deterministic failures ({@link WriteConflictError},\n * {@link ValidationError}, {@link IntegrityError}, {@link NotFoundError}, …): retrying those either can't\n * help or would be incorrect. OCC conflicts are retried by a *separate* loop (the engine's read-modify-write)\n * because each retry must re-read and re-apply, not blindly replay the same call.\n */\nimport type { Clock, Rng } from './determinism';\nimport { isTransientError } from './errors';\n\nexport interface RetryPolicy {\n /** Total attempts including the first (so `maxAttempts: 4` = 1 try + 3 retries). Must be ≥ 1. */\n readonly maxAttempts: number;\n /** Delay before the first retry, in ms. Grows by `backoffFactor` each subsequent retry. */\n readonly baseDelayMs: number;\n /** Upper bound on a single (pre-jitter) delay, in ms — caps the exponential growth. */\n readonly maxDelayMs: number;\n /** Exponential growth factor between retries (e.g. 2 ⇒ base, 2·base, 4·base, …). */\n readonly backoffFactor: number;\n /**\n * `'full'` ⇒ the actual wait is uniform in `[0, computed]` (AWS-recommended full jitter: decorrelates\n * concurrent retriers so they don't reconverge into a thundering herd). `'none'` ⇒ wait exactly `computed`.\n */\n readonly jitter: 'full' | 'none';\n}\n\n/**\n * Conservative defaults: 4 attempts, 50ms → 100 → 200 (×2), capped at 2s, full jitter. Tuned for a cloud\n * backend's brief throttle/5xx blip — enough to ride out a transient fault without turning a hard outage\n * into a long hang. Override per store/driver if your latency budget differs.\n */\nexport const DEFAULT_RETRY_POLICY: RetryPolicy = {\n maxAttempts: 4,\n baseDelayMs: 50,\n maxDelayMs: 2_000,\n backoffFactor: 2,\n jitter: 'full',\n};\n\n/** Backoff for the engine's OCC conflict loop — local contention resolves fast, so smaller + tighter. */\nexport const DEFAULT_OCC_BACKOFF: RetryPolicy = {\n maxAttempts: 1, // attempts are owned by the engine's loop; this policy only supplies the delay schedule\n baseDelayMs: 5,\n maxDelayMs: 200,\n backoffFactor: 2,\n jitter: 'full',\n};\n\nexport interface RetryDeps {\n readonly clock: Clock;\n readonly rng: Rng;\n /** Override which errors are retryable. Default: any {@link TransientError} (incl. `TimeoutError`). */\n readonly isRetryable?: (err: unknown) => boolean;\n /** Optional hook (observability) fired before each backoff wait. `attempt` is 1-based (the one that failed). */\n readonly onRetry?: (info: { attempt: number; delayMs: number; err: unknown }) => void;\n}\n\n/** Default classifier: retry transient infrastructure faults only. */\nexport function isTransient(err: unknown): boolean {\n return isTransientError(err);\n}\n\n/**\n * Backoff delay (ms) for the retry that follows a given 1-based attempt, before jitter is applied. Exposed\n * for tests and the engine's OCC loop. `attempt` 1 ⇒ `baseDelayMs`, 2 ⇒ `base·factor`, … capped at `maxDelayMs`.\n */\nexport function backoffDelayMs(policy: RetryPolicy, attempt: number): number {\n const raw = policy.baseDelayMs * policy.backoffFactor ** (attempt - 1);\n return Math.min(policy.maxDelayMs, raw);\n}\n\n/** Apply the policy's jitter to a computed delay using the injected RNG. */\nexport function applyJitter(policy: RetryPolicy, delayMs: number, rng: Rng): number {\n if (policy.jitter === 'none') return delayMs;\n return rng.next() * delayMs; // full jitter: uniform in [0, delayMs)\n}\n\n/**\n * Run `op`, retrying transient failures per `policy`. Resolves with `op`'s result, or rejects with the last\n * error once attempts are exhausted (or immediately for a non-retryable error). The thrown error is always\n * the *operation's* error — never a wrapper — so callers keep their typed-error branching.\n */\nexport async function withRetry<T>(\n op: () => Promise<T>,\n policy: RetryPolicy,\n deps: RetryDeps,\n): Promise<T> {\n const retryable = deps.isRetryable ?? isTransient;\n const attempts = Math.max(1, policy.maxAttempts);\n let lastErr: unknown;\n for (let attempt = 1; attempt <= attempts; attempt++) {\n try {\n return await op();\n } catch (err) {\n lastErr = err;\n if (attempt >= attempts || !retryable(err)) throw err;\n const delayMs = applyJitter(policy, backoffDelayMs(policy, attempt), deps.rng);\n deps.onRetry?.({ attempt, delayMs, err });\n await deps.clock.sleep(delayMs);\n }\n }\n // Unreachable: the loop either returns or throws. Satisfies the type checker.\n throw lastErr;\n}\n","/**\n * SegmentEngine — the in-memory core: routing + tombstone merge + the HOT cache, exposing the seven\n * ops over the driver interfaces. Storage-agnostic and time/random-free\n * (the determinism seam): all I/O is via injected drivers; the cache carries its own `Clock`.\n */\nimport { splitId, joinId, CHUNK_COUNT } from './bit-route';\nimport type { CodecBitmap, CodecInterface } from './codec';\nimport { emptyDelta, applyAdd, applyRemove, effective, encodeDelta, decodeDelta } from './chunk';\nimport type { ChunkDelta } from './chunk';\nimport { checkBudget, DEFAULT_BUDGET, resolvePerOpBudget } from './budget';\nimport type { Budget, BudgetOption } from './budget';\nimport { mapWithConcurrency } from './concurrency';\nimport type { Clock, Rng } from './determinism';\nimport {\n IntegrityError,\n ValidationError,\n WriteConflictError,\n isWriteConflictError,\n} from './errors';\nimport { chunkGenKey, chunkRefKey } from './keys';\nimport type { BoundedLru } from './lru';\nimport { NOOP_METRICS, safeMetrics } from './metrics';\nimport type { IMetricsSink } from './metrics';\nimport { NO_ROW } from './ports';\nimport type {\n ChunkRef,\n ColdChunkSource,\n IWarmDriver,\n SegmentRef,\n SegmentSize,\n WarmReadOptions,\n WarmRow,\n} from './ports';\nimport { DEFAULT_OCC_BACKOFF, applyJitter, backoffDelayMs } from './retry';\nimport type { RetryPolicy } from './retry';\n\nconst DEFAULT_MAX_BITMAP_BYTES = 1 << 20; // 1 MiB per bitmap — generous; real chunks are far smaller\nconst DEFAULT_MAX_RETRIES = 16;\n/** Max overlapping-chunk intersections in flight — bounds memory + concurrent reads (invariant 6). */\nconst DEFAULT_INTERSECT_CONCURRENCY = 8;\n\n/**\n * Pure no-wait clock / zero RNG used when the engine is constructed without a time source (e.g. unit tests\n * that don't exercise backoff). `sleep` resolves on a microtask (no timer — `core/` is timer-free) and the\n * RNG returns 0, so OCC backoff collapses to \"retry immediately\" — the pre-4b behaviour. Production wiring\n * (`CloudRoaring`) injects a real `setTimeout`-backed clock + RNG, enabling genuine jittered backoff.\n */\nclass InstantClock implements Clock {\n now(): number {\n return 0;\n }\n sleep(): Promise<void> {\n return Promise.resolve();\n }\n}\nclass ZeroRng implements Rng {\n next(): number {\n return 0;\n }\n}\n\nexport interface EngineDeps {\n readonly warm: IWarmDriver;\n readonly cold: ColdChunkSource;\n /** Optional HOT cache of decoded (immutable) Cold chunks. */\n readonly cache?: BoundedLru<string, CodecBitmap>;\n readonly maxBitmapBytes?: number;\n /**\n * The bitmap codec (DECISIONS #58) — **required**. `core/` is\n * codec-agnostic: it can have no default, because the concrete codec lives in a *flavor* package that depends\n * on core (a default here would invert that arrow). A flavor's facade injects it — `@cloudbitmaps/roaring`\n * passes `roaringCodec` — so applications never see this.\n */\n readonly codec: CodecInterface;\n readonly maxRetries?: number;\n /** Injected for jittered OCC backoff + replayable tests; defaults to an instant clock / zero RNG. */\n readonly clock?: Clock;\n readonly rng?: Rng;\n /** Backoff schedule between OCC conflict retries; defaults to {@link DEFAULT_OCC_BACKOFF}. */\n readonly occBackoff?: RetryPolicy;\n /** Observability sink (Phase 5a); defaults to a no-op. Assumed exception-safe (the facade wraps it). */\n readonly metrics?: IMetricsSink;\n /**\n * Warm read consistency for the READ paths (`has`/`count`/`iterate`/`intersect`); default `'strong'`\n * (read-your-writes). `'eventual'` trades read-after-write for ~½ the DynamoDB RCU (gap #9). The OCC\n * read-modify-write path is always strong regardless (correctness).\n */\n readonly warmReadConsistency?: 'strong' | 'eventual';\n /**\n * Max Warm chunk writes in flight per `addMany`/`removeMany` (the bounded flusher). Default **1** (serial —\n * unchanged behavior). Higher values fan out distinct-chunk writes for throughput; each chunk is its own OCC\n * row, so bounded concurrency is safe (`addMany` is already non-atomic on partial failure).\n */\n readonly writeConcurrency?: number;\n /**\n * Per-op denial-of-wallet budget (07 Decision #3 / T3), already resolved by the facade: a {@link Budget} to\n * enforce, or `null` to disable. Undefined ⇒ {@link DEFAULT_BUDGET} (a direct engine construction still gets\n * the generous default). Read ops refuse before fan-out if they'd exceed it.\n */\n readonly budget?: Budget | null;\n}\n\ntype Mutator = (delta: ChunkDelta, remainder: number) => void;\n\nexport class SegmentEngine {\n private readonly warm: IWarmDriver;\n private readonly cold: ColdChunkSource;\n private readonly cache: BoundedLru<string, CodecBitmap> | undefined;\n private readonly codec: CodecInterface;\n private readonly maxBitmapBytes: number;\n private readonly maxRetries: number;\n private readonly clock: Clock;\n private readonly rng: Rng;\n private readonly occBackoff: RetryPolicy;\n private readonly metrics: IMetricsSink;\n private readonly metricsOn: boolean;\n /** Consistency for READ-path Warm fetches (precomputed; OCC RMW passes strong explicitly, see `warmGet`). */\n private readonly readOpts: WarmReadOptions;\n private readonly writeConcurrency: number;\n /** Resolved per-op budget (null = disabled); undefined deps ⇒ the generous default. See {@link checkBudget}. */\n private readonly budget: Budget | null;\n\n constructor(deps: EngineDeps) {\n this.warm = deps.warm;\n this.cold = deps.cold;\n this.cache = deps.cache;\n this.codec = deps.codec;\n this.maxBitmapBytes = deps.maxBitmapBytes ?? DEFAULT_MAX_BITMAP_BYTES;\n this.maxRetries = deps.maxRetries ?? DEFAULT_MAX_RETRIES;\n this.clock = deps.clock ?? new InstantClock();\n this.rng = deps.rng ?? new ZeroRng();\n this.occBackoff = deps.occBackoff ?? DEFAULT_OCC_BACKOFF;\n this.readOpts = { consistent: (deps.warmReadConsistency ?? 'strong') !== 'eventual' };\n this.writeConcurrency = deps.writeConcurrency ?? 1;\n // undefined ⇒ the generous default; null ⇒ explicitly disabled (must not be re-defaulted by `??`).\n this.budget = deps.budget === undefined ? DEFAULT_BUDGET : deps.budget;\n // Wrap for defense-in-depth (idempotent for the no-op) so even a direct engine construction with a\n // throwing sink can't break the data path; `metricsOn` short-circuits all emission when unused.\n this.metrics = safeMetrics(deps.metrics ?? NOOP_METRICS);\n this.metricsOn = this.metrics !== NOOP_METRICS;\n }\n\n add(seg: SegmentRef, id: number): Promise<void> {\n const { chunkKey, remainder } = splitId(id);\n return this.readModifyWrite(seg, chunkKey, (d) => applyAdd(d, remainder));\n }\n\n remove(seg: SegmentRef, id: number): Promise<void> {\n const { chunkKey, remainder } = splitId(id);\n return this.readModifyWrite(seg, chunkKey, (d) => applyRemove(d, remainder));\n }\n\n addMany(seg: SegmentRef, ids: Iterable<number>): Promise<void> {\n return this.mutateMany(seg, ids, applyAdd);\n }\n\n removeMany(seg: SegmentRef, ids: Iterable<number>): Promise<void> {\n return this.mutateMany(seg, ids, applyRemove);\n }\n\n async has(seg: SegmentRef, id: number, opts?: WarmReadOptions): Promise<boolean> {\n const { chunkKey, remainder } = splitId(id);\n const ref: ChunkRef = { ...seg, chunkKey };\n // Default: honor the store's warmReadConsistency (gap #9). Callers that need read-your-writes regardless\n // (the GDPR subjectReport/eraseSubject membership check) pass `{ consistent: true }` to force strong.\n const row = await this.warmGet(ref, opts ?? this.readOpts);\n if (row) {\n const delta = decodeDelta(row.bytes, this.maxBitmapBytes, this.codec);\n if (delta.removes.has(remainder)) return false;\n if (delta.adds.has(remainder)) return true;\n }\n const cold = await this.coldChunk(ref, await this.currentGen(seg));\n return cold ? cold.has(remainder) : false;\n }\n\n async count(seg: SegmentRef): Promise<number> {\n const warmRows = await this.collectWarm(seg);\n // Cheap count (Phase 5c): when the Cold source can serve per-chunk cardinality from its `.crbm` index,\n // a warm-delta-free chunk is counted straight from the index — no payload fetch/decode — and only the\n // dirty chunks (those with a Warm delta) are merged. A source without that capability, or a segment with\n // no Cold generation, falls back to fetching + merging every effective chunk.\n //\n // Generation resolution ordering (gap #4): resolve `gen` **after** the shape read (`cardinalities` /\n // `chunkKeys`), matching `intersect`. A non-null shape read means the source resolved and cached a non-null\n // snapshot, so `gen` can't then come back null while cold data is present. Resolving `gen` *first* races a\n // segment's very first publish — `gen` reads null (no registry record yet), the shape read then sees the\n // freshly-published generation, and the stale null `gen` would make `coldChunk` skip cold for dirty chunks\n // (a silent undercount). `gen` and the shape read share the one snapshot, so within a call shorter than\n // `coldGenTtlMs` the count is generation-consistent — **absent cache-pressure eviction**: if the reader\n // cache (`maxOpenSegments`, gap #1) evicts this segment mid-call, the re-read re-resolves fresh (bypassing\n // the TTL), which can hop generations even sub-TTL. Likewise a *long* count that straddles a mid-call TTL\n // boundary during a compaction can mix generations — either way a bounded, transient skew that converges\n // next call (never a torn read: each chunk is still a whole, immutable generation). Full intra-op snapshot\n // isolation is deferred (gap #4).\n const cardinalities = this.cold.cardinalities ? await this.cold.cardinalities(seg) : null;\n if (!cardinalities) {\n const chunkKeys = await this.chunkKeys(seg, warmRows);\n checkBudget(this.budget, chunkKeys.length, 'count'); // one cold fetch per effective chunk (before fan-out)\n const gen = await this.currentGen(seg);\n let total = 0;\n for (const chunkKey of chunkKeys) {\n total += (await this.effectiveChunk(seg, chunkKey, warmRows, gen)).size;\n }\n return total;\n }\n // Cheap path: only the dirty (Warm) chunks are fetched; clean chunks are counted from the index (0 reads).\n checkBudget(this.budget, warmRows.size, 'count');\n const gen = await this.currentGen(seg);\n const keys = new Set<number>(warmRows.keys());\n for (const k of cardinalities.keys()) keys.add(k);\n let total = 0;\n for (const k of keys) {\n this.assertChunkKeyInRange(k);\n total += warmRows.has(k)\n ? (await this.effectiveChunk(seg, k, warmRows, gen)).size // dirty: merge (Cold ∪ adds) \\ removes\n : (cardinalities.get(k) ?? 0); // clean: index cardinality, zero payload reads\n }\n return total;\n }\n\n /** Whether the Cold source can measure segment size (for grounded cost); false ⇒ storage isn't grounded. */\n get supportsColdSize(): boolean {\n return typeof this.cold.sizeOf === 'function';\n }\n\n /** Grounded Cold size of a segment's current generation (cost reporting), or null if it has no generation. */\n segmentSize(seg: SegmentRef): Promise<SegmentSize | null> {\n return this.cold.sizeOf ? this.cold.sizeOf(seg) : Promise.resolve(null);\n }\n\n async *iterate(seg: SegmentRef): AsyncGenerator<number> {\n const warmRows = await this.collectWarm(seg);\n const chunkKeys = await this.chunkKeys(seg, warmRows);\n checkBudget(this.budget, chunkKeys.length, 'iterate'); // one cold fetch per effective chunk (before fan-out)\n const gen = await this.currentGen(seg); // after the shape read (see `count`) — avoids a first-publish undercount\n for (const chunkKey of chunkKeys) {\n const eff = await this.effectiveChunk(seg, chunkKey, warmRows, gen);\n for (const remainder of eff) yield joinId(chunkKey, remainder);\n }\n }\n\n /**\n * Chunk-skipping intersection. Computes\n * `seg[0] ∩ seg[1] ∩ …` and streams the result ids ascending. It aligns each segment's *effective*\n * chunk-key set (Warm ∪ Cold), keeps only keys present in **all** operands (a key missing from any\n * operand can't contribute → its **Cold chunks are never fetched** — the core saving), then for each\n * surviving key merges tiers per operand (operand fetches run in parallel) and hands the buffers to the\n * roaring engine for the AND, streaming results through a bounded in-flight window.\n *\n * **Memory:** the Cold payload footprint is bounded by the window (`concurrency × operands × chunk`), not\n * by segment size — that's the Lambda-friendly property. The **Warm** side, however, is snapshotted up\n * front (`collectWarm` per operand), so total memory also carries each operand's Warm size. Under\n * Topology-A (read-mostly; compaction keeps Warm small) that's negligible; a streaming Warm/Cold\n * merge-join for large Warm is Phase 4.\n *\n * Generation-consistent within the call (normal case): each operand's current generation is resolved **once**\n * up front (before the fan-out) and threaded into every chunk read, so a concurrent compaction can't corrupt\n * or tear the result — every chunk read is a whole, checksum-verified, immutable generation (finding C10).\n * The edge a *long* call can hit: if it straddles a mid-call `coldGenTtlMs` boundary and a compaction has\n * committed, an operand's not-yet-read chunks may re-resolve forward to the newer generation (a generation\n * hop within one long call) — the call never crashes or returns a torn object, but may mix generations. That\n * window is a single TTL (default 2 s), not the multi-cycle GC-sweep window it took pre-Phase-B. A shorter call\n * is unaffected **unless the reader cache evicts an operand mid-call** (`maxOpenSegments`, gap #1): the re-read\n * re-resolves fresh (bypassing the TTL), which can hop generations even sub-TTL — still whole/immutable per\n * read, never torn. Full intra-op snapshot isolation is deferred (gap #4).\n */\n async *intersect(\n segs: readonly SegmentRef[],\n options?: { concurrency?: number; budget?: BudgetOption },\n ): AsyncGenerator<number> {\n if (segs.length === 0) {\n throw new ValidationError('intersect requires at least one segment');\n }\n const limit = options?.concurrency ?? DEFAULT_INTERSECT_CONCURRENCY;\n if (!Number.isInteger(limit) || limit < 1) {\n throw new ValidationError(\n `concurrency must be a positive integer; got ${options?.concurrency}`,\n );\n }\n // Per-op budget override (else the store budget); resolved before any I/O so a bad value fails fast. A\n // partial override inherits the store's tightening (not the generous default) — see resolvePerOpBudget.\n const budget = resolvePerOpBudget(options?.budget, this.budget);\n\n // ① Index-map extraction: each operand's effective key set (Warm ∪ Cold) + its current generation, resolved\n // ONCE here (not per chunk) so the fan-out below adds no per-chunk generation re-resolve. Only metadata so far.\n const operands = await Promise.all(\n segs.map(async (seg) => {\n const warmRows = await this.collectWarm(seg);\n const keys = await this.chunkKeys(seg, warmRows);\n const gen = await this.currentGen(seg);\n return { seg, warmRows, keys: new Set(keys), gen };\n }),\n );\n\n // ② Key alignment: keys present in ALL operands. Start from the smallest set to minimize the scan.\n const pivot = operands.reduce((a, b) => (a.keys.size <= b.keys.size ? a : b));\n const common: number[] = [];\n for (const k of pivot.keys) {\n if (operands.every((op) => op.keys.has(k))) common.push(k);\n }\n common.sort((a, b) => a - b); // defensive: `chunkKeys` already returns sorted; don't rely on it\n\n // Denial-of-wallet budget (before the fan-out AND before we emit a \"work done\" metric): the heavy cost is\n // one cold fetch per surviving key per operand — refuse up front if that would exceed the budget (07\n // Decision #3 / T3). Placed above the metric so a refused intersect doesn't report chunks it never fetched.\n checkBudget(budget, common.length * operands.length, 'intersect');\n\n // Emit the chunk-skipping efficiency: `fetched` = shared keys we'll read, `skipped` = distinct keys\n // pruned across all operands (never fetched — the core saving). Bounded metadata work, no extra I/O.\n if (this.metricsOn) {\n const distinctKeys = new Set<number>();\n for (const op of operands) {\n for (const k of op.keys) distinctKeys.add(k);\n }\n this.metrics.onEvent({\n kind: 'intersect',\n operands: segs.length,\n fetchedChunks: common.length,\n skippedChunks: distinctKeys.size - common.length,\n });\n }\n\n // ③–⑤ Surgical streaming AND through a bounded, order-preserving window: fetch+intersect at most\n // `limit` keys concurrently, yield each key's ids before priming far ahead (bounded Cold footprint).\n // Each task resolves to a value (never rejects) so an error on one key can't leave the other in-flight\n // promises unhandled — we surface it, in key order, when its slot is drained.\n type Slot = { key: number; result: CodecBitmap | null; error?: unknown };\n const startAt = (key: number): Promise<Slot> =>\n this.intersectChunk(operands, key).then(\n (result) => ({ key, result }),\n (error: unknown) => ({ key, result: null, error }),\n );\n\n const inFlight: Array<Promise<Slot>> = [];\n let next = 0;\n while (next < common.length && inFlight.length < limit) inFlight.push(startAt(common[next++]!));\n while (inFlight.length > 0) {\n const slot = await inFlight.shift()!; // FIFO over ascending keys ⇒ ascending output\n if (next < common.length) inFlight.push(startAt(common[next++]!));\n if (slot.error !== undefined) throw slot.error;\n if (slot.result && !slot.result.isEmpty) {\n for (const remainder of slot.result) yield joinId(slot.key, remainder);\n }\n }\n }\n\n /**\n * The AND of one chunk key across all operands (tier-merged per operand), or `null` if empty. Operand\n * chunks are fetched **in parallel** (the spec's parallel byte-range reads). `acc` takes ownership of the\n * first operand's effective chunk and mutates it in place — safe because `effectiveChunk` always returns\n * a FRESH bitmap (never a cached/shared Cold instance), so this can't poison the HOT cache.\n */\n private async intersectChunk(\n operands: ReadonlyArray<{\n seg: SegmentRef;\n warmRows: Map<number, Uint8Array>;\n gen: number | null | undefined;\n }>,\n chunkKey: number,\n ): Promise<CodecBitmap | null> {\n const chunks = await Promise.all(\n operands.map((op) => this.effectiveChunk(op.seg, chunkKey, op.warmRows, op.gen)),\n );\n const acc = chunks[0]!; // fresh, owned (see method note)\n for (let i = 1; i < chunks.length; i++) {\n acc.andInPlace(chunks[i]!);\n if (acc.isEmpty) return null; // once empty, the remaining operands can't revive it\n }\n return acc.isEmpty ? null : acc;\n }\n\n /**\n * Materialize `seg[0] ∩ seg[1] ∩ …` into `dest` via batched `addMany` (streaming, bounded memory).\n * **Not atomic** — like `addMany`, ids land chunk-by-chunk; a failure mid-stream leaves a partial result.\n * `dest` is added to, not replaced.\n */\n async intersectInto(\n dest: SegmentRef,\n segs: readonly SegmentRef[],\n options?: { concurrency?: number; batchSize?: number },\n ): Promise<void> {\n const batchSize = Math.max(1, options?.batchSize ?? 4096);\n let batch: number[] = [];\n for await (const id of this.intersect(segs, options)) {\n batch.push(id);\n if (batch.length >= batchSize) {\n await this.addMany(dest, batch);\n batch = [];\n }\n }\n if (batch.length > 0) await this.addMany(dest, batch);\n }\n\n private async mutateMany(seg: SegmentRef, ids: Iterable<number>, apply: Mutator): Promise<void> {\n const byChunk = new Map<number, number[]>();\n for (const id of ids) {\n const { chunkKey, remainder } = splitId(id);\n const rems = byChunk.get(chunkKey) ?? [];\n rems.push(remainder);\n byChunk.set(chunkKey, rems);\n }\n // Bounded flusher: one OCC read-modify-write per distinct chunk, at most `writeConcurrency` in flight\n // (default 1 ⇒ serial, unchanged). Distinct chunks are independent OCC rows, so fanning them out is safe;\n // as before, a mid-flush failure can leave a partial result (`addMany`/`removeMany` are not atomic).\n await mapWithConcurrency([...byChunk], this.writeConcurrency, ([chunkKey, rems]) =>\n this.readModifyWrite(seg, chunkKey, (d) => {\n for (const r of rems) apply(d, r);\n }),\n );\n }\n\n /** OCC read-modify-write on a chunk's Warm delta, retrying on conflict (bounded). */\n private async readModifyWrite(\n seg: SegmentRef,\n chunkKey: number,\n mutate: (delta: ChunkDelta) => void,\n ): Promise<void> {\n const ref: ChunkRef = { ...seg, chunkKey };\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n const row = await this.warmGet(ref);\n const delta = row\n ? decodeDelta(row.bytes, this.maxBitmapBytes, this.codec)\n : emptyDelta(this.codec);\n mutate(delta);\n const encoded = encodeDelta(delta);\n try {\n await this.warm.putConditional(ref, encoded, row ? row.token : NO_ROW);\n if (this.metricsOn) {\n this.metrics.onEvent({\n kind: 'warm.write',\n namespace: ref.namespace,\n segment: ref.segment,\n bytes: encoded.length,\n });\n }\n return;\n } catch (err) {\n if (isWriteConflictError(err) && attempt < this.maxRetries) {\n // Jittered backoff so concurrent writers to a hot chunk don't reconverge into a tight retry storm\n // (full jitter decorrelates them). Instant under the default no-wait clock; real under production wiring.\n const delayMs = applyJitter(\n this.occBackoff,\n backoffDelayMs(this.occBackoff, attempt + 1),\n this.rng,\n );\n if (this.metricsOn) {\n this.metrics.onEvent({ kind: 'retry', reason: 'occ', attempt: attempt + 1, delayMs });\n }\n await this.clock.sleep(delayMs);\n continue;\n }\n throw err;\n }\n }\n throw new WriteConflictError(`OCC retries exhausted for chunk ${chunkKey}`);\n }\n\n /** `warm.get` + a `warm.read` metric (read bytes = the row size, 0 if absent). */\n private async warmGet(ref: ChunkRef, opts?: WarmReadOptions): Promise<WarmRow | null> {\n // No `opts` ⇒ the driver default (strong) — the OCC read-modify-write path relies on that; read paths pass\n // `this.readOpts` so `warmReadConsistency: 'eventual'` can lighten them (gap #9).\n const row = await this.warm.get(ref, opts);\n if (this.metricsOn) {\n this.metrics.onEvent({\n kind: 'warm.read',\n namespace: ref.namespace,\n segment: ref.segment,\n bytes: row ? row.bytes.length : 0,\n });\n }\n return row;\n }\n\n private async collectWarm(seg: SegmentRef): Promise<Map<number, Uint8Array>> {\n const rows = new Map<number, Uint8Array>();\n let bytes = 0;\n // Read path (count/iterate/intersect): honor warmReadConsistency (gap #9).\n for await (const row of this.warm.listChunks(seg, this.readOpts)) {\n rows.set(row.chunkKey, row.bytes);\n bytes += row.bytes.length;\n }\n if (this.metricsOn) {\n this.metrics.onEvent({\n kind: 'warm.read',\n namespace: seg.namespace,\n segment: seg.segment,\n bytes,\n });\n }\n return rows;\n }\n\n private async chunkKeys(seg: SegmentRef, warmRows: Map<number, Uint8Array>): Promise<number[]> {\n const keys = new Set<number>(warmRows.keys());\n for (const k of await this.cold.listChunkKeys(seg)) keys.add(k);\n for (const k of keys) this.assertChunkKeyInRange(k);\n return [...keys].sort((a, b) => a - b);\n }\n\n /**\n * Tier-derived keys are untrusted (invariant 5) — fail fast on a corrupt/out-of-range key rather than\n * letting it flow into `joinId` and produce a bogus id.\n */\n private assertChunkKeyInRange(k: number): void {\n if (!Number.isInteger(k) || k < 0 || k >= CHUNK_COUNT) {\n throw new IntegrityError(`chunk key from a tier is out of range: ${k}`);\n }\n }\n\n private async effectiveChunk(\n seg: SegmentRef,\n chunkKey: number,\n warmRows: Map<number, Uint8Array>,\n gen: number | null | undefined,\n ): Promise<CodecBitmap> {\n const warmBytes = warmRows.get(chunkKey);\n const delta = warmBytes\n ? decodeDelta(warmBytes, this.maxBitmapBytes, this.codec)\n : emptyDelta(this.codec);\n const cold = (await this.coldChunk({ ...seg, chunkKey }, gen)) ?? this.codec.empty();\n // Always return a fresh bitmap: `effective` clones Cold before any in-place op, so callers can\n // never mutate the (shared, cached) Cold instance. This is now LOAD-BEARING: `intersectChunk` mutates\n // the returned bitmap in place via `andInPlace`. A single-tier fast path that returns the cached Cold\n // by reference would silently poison the HOT cache through that path — it stays deferred (Phase 5 perf)\n // and MUST come with a read-only bitmap view.\n return effective(cold, delta);\n }\n\n /** The segment's current generation, resolved once per op (`undefined` ⇒ source can't report it). */\n private currentGen(seg: SegmentRef): Promise<number | null | undefined> {\n return this.cold.currentGeneration\n ? this.cold.currentGeneration(seg)\n : Promise.resolve(undefined);\n }\n\n /**\n * Decode a Cold chunk. `gen` is the segment's current generation, resolved **once per op** by the caller (not\n * per chunk — that would put a registry re-resolve on every chunk of a count/intersect). The HOT cache is\n * keyed by it (gap #4), so a compaction that advances the generation misses the cache and re-reads the new\n * bytes instead of serving a stale decoded chunk (an erased id can't resurrect from a cached pre-compaction\n * chunk). `gen === null` ⇒ the source reports no current generation ⇒ no cold bytes for any chunk, so skip the\n * fetch entirely (also avoids a redundant re-resolve on the warm-only path). `gen === undefined` ⇒ the source\n * can't report a generation (pins one for its lifetime) ⇒ the key stays generation-free (unchanged behaviour).\n * Superseded-generation entries age out under the LRU ceiling — no active purge.\n */\n private async coldChunk(\n ref: ChunkRef,\n gen: number | null | undefined,\n ): Promise<CodecBitmap | null> {\n if (gen === null) return null;\n const cacheKey = gen === undefined ? chunkRefKey(ref) : chunkGenKey(ref, gen);\n if (this.cache) {\n const cached = this.cache.get(cacheKey);\n if (cached) {\n if (this.metricsOn) this.metrics.onEvent({ kind: 'cache', hit: true });\n return cached;\n }\n if (this.metricsOn) this.metrics.onEvent({ kind: 'cache', hit: false });\n }\n const startedAt = this.metricsOn ? this.clock.now() : 0;\n const bytes = await this.cold.getChunk(ref);\n if (this.metricsOn) {\n this.metrics.onEvent({\n kind: 'cold.get',\n namespace: ref.namespace,\n segment: ref.segment,\n bytes: bytes ? bytes.length : 0,\n ms: Math.max(0, this.clock.now() - startedAt),\n });\n }\n if (!bytes) return null;\n const bitmap = this.codec.safeDeserialize(bytes, this.maxBitmapBytes);\n this.cache?.set(cacheKey, bitmap);\n return bitmap;\n }\n}\n","/**\n * Bounded LRU cache with optional TTL — the HOT tier's memory ceiling (finding C6).\n *\n * Time comes from an injected `Clock` (never `Date.now()`) so the cache is deterministic\n * under simulation.\n *\n * The cache can be bounded by entry **count** (`maxEntries`, always) and, optionally, by an aggregate\n * **byte weight** (`maxBytes`). The byte bound exists for values whose footprint is large and uneven — the\n * cold reader cache, where one entry pins a fully-parsed `.crbm` index that can be ~6 MB for a wide segment\n * yet a few hundred bytes for a small one (gap #1: a count-only bound lets 1024 wide indices blow a Lambda's\n * memory even though the count is \"in bounds\"). Weights arrive **after** insertion (a cached reader is a\n * pending promise; its size is known only once it resolves), so weight is reported via {@link setWeight} and\n * eviction re-runs then.\n */\nimport type { Clock } from './determinism';\nimport { ValidationError } from './errors';\n\nexport interface LruOptions {\n /** Hard ceiling on entries; the least-recently-used is evicted past it. */\n readonly maxEntries: number;\n /**\n * Optional aggregate byte ceiling across all entries' reported weights (see {@link BoundedLru.setWeight}).\n * When set, the least-recently-used entries are evicted until the total is within budget — in addition to\n * the `maxEntries` bound. Omit for a pure count-bounded cache (weights stay 0, no byte eviction).\n */\n readonly maxBytes?: number;\n /** Optional time-to-live in ms; an entry older than this is treated as absent. */\n readonly ttlMs?: number;\n /** Only `now()` is used (never `sleep`), so a count-only cache can pass a minimal time source. */\n readonly clock: Pick<Clock, 'now'>;\n}\n\ninterface Entry<V> {\n readonly value: V;\n readonly expiresAt: number; // Infinity when no TTL\n bytes: number; // reported weight (0 until setWeight); summed against maxBytes\n}\n\nexport class BoundedLru<K, V> {\n private readonly map = new Map<K, Entry<V>>();\n private readonly maxEntries: number;\n private readonly maxBytes: number | undefined;\n private readonly ttlMs: number | undefined;\n private readonly clock: Pick<Clock, 'now'>;\n private totalBytes = 0;\n\n constructor(options: LruOptions) {\n if (!Number.isInteger(options.maxEntries) || options.maxEntries < 1) {\n throw new ValidationError(`maxEntries must be a positive integer; got ${options.maxEntries}`);\n }\n if (\n options.maxBytes !== undefined &&\n (!(options.maxBytes > 0) || !Number.isFinite(options.maxBytes))\n ) {\n throw new ValidationError(\n `maxBytes must be a positive finite number; got ${options.maxBytes}`,\n );\n }\n if (options.ttlMs !== undefined && (!(options.ttlMs > 0) || !Number.isFinite(options.ttlMs))) {\n throw new ValidationError(`ttlMs must be a positive finite number; got ${options.ttlMs}`);\n }\n this.maxEntries = options.maxEntries;\n this.maxBytes = options.maxBytes;\n this.ttlMs = options.ttlMs;\n this.clock = options.clock;\n }\n\n get(key: K): V | undefined {\n const entry = this.map.get(key);\n if (entry === undefined) return undefined;\n if (entry.expiresAt <= this.clock.now()) {\n this.drop(key, entry);\n return undefined;\n }\n // Refresh recency: re-insert so it becomes most-recently-used.\n this.map.delete(key);\n this.map.set(key, entry);\n return entry.value;\n }\n\n /** Read a value **without** counting as an access (recency unchanged, no purge on expiry). */\n peek(key: K): V | undefined {\n return this.map.get(key)?.value;\n }\n\n set(key: K, value: V): void {\n const prev = this.map.get(key);\n if (prev !== undefined) this.totalBytes -= prev.bytes;\n this.map.delete(key);\n const expiresAt = this.ttlMs === undefined ? Infinity : this.clock.now() + this.ttlMs;\n this.map.set(key, { value, expiresAt, bytes: 0 });\n while (this.map.size > this.maxEntries) {\n const oldest = this.map.keys().next();\n if (oldest.done === true) break;\n this.dropKey(oldest.value);\n }\n this.evictToBudget(key);\n }\n\n /**\n * Report an entry's byte weight (typically once a cached promise resolves and its size is known). Updates\n * the running total and evicts the least-recently-used entries if the aggregate now exceeds `maxBytes`.\n * Recency is **not** changed. The `key` being weighted is protected from this eviction pass (we just\n * populated it) — so a single entry larger than the whole budget is kept rather than immediately dropped.\n */\n setWeight(key: K, bytes: number): void {\n if (!(bytes >= 0) || !Number.isFinite(bytes)) {\n // Guard the running total against a NaN/negative weight, which no removal path could ever restore.\n throw new ValidationError(`weight must be a non-negative finite number; got ${bytes}`);\n }\n const entry = this.map.get(key);\n if (entry === undefined) return;\n this.totalBytes += bytes - entry.bytes;\n entry.bytes = bytes;\n this.evictToBudget(key);\n }\n\n private evictToBudget(protectKey: K): void {\n if (this.maxBytes === undefined) return;\n while (this.totalBytes > this.maxBytes && this.map.size > 1) {\n const oldest = this.oldestExcept(protectKey);\n if (oldest === undefined) break; // only the protected key remains\n this.dropKey(oldest);\n }\n }\n\n /** The least-recently-used key that is not `protectKey`, or undefined if none other exists. */\n private oldestExcept(protectKey: K): K | undefined {\n for (const key of this.map.keys()) {\n if (key !== protectKey) return key;\n }\n return undefined;\n }\n\n private dropKey(key: K): void {\n const entry = this.map.get(key);\n if (entry !== undefined) this.drop(key, entry);\n }\n\n private drop(key: K, entry: Entry<V>): void {\n this.totalBytes -= entry.bytes;\n this.map.delete(key);\n }\n\n /** Membership test that does NOT count as an access (recency is unchanged). Purges if expired. */\n has(key: K): boolean {\n const entry = this.map.get(key);\n if (entry === undefined) return false;\n if (entry.expiresAt <= this.clock.now()) {\n this.drop(key, entry);\n return false;\n }\n return true;\n }\n\n delete(key: K): boolean {\n const entry = this.map.get(key);\n if (entry === undefined) return false;\n this.drop(key, entry);\n return true;\n }\n\n clear(): void {\n this.map.clear();\n this.totalBytes = 0;\n }\n\n /** Current entry count (may include not-yet-evicted expired entries). */\n get size(): number {\n return this.map.size;\n }\n\n /** Current aggregate reported weight (bytes) across all entries. */\n get weightBytes(): number {\n return this.totalBytes;\n }\n}\n","/**\n * Cost model & estimator (Phase 5b) — pure, `core/`-safe (no I/O, time, or\n * SDK). Turns the verified economics into a first-class library API:\n *\n * - {@link estimateCost} — **planning** mode: pure what-if from segment sizes + a workload (sizing/sales).\n * - `segment.costReport()` (wired in `index.ts`) — **grounded** mode: the segment's real size from the\n * `.crbm` index (free + exact, no payload reads) + a supplied workload for request rates. (Whole-store\n * aggregation is a later phase — see [DECISIONS #22](../DECISIONS.md).)\n *\n * Guiding split (08 decision #3): **formulas are the spec; rates are a pluggable {@link PricingProfile}.**\n * The report always emits a {@link CostReport.verdict} that includes the lose-zone — it never hides where an\n * always-on cache (Redis) wins.\n *\n * Model scope (kept deliberately simple, and stated in `assumptions.notes`): S3→same-region egress is free\n * and internet egress is not modeled; Warm delta storage is treated as negligible (it's tiny — only dirty\n * chunks); request cost is derived from the supplied workload rates (deriving it from live metrics counters\n * is a later refinement — the cost-completeness events are deferred).\n */\nimport { CHUNK_COUNT } from './bit-route';\nimport { ValidationError } from './errors';\n\n/** Pluggable rate card. Rates differ by cloud/region/term and drift over time; the formulas don't. */\nexport interface PricingProfile {\n readonly name: string;\n readonly cold: {\n /** S3 GET (per **million** requests). A ranged GET bills as a full GET. */\n readonly getPerMillion: number;\n /** S3 PUT (per million). */\n readonly putPerMillion: number;\n readonly storagePerGiBMonth: number;\n };\n readonly warm: {\n /** DynamoDB read-request-units (per million). */\n readonly rruPerMillion: number;\n /** DynamoDB write-request-units (per million). **0 models a provisioned/flat tier** (no per-write charge). */\n readonly wruPerMillion: number;\n /** KiB billed per read unit (DynamoDB: 4). */\n readonly readUnitKiB: number;\n /** KiB billed per write unit (DynamoDB: 1 — the write cost driver). */\n readonly writeUnitKiB: number;\n readonly storagePerGiBMonth: number;\n /** Strongly-consistent reads bill 1 RRU/unit; eventually-consistent bill 0.5. */\n readonly stronglyConsistent: boolean;\n };\n /** The always-on baseline to compare against (e.g. an ElastiCache HA cluster). */\n readonly redis: { readonly monthlyUSD: number };\n}\n\n/**\n * Default profile — **AWS us-east-1, on-demand**, mid-2026, from the fact-checked\n * published pricing rather than copied from a blog post. Override it for your region, cloud, or committed term.\n */\nexport const AWS_US_EAST_1_ONDEMAND: PricingProfile = {\n name: 'aws-us-east-1-ondemand',\n cold: { getPerMillion: 0.4, putPerMillion: 5.0, storagePerGiBMonth: 0.023 },\n warm: {\n rruPerMillion: 0.125,\n wruPerMillion: 0.625,\n readUnitKiB: 4,\n writeUnitKiB: 1,\n storagePerGiBMonth: 0.25,\n stronglyConsistent: true,\n },\n redis: { monthlyUSD: 346 }, // ElastiCache HA: 1 primary + 2 replicas (cache.m7g.large); ~$115 single-node\n};\n\nexport const DEFAULT_PRICING: PricingProfile = AWS_US_EAST_1_ONDEMAND;\n\n/** Which write path is live. `A` = Hot+Cold read-mostly (writes via bulk-load); `B` = live Warm writes. */\nexport type Topology = 'A' | 'B';\n\n/** Sustained access pattern. All rates default to 0; unspecified ⇒ that op contributes nothing. */\nexport interface Workload {\n readonly readsPerSec?: number;\n readonly writesPerSec?: number;\n readonly intersectsPerSec?: number;\n /** HOT-cache hit rate in `[0, 1]` — hits are free; only misses cost. Default 0. */\n readonly cacheHitRate?: number;\n /** Avg serialized chunk/item size (KiB) — drives read/write units. Default 8 (a full roaring bitmap container). */\n readonly avgItemKiB?: number;\n /** Cold chunks fetched per intersection (the chunk-skipping survivors). Default 1. */\n readonly chunksPerIntersect?: number;\n /**\n * Compaction cycles per month across the modeled data (gap #10). Default **0** ⇒ compaction is not modeled\n * and the report *discloses* the omission (rather than silently under-reporting). Set it to fold in the\n * background job that usually dominates operational cost.\n */\n readonly compactionsPerMonth?: number;\n /**\n * Cold chunks re-read per compaction cycle — the whole generation (clean chunks are copied through, 1 GET\n * each). Default: derived from `coldBytes / avgItemKiB` (i.e. the whole modeled cold set is one generation —\n * exact for a single-segment/grounded report; for a multi-segment fleet set this to your *per-segment* chunk\n * count). This whole-generation re-read is the dominant compaction term.\n */\n readonly chunksPerCompaction?: number;\n /** Dirty Warm rows purged per compaction — the secondary RRU-read + WRU-delete term. Default 0. */\n readonly dirtyChunksPerCompaction?: number;\n}\n\n/** One (group of) segment(s) for planning. `count` = how many like this (default 1). */\nexport interface SegmentSizing {\n readonly sizeBytes?: number;\n readonly cardinality?: number;\n /** Number of segments with these characteristics. Default 1. */\n readonly count?: number;\n}\n\nexport interface EstimateInput {\n readonly segments: readonly SegmentSizing[];\n readonly workload?: Workload;\n readonly topology?: Topology;\n readonly pricing?: PricingProfile;\n}\n\n/**\n * A self-relative cost hint. See {@link CostReport.advisories}.\n *\n * `code` is the stable, machine-readable identity — branch on it rather than parsing `message`.\n */\nexport interface CostAdvisory {\n /**\n * `'batchable-writes'` — the modeled write count far exceeds the number of distinct Warm rows the data can\n * occupy, so each row is being rewritten many times over. If those ids ever arrive together, `addMany()`\n * collapses them to one write per chunk and bulk-load writes Cold directly.\n */\n readonly code: 'batchable-writes';\n /** Human-readable, safe to log or print. Carries the numbers that triggered it. */\n readonly message: string;\n /** The modeled cost of the term this advisory is about (USD/month). */\n readonly currentUSD: number;\n /**\n * A **floor**, not a promise: the same term if the writes were perfectly batched into one write per distinct\n * Warm row. Real batching lands between this and {@link CostAdvisory.currentUSD}, depending on how the ids\n * actually arrive — which the estimator cannot know.\n */\n readonly batchedFloorUSD: number;\n}\n\nexport interface CostReport {\n readonly monthlyUSD: {\n readonly byTier: { readonly hot: number; readonly warm: number; readonly cold: number };\n readonly byOp: {\n readonly reads: number;\n readonly writes: number;\n readonly intersects: number;\n readonly storage: number;\n /** Background compaction (whole-generation re-read + PUT + Warm purge). 0 unless `compactionsPerMonth` is set. */\n readonly compaction: number;\n };\n readonly total: number;\n };\n /**\n * Sustained rate at which the pay-per-use model's cost passes the flat Redis baseline (per axis, the other\n * at 0), **evaluated at this report's `cacheHitRate` + `avgItemKiB`** — so a higher cache-hit rate raises\n * `readsPerSec` (cache hits are free). `Infinity` means that axis never crosses (e.g. a flat/provisioned\n * tier, or a 100% cache-hit rate). The published anchors (~26 writes/s, ~329 reads/s) are at `cacheHitRate: 0`.\n */\n readonly redisCrossover: { readonly writesPerSec: number; readonly readsPerSec: number };\n readonly verdict: 'win-big' | 'win' | 'lose-zone';\n readonly rationale: string;\n /**\n * Zero or more **self-relative** hints: places this workload is paying more than *this same library* would\n * charge for the same outcome. Distinct from {@link CostReport.verdict}, which only compares against the flat\n * Redis baseline — a workload can beat Redis by 40× and still be 100× more expensive than it needs to be, and\n * the verdict alone would call that `win-big` and say nothing.\n *\n * Empty is the normal case. Advisories never change the dollar figures; they are additive commentary, and each\n * carries a machine-readable {@link CostAdvisory.code} so consumers don't string-match.\n */\n readonly advisories: readonly CostAdvisory[];\n readonly assumptions: {\n readonly cacheHitRate: number;\n readonly pricingName: string;\n /** True when segment **sizes** were real (grounded `costReport`), false for a pure `estimateCost`. */\n readonly grounded: boolean;\n readonly topology: Topology;\n readonly notes: readonly string[];\n };\n}\n\nconst SECONDS_PER_MONTH = 730 * 3600; // 2,628,000 — the research's convention\nconst GIB = 1024 ** 3;\n\n/** Fail-fast at the boundary: reject non-finite / negative inputs rather than leak NaN into the report. */\nfunction requireFiniteNonNeg(n: number, field: string): number {\n if (!Number.isFinite(n) || n < 0) {\n throw new ValidationError(`${field} must be a finite number >= 0; got ${n}`);\n }\n return n;\n}\n\n/** As above, but for divisors that must be strictly positive (a 0-KiB unit would divide to Infinity). */\nfunction requireFinitePos(n: number, field: string): number {\n if (!Number.isFinite(n) || n <= 0) {\n throw new ValidationError(`${field} must be a finite number > 0; got ${n}`);\n }\n return n;\n}\n\nfunction clamp01(n: number): number {\n return n < 0 ? 0 : n > 1 ? 1 : n;\n}\n\n/** Rough bytes for a segment when only cardinality is known: 2 B/value (array-container upper bound, B6/B7). */\nfunction sizingBytes(spec: SegmentSizing): number {\n if (spec.sizeBytes !== undefined) return requireFiniteNonNeg(spec.sizeBytes, 'segment.sizeBytes');\n if (spec.cardinality !== undefined) {\n return requireFiniteNonNeg(spec.cardinality, 'segment.cardinality') * 2;\n }\n return 0;\n}\n\n/**\n * Fire `batchable-writes` only once a Warm row is being rewritten at least this many times over the month.\n * Below it there is little to amortize — at a ratio of 1 you are already at one write per row.\n */\nconst BATCHABLE_WRITE_RATIO = 8;\n\n/**\n * …and only when acting on it is worth real money. Without this the advisory nags about pennies on any\n * write-shaped workload, and an advisory that cries wolf is worse than no advisory at all.\n */\nconst BATCHABLE_MIN_SAVINGS_USD = 1;\n\n/**\n * Derive the self-relative advisories. **Pure** — no I/O, clock, or randomness, so it stays inside the\n * deterministic core seam and is directly unit-testable.\n *\n * `maxWarmRows` must be a HARD upper bound on the distinct Warm rows the modeled data can occupy, never an\n * estimate. That direction matters: the trigger is `writes / maxWarmRows`, so *over*-stating the bound makes the\n * advisory quieter (a false negative — it misses a case it could have flagged) while *under*-stating it makes the\n * advisory fire on workloads that are already optimal (a false positive, which trains people to ignore it). The\n * bound is therefore taken from the id space itself — a 16-bit chunk key means at most {@link CHUNK_COUNT} rows\n * per segment — tightened by declared cardinality only, which cannot exceed the row count either. Byte-derived\n * cardinality is deliberately NOT used: `sizingBytes`'s 2 B/value convention understates a dense bitmap\n * container by ~16×, which would understate the bound and produce exactly the false positives above.\n */\nfunction deriveAdvisories(input: {\n readonly writes: number;\n readonly writesUSD: number;\n readonly maxWarmRows: number;\n readonly warmWriteUSD: number;\n}): readonly CostAdvisory[] {\n const { writes, writesUSD, maxWarmRows, warmWriteUSD } = input;\n const out: CostAdvisory[] = [];\n\n if (writes > 0 && writesUSD > 0 && maxWarmRows > 0) {\n const ratio = writes / maxWarmRows;\n const batchedFloorUSD = maxWarmRows * warmWriteUSD;\n const savings = writesUSD - batchedFloorUSD;\n if (ratio >= BATCHABLE_WRITE_RATIO && savings >= BATCHABLE_MIN_SAVINGS_USD) {\n out.push({\n code: 'batchable-writes',\n message:\n `${Math.round(writes).toLocaleString('en-US')} writes/mo against data occupying at most ` +\n `${maxWarmRows.toLocaleString('en-US')} Warm rows — each row rewritten ~${Math.round(ratio).toLocaleString('en-US')}× ` +\n `($${writesUSD.toFixed(2)}/mo). IF these ids ever arrive together, addMany() collapses them to one ` +\n `write per chunk and bulkLoadCrbmGeneration writes Cold directly, taking the write term toward ` +\n `$${batchedFloorUSD.toFixed(2)}/mo. If they genuinely arrive one at a time (real-time qualification), ` +\n `add() is the correct path and this is simply what it costs.`,\n currentUSD: writesUSD,\n batchedFloorUSD,\n });\n }\n }\n\n return out;\n}\n\n/** Core report builder shared by planning + grounded modes. `coldBytes` is total across all segments. */\nfunction buildReport(input: {\n readonly coldBytes: number;\n readonly workload: Workload;\n readonly topology: Topology;\n readonly pricing: PricingProfile;\n readonly grounded: boolean;\n readonly extraNotes?: readonly string[];\n /** Hard upper bound on distinct Warm rows the modeled data can occupy. See {@link deriveAdvisories}. */\n readonly maxWarmRows: number;\n}): CostReport {\n const { topology, pricing, grounded } = input;\n const { cold, warm, redis } = pricing;\n const S = SECONDS_PER_MONTH;\n\n // The pricing profile is a public, caller-supplied boundary input too — validate every rate that feeds\n // the report so a malformed profile fails fast rather than leaking NaN/Infinity dollars + a bogus verdict.\n requireFiniteNonNeg(cold.getPerMillion, 'pricing.cold.getPerMillion');\n requireFiniteNonNeg(cold.putPerMillion, 'pricing.cold.putPerMillion'); // now consumed by the compaction term\n requireFiniteNonNeg(cold.storagePerGiBMonth, 'pricing.cold.storagePerGiBMonth');\n requireFiniteNonNeg(warm.rruPerMillion, 'pricing.warm.rruPerMillion');\n requireFiniteNonNeg(warm.wruPerMillion, 'pricing.warm.wruPerMillion');\n requireFinitePos(warm.readUnitKiB, 'pricing.warm.readUnitKiB');\n requireFinitePos(warm.writeUnitKiB, 'pricing.warm.writeUnitKiB');\n requireFiniteNonNeg(redis.monthlyUSD, 'pricing.redis.monthlyUSD');\n\n const coldBytes = requireFiniteNonNeg(input.coldBytes, 'coldBytes');\n const cacheHitRate = clamp01(\n requireFiniteNonNeg(input.workload.cacheHitRate ?? 0, 'cacheHitRate'),\n );\n const readsPerSec = requireFiniteNonNeg(input.workload.readsPerSec ?? 0, 'readsPerSec');\n const writesPerSec = requireFiniteNonNeg(input.workload.writesPerSec ?? 0, 'writesPerSec');\n const intersectsPerSec = requireFiniteNonNeg(\n input.workload.intersectsPerSec ?? 0,\n 'intersectsPerSec',\n );\n const avgItemKiB = requireFiniteNonNeg(input.workload.avgItemKiB ?? 8, 'avgItemKiB');\n const chunksPerIntersect = requireFiniteNonNeg(\n input.workload.chunksPerIntersect ?? 1,\n 'chunksPerIntersect',\n );\n const compactionsPerMonth = requireFiniteNonNeg(\n input.workload.compactionsPerMonth ?? 0,\n 'compactionsPerMonth',\n );\n const avgItemBytes = avgItemKiB * 1024;\n const derivedChunks = avgItemBytes > 0 ? Math.ceil(coldBytes / avgItemBytes) : 0;\n const chunksPerCompaction = requireFiniteNonNeg(\n input.workload.chunksPerCompaction ?? derivedChunks,\n 'chunksPerCompaction',\n );\n const dirtyChunksPerCompaction = requireFiniteNonNeg(\n input.workload.dirtyChunksPerCompaction ?? 0,\n 'dirtyChunksPerCompaction',\n );\n\n // Per-op unit costs (USD). `Math.max(1, ...)` enforces DynamoDB's ≥1-unit-per-request billing.\n const rruMult = warm.stronglyConsistent ? 1 : 0.5;\n const warmReadUSD =\n Math.max(1, Math.ceil(avgItemKiB / warm.readUnitKiB)) * rruMult * (warm.rruPerMillion / 1e6);\n const warmWriteUSD =\n Math.max(1, Math.ceil(avgItemKiB / warm.writeUnitKiB)) * (warm.wruPerMillion / 1e6);\n const coldGetUSD = cold.getPerMillion / 1e6; // same-region egress is free; internet egress not modeled\n\n // Monthly op volumes.\n const missFraction = 1 - cacheHitRate;\n const readMisses = readsPerSec * S * missFraction;\n const writes = writesPerSec * S;\n const intersects = intersectsPerSec * S;\n\n // Storage (monthly, exact when grounded). Warm delta storage is treated as negligible (only dirty chunks).\n const storageUSD = (coldBytes / GIB) * cold.storagePerGiBMonth;\n\n // Request costs by op. Topology-A reads hit Cold (S3 GET); Topology-B reads hit the Warm tier; Topology-A\n // has no per-op writes (writes arrive via bulk-load). Intersection fetches the surviving Cold chunks.\n const readsUSD = topology === 'A' ? readMisses * coldGetUSD : readMisses * warmReadUSD;\n const writesUSD = topology === 'B' ? writes * warmWriteUSD : 0;\n const intersectsUSD = intersects * chunksPerIntersect * coldGetUSD;\n\n // Compaction (gap #10): per cycle, re-read the whole generation (chunksPerCompaction Cold GETs — the\n // dominant term), write one new `.crbm` (a PUT), and purge the dirty Warm rows (an RRU read + a WRU delete).\n // Same-region GET/PUT egress is free; the GC delete of the superseded generation is free (not modeled).\n const putUSD = cold.putPerMillion / 1e6;\n const compactionColdUSD = compactionsPerMonth * (chunksPerCompaction * coldGetUSD + putUSD);\n const compactionWarmUSD =\n compactionsPerMonth * dirtyChunksPerCompaction * (warmReadUSD + warmWriteUSD);\n const compactionUSD = compactionColdUSD + compactionWarmUSD;\n\n const total = readsUSD + writesUSD + intersectsUSD + storageUSD + compactionUSD;\n\n const warmTierUSD = (topology === 'B' ? readsUSD + writesUSD : 0) + compactionWarmUSD;\n const coldTierUSD =\n storageUSD + (topology === 'A' ? readsUSD : 0) + intersectsUSD + compactionColdUSD;\n\n // Crossovers: sustained rate (other axis 0) where request cost alone passes (redis − fixed storage),\n // evaluated at this report's cache posture (misses) and item size (units).\n const headroom = Math.max(0, redis.monthlyUSD - storageUSD);\n const perReadUSD = topology === 'A' ? coldGetUSD : warmReadUSD;\n const writesCross =\n topology === 'B' && warmWriteUSD > 0 ? headroom / (S * warmWriteUSD) : Infinity;\n const readsCross =\n perReadUSD > 0 && missFraction > 0 ? headroom / (S * perReadUSD * missFraction) : Infinity;\n\n const verdict: CostReport['verdict'] =\n total <= redis.monthlyUSD * 0.1 ? 'win-big' : total < redis.monthlyUSD ? 'win' : 'lose-zone';\n\n const dominant = Math.max(readsUSD, writesUSD, intersectsUSD, storageUSD, compactionUSD);\n let driver = 'storage';\n if (dominant === writesUSD && writesUSD > 0)\n driver = 'warm writes (the per-1KiB WRU cost driver)';\n else if (dominant === readsUSD && readsUSD > 0)\n driver = topology === 'A' ? 'cold reads (S3 GETs)' : 'warm reads';\n else if (dominant === intersectsUSD && intersectsUSD > 0) driver = 'intersection cold fetches';\n else if (dominant === compactionUSD && compactionUSD > 0)\n driver = 'compaction (whole-generation re-read)';\n const rationale =\n verdict === 'lose-zone'\n ? `pay-per-use total $${total.toFixed(2)}/mo exceeds the $${redis.monthlyUSD}/mo flat baseline; dominated by ${driver}`\n : verdict === 'win-big'\n ? `$${total.toFixed(2)}/mo — ≤10% of the $${redis.monthlyUSD}/mo baseline; dominated by ${driver}`\n : `$${total.toFixed(2)}/mo, under the $${redis.monthlyUSD}/mo baseline; dominated by ${driver}`;\n\n const notes = [\n 'S3→same-region egress treated as free; internet egress is not modeled.',\n 'Warm delta storage treated as negligible (only dirty chunks).',\n 'Request cost is from the supplied workload rates (live-metrics-derived request cost is a later phase).',\n compactionsPerMonth > 0\n ? `Compaction modeled: ${compactionsPerMonth}/mo × (${chunksPerCompaction} Cold GET + 1 PUT${dirtyChunksPerCompaction > 0 ? ` + ${dirtyChunksPerCompaction}-row Warm purge` : ''}); the whole-generation re-read dominates. GC delete of the superseded generation is free (not modeled).`\n : 'Compaction is NOT modeled — set workload.compactionsPerMonth (+ chunksPerCompaction) to include the whole-generation re-read that dominates operational cost.',\n ...(input.extraNotes ?? []),\n ];\n\n return {\n monthlyUSD: {\n byTier: { hot: 0, warm: warmTierUSD, cold: coldTierUSD },\n byOp: {\n reads: readsUSD,\n writes: writesUSD,\n intersects: intersectsUSD,\n storage: storageUSD,\n compaction: compactionUSD,\n },\n total,\n },\n redisCrossover: { writesPerSec: writesCross, readsPerSec: readsCross },\n verdict,\n rationale,\n // Topology-A has no per-op writes (they arrive via bulk-load), so `writesUSD` is 0 there and the advisory\n // cannot fire — correctly, since bulk-load is already the batched path.\n advisories: deriveAdvisories({\n writes,\n writesUSD,\n maxWarmRows: requireFiniteNonNeg(input.maxWarmRows, 'maxWarmRows'),\n warmWriteUSD,\n }),\n assumptions: { cacheHitRate, pricingName: pricing.name, grounded, topology, notes },\n };\n}\n\n/**\n * **Planning** cost estimate — pure, no instance or live data needed (sizing, sales, what-if). Segment sizes\n * are taken as given (or roughly derived from cardinality); use the grounded `segment.costReport()` for\n * exact, real sizes. See {@link CostReport}.\n */\nexport function estimateCost(input: EstimateInput): CostReport {\n const topology = input.topology ?? 'A';\n const pricing = input.pricing ?? DEFAULT_PRICING;\n const workload = input.workload ?? {};\n let coldBytes = 0;\n // Hard bound on distinct Warm rows: a 16-bit chunk key caps a segment at CHUNK_COUNT rows, and a segment can\n // never occupy more rows than it holds ids — so declared `cardinality` tightens it. `sizeBytes`-only specs get\n // the un-tightened cap rather than a byte-derived guess, which would understate it (see `deriveAdvisories`).\n let maxWarmRows = 0;\n for (const spec of input.segments) {\n const count = Math.floor(requireFiniteNonNeg(spec.count ?? 1, 'segment.count'));\n coldBytes += sizingBytes(spec) * count;\n const perSegment =\n spec.cardinality !== undefined\n ? Math.min(\n Math.floor(requireFiniteNonNeg(spec.cardinality, 'segment.cardinality')),\n CHUNK_COUNT,\n )\n : CHUNK_COUNT;\n maxWarmRows += perSegment * count;\n }\n return buildReport({ coldBytes, workload, topology, pricing, grounded: false, maxWarmRows });\n}\n\n/**\n * **Grounded** report from a real segment byte total (from the `.crbm` index) + a supplied workload. Used by\n * `Segment.costReport()` in `index.ts`. `grounded` defaults to true (the size is exact, not estimated); the\n * caller passes `grounded: false` + a note when the Cold source can't measure size.\n */\nexport function groundedReport(input: {\n readonly coldBytes: number;\n readonly grounded?: boolean;\n readonly workload?: Workload;\n readonly topology?: Topology;\n readonly pricing?: PricingProfile;\n readonly extraNotes?: readonly string[];\n /**\n * Hard upper bound on distinct Warm rows, for the advisories. Defaults to {@link CHUNK_COUNT} — this models\n * ONE segment, and a 16-bit chunk key caps a segment there. `SegmentSize` carries only `sizeBytes` today, so\n * an exact per-segment chunk count would need a driver-interface change; the id-space cap needs nothing and is\n * sound in the safe direction (it can only make the advisory quieter).\n */\n readonly maxWarmRows?: number;\n}): CostReport {\n return buildReport({\n coldBytes: input.coldBytes,\n workload: input.workload ?? {},\n topology: input.topology ?? 'A',\n pricing: input.pricing ?? DEFAULT_PRICING,\n grounded: input.grounded ?? true,\n extraNotes: input.extraNotes,\n maxWarmRows: input.maxWarmRows ?? CHUNK_COUNT,\n });\n}\n","/**\n * Audit sink (Phase 5d) — an injected, no-op-by-default seam for **security/compliance** events, distinct\n * from the metrics sink (5a). Different audience (an audit log / SIEM, not a dashboard), different retention,\n * and only the compliance-relevant *state changes* — never routine reads/writes (that's the metrics sink).\n * It doubles as the GDPR Art. 30 \"record of processing\" surface: publishes, compactions, and erasures.\n *\n * Like `Clock`/`Rng`/`IMetricsSink`, it's injected (into the lifecycle operations that emit — compaction,\n * bulk-load, erasure) and wrapped exception-safe, so a buggy sink can never break the operation it observes.\n * Events are vendor-neutral and carry no timestamp/actor — the sink runs synchronously at the event, so it\n * stamps its own time / attaches the caller identity (keeps `core/` free of ambient time). As with metrics,\n * `segment`/`namespace` are caller-controlled strings that may be PII — treat them accordingly when routing.\n *\n * Not (yet) emitted: **KEK rotation** — rotation here is operator-side keystore reconfiguration (key-id-tagged\n * wrappings, no data re-encryption), so there is no library call to hook. A future `rewrapSegment()` op would\n * add a `kek.rotate` variant; until then, audit key changes at your keystore-config layer.\n */\n\n/** A security/compliance-relevant state change. Vendor-neutral; the sink adds its own timestamp/actor. */\nexport type AuditEvent =\n | {\n /** A new immutable Cold generation *became the segment's current generation* (via bulk-load publish). */\n readonly kind: 'segment.publish';\n readonly namespace?: string;\n readonly segment: string;\n readonly generation: number;\n }\n | {\n /** Compaction committed a new generation (emitted at the durable commit, before Warm-row purge). */\n readonly kind: 'segment.compact';\n readonly namespace?: string;\n readonly segment: string;\n readonly generation: number;\n }\n | {\n /**\n * A segment was **crypto-shredded** — its wrapped DEK(s) are gone, so its at-rest Cold bytes are now\n * permanently unreadable. Emitted only for a genuine key shred, never for a cleartext tombstone (which\n * leaves the Cold bytes readable) or an idempotent re-run.\n */\n readonly kind: 'segment.erase';\n readonly namespace?: string;\n readonly segment: string;\n }\n | {\n /** A namespace erasure was executed. `segmentsShredded` is the count actually crypto-shredded (may be 0). */\n readonly kind: 'namespace.erase';\n readonly namespace: string;\n readonly segmentsShredded: number;\n };\n\n/** The `kind` discriminant of an {@link AuditEvent}. */\nexport type AuditEventKind = AuditEvent['kind'];\n\n/** Sink for {@link AuditEvent}s. Injected via the lifecycle options; the default is {@link NOOP_AUDIT}. */\nexport interface IAuditSink {\n onEvent(event: AuditEvent): void;\n}\n\n/** The default sink: records nothing. */\nexport const NOOP_AUDIT: IAuditSink = {\n onEvent(): void {\n /* discard */\n },\n};\n\n/**\n * Wrap a sink so a throwing/buggy `onEvent` can never break the lifecycle operation it observes — audit is\n * strictly observation. Returns {@link NOOP_AUDIT} unchanged (so the no-op case skips even the try/catch alloc).\n */\nexport function safeAudit(sink: IAuditSink): IAuditSink {\n if (sink === NOOP_AUDIT) return sink;\n return {\n onEvent(event: AuditEvent): void {\n try {\n sink.onEvent(event);\n } catch {\n /* swallow — an audit sink must never break the operation it observes */\n }\n },\n };\n}\n\n/** A ready-made sink that records events into an in-memory list — handy for tests + simple audit trails. */\nexport class RecordingAuditSink implements IAuditSink {\n private readonly recorded: AuditEvent[] = [];\n\n onEvent(event: AuditEvent): void {\n this.recorded.push(event);\n }\n\n /** An independent copy of the recorded events, in emission order. */\n snapshot(): AuditEvent[] {\n return this.recorded.map((e) => ({ ...e }));\n }\n\n reset(): void {\n this.recorded.length = 0;\n }\n}\n","/**\n * The **bitmap-codec seam**.\n *\n * `core/` is **codec-agnostic**: `SegmentEngine`, compaction, and the `.crbm` read/write helpers only ever\n * construct and combine bitmaps through the {@link CodecInterface} factory + the {@link CodecBitmap} value type\n * defined here — never a concrete implementation. The flagship codec is roaring (`roaringCodec`, today in\n * `core/bitmap.ts`; it moves to `@cloudbitmaps/roaring` when the package split lands); `@cloudbitmaps/bitmap`\n * (plain bitset) and `@cloudbitmaps/soaring` plug in behind the same seam with zero engine or driver changes.\n *\n * **Homogeneity contract:** a single store uses a single codec, so every {@link CodecBitmap} an operation sees\n * was produced by the same {@link CodecInterface}. The binary set ops ({@link CodecBitmap.orInPlace} etc.) may\n * therefore assume `other` is the same concrete type and are not required to interoperate across codecs.\n * (Corollary: a decoded-chunk HOT cache is codec-specific — never share one `cache` across engines built with\n * different codecs, or a cached bitmap from codec A could reach codec B's in-place op. The `CloudRoaring` facade\n * mints the cache per store, so this cannot arise in normal use.)\n *\n * **Interface surface = exactly what the engine needs**, kept general enough for the known fast-follow codecs\n * (positional/rank-select access + raw-bitset interop that `@cloudbitmaps/bitmap` will add live on that\n * package's own extended value type, not here — the engine never calls them). The one codec-linked concern\n * this seam intentionally leaves in the format layer is the `.crbm` **serialization id** (`ROARING_PORTABLE_ID`\n * in `crbm/format.ts`): it is stamped in the footer and validated on read, and generalizes to a per-codec id\n * *with* the second codec's format work — a documented follow-up, not part of this interface.\n */\n\nimport { ValidationError } from './errors';\n\n/**\n * The value type a codec produces — a mutable set of `u32` with set algebra and portable (de)serialization.\n * This is the shape `SafeBitmap` already has; the engine holds these, caches them, and merges tiers with them.\n */\nexport interface CodecBitmap {\n /** Serialize with the codec's **stable, portable** format (never a frozen/unsafe variant). */\n serialize(): Uint8Array;\n add(value: number): void;\n addMany(values: Iterable<number>): void;\n remove(value: number): void;\n removeMany(values: Iterable<number>): void;\n has(value: number): boolean;\n /** Cardinality. */\n readonly size: number;\n readonly isEmpty: boolean;\n /** A deep copy — mutating the clone must not touch the original (the HOT cache relies on this). */\n clone(): CodecBitmap;\n /** In-place union `this = this ∪ other`. `other` is from the same codec (see the homogeneity contract). */\n orInPlace(other: CodecBitmap): void;\n /** In-place difference `this = this \\ other`. */\n andNotInPlace(other: CodecBitmap): void;\n /** In-place intersection `this = this ∩ other`. */\n andInPlace(other: CodecBitmap): void;\n /** Ascending iterator over the set values. */\n [Symbol.iterator](): IterableIterator<number>;\n toArray(): number[];\n}\n\n/**\n * A pluggable bitmap codec — the factory the codec-agnostic engine constructs {@link CodecBitmap}s through.\n * Implementations **must** size-cap before handing untrusted bytes to any native decoder and use a safe\n * (never a trusting/frozen) deserializer (threat model S1).\n */\nexport interface CodecInterface {\n /** An empty set. */\n empty(): CodecBitmap;\n /** A set seeded from an iterable of `u32` values. */\n fromValues(values: Iterable<number>): CodecBitmap;\n /**\n * Size-cap (`bytes.length <= maxBytes`) then portable-deserialize. Throws `IntegrityError` when the input\n * exceeds the cap or fails to decode — the native decoder is never handed unbounded or unsafe-format input.\n */\n safeDeserialize(bytes: Uint8Array, maxBytes: number): CodecBitmap;\n}\n\n/**\n * Resolve a codec that a **public core entry point** was given, failing fast when it is missing.\n *\n * Why these entry points take `codec?` rather than a required field: `bulkLoadCrbmGeneration` /\n * `compactSegment` / `runExport` are call-compatible public API, and core cannot supply a default (the concrete\n * codec lives in a *flavor* package that depends on core — a default here would invert that arrow). A **flavor**\n * package binds the codec for its users (`@cloudbitmaps/roaring` re-exports codec-bound wrappers), so an\n * application never reaches this throw; only someone calling `@cloudbitmaps/core` directly — i.e. a flavor or\n * driver author — can, and for them the typed error names exactly what to pass.\n */\nexport function requireCodec(codec: CodecInterface | undefined, api: string): CodecInterface {\n if (codec === undefined) {\n throw new ValidationError(\n `${api} needs a bitmap codec: pass \\`codec\\` (e.g. \\`roaringCodec\\` from @cloudbitmaps/roaring). ` +\n `@cloudbitmaps/core is codec-agnostic and has no default — install a flavor package, whose ` +\n `equivalents bind the codec for you.`,\n );\n }\n return codec;\n}\n","/**\n * Encryption seams — the **pure** interfaces `core/` depends on so the codec can encrypt/decrypt without\n * importing `node:crypto` (lint-banned here, like `Clock`/`Rng`/drivers). Concrete AES-256-GCM lives outside\n * `core/` (`src/drivers/crypto.ts`) and is injected. The envelope scheme: a per-segment DEK wrapped under an\n * operator-held KEK, so discarding the DEK crypto-shreds the segment,\n * [DECISIONS #19]. Per-chunk AEAD over the `.crbm` payloads + index; a per-segment **DEK** wrapped (envelope\n * encryption) under one or more **KEK**s by an {@link IKeystore}; the wrapped DEK(s) live in the registry, so\n * crypto-shred = delete them.\n */\n\n/** One AEAD result: a fresh per-message nonce, the ciphertext, and the authentication tag. */\nexport interface AeadSealed {\n readonly nonce: Uint8Array;\n readonly ciphertext: Uint8Array;\n readonly tag: Uint8Array;\n}\n\n/**\n * Authenticated encryption bound to a single key (a segment's DEK). `aad` (associated data) is authenticated\n * but not encrypted — the codec passes each chunk's `(namespace, segment, generation, chunkKey)` identity\n * ({@link aadFor}), so a chunk's ciphertext can't be silently relocated to another segment/generation/chunk or\n * the index, even by someone who can rewrite Cold objects. The seam is symmetric and self-framing-agnostic:\n * the caller decides where the nonce/tag go (inline with a chunk, or in the footer for the index).\n */\nexport interface Aead {\n /** Encrypt `plaintext`, authenticating `aad`. Returns a fresh nonce + ciphertext + tag. */\n seal(plaintext: Uint8Array, aad: Uint8Array): AeadSealed;\n /**\n * Decrypt + verify. Throws {@link IntegrityError} on **any** mismatch (wrong key, tampered ciphertext/tag,\n * or `aad` that doesn't match what was sealed) — never returns wrong-but-plausible plaintext.\n */\n open(sealed: AeadSealed, aad: Uint8Array): Uint8Array;\n}\n\n/**\n * A DEK wrapped under one KEK. A segment stores a **list** of these (one per KEK it was wrapped under — e.g.\n * an active KEK plus an offline recovery KEK), so losing one KEK isn't fatal and KEK rotation needs no\n * data re-encryption. `keyId` names which KEK; `wrapped` is the opaque wrapped-key blob (base64). Carries no\n * plaintext key material — safe to store in the registry next to the (encrypted) data.\n */\nexport interface WrappedDek {\n readonly keyId: string;\n readonly wrapped: string;\n}\n\n/**\n * Envelope key management — the injected seam between the codec and however the operator holds key material\n * (in-process BYOK by default; KMS/Vault as optional adapters later). Async so a remote keystore (KMS) fits\n * the same interface. Never exposes raw key bytes to `core/`: it returns an {@link Aead} bound to the DEK.\n */\nexport interface IKeystore {\n /**\n * Mint a fresh per-segment DEK, wrapped under the active KEK (and any recovery KEK). Returns the wrapping(s)\n * to persist in the registry plus an {@link Aead} to encrypt this segment's chunks with.\n */\n createDek(): Promise<{ wrapped: WrappedDek[]; aead: Aead }>;\n /**\n * Reconstruct the {@link Aead} from a segment's stored wrappings by unwrapping with any KEK currently held.\n * Throws {@link KeyUnavailableError} if it holds none of the referenced KEKs (lost key, or a shredded\n * segment whose wrappings were deleted).\n */\n openDek(wrapped: readonly WrappedDek[]): Promise<Aead>;\n}\n\n/**\n * What the encrypting codec needs: the {@link Aead} for this segment's DEK plus a way to build the AAD for a\n * given scope (`'index'` or a chunkKey). Built per (segment, generation) by the cold-source bridge so the\n * codec itself stays segment-agnostic.\n */\nexport interface CrbmCrypto {\n readonly aead: Aead;\n aadFor(scope: number | 'index'): Uint8Array;\n}\n\nconst AAD_VERSION = 1;\nconst SCOPE_CHUNK = 0;\nconst SCOPE_INDEX = 1;\n\n/**\n * Build the AEAD associated-data binding a chunk (or the index) to its exact location:\n * `v1 ‖ len(namespace) ‖ namespace ‖ len(segment) ‖ segment ‖ generation ‖ scope ‖ chunkKey`. Length-prefixed\n * so distinct `(namespace, segment)` pairs can never collide. Pure (no crypto) — just the authenticated label.\n */\nexport function aadFor(\n ref: { readonly namespace?: string; readonly segment: string },\n generation: number,\n scope: number | 'index',\n): Uint8Array {\n const enc = new TextEncoder();\n const ns = enc.encode(ref.namespace ?? '');\n const seg = enc.encode(ref.segment);\n const out = new Uint8Array(1 + 2 + ns.length + 2 + seg.length + 8 + 1 + 4);\n const view = new DataView(out.buffer);\n let o = 0;\n out[o] = AAD_VERSION;\n o += 1;\n view.setUint16(o, ns.length, true);\n o += 2;\n out.set(ns, o);\n o += ns.length;\n view.setUint16(o, seg.length, true);\n o += 2;\n out.set(seg, o);\n o += seg.length;\n view.setBigUint64(o, BigInt(generation), true);\n o += 8;\n out[o] = scope === 'index' ? SCOPE_INDEX : SCOPE_CHUNK;\n o += 1;\n view.setUint32(o, scope === 'index' ? 0 : scope, true);\n return out;\n}\n","/**\n * CRC32C (Castagnoli, polynomial 0x1EDC6F41) — the pre-deserialize integrity screen for `.crbm`\n * payloads, index, and footer.\n *\n * Pure TypeScript, table-driven: `core/` may not import `crypto`/`node:crypto` (the determinism lint\n * enforces it), and a from-scratch implementation is what the cross-language golden corpus will be pinned\n * against. CRC32C (not CRC32) is the locked choice — it matches the hardware-accelerated checksum used\n * by SSE/iSCSI/Btrfs, and it is the algorithm the `.crbm` format locks in.\n */\n\n/** Reflected CRC32C lookup table (256 entries), built once from the reflected polynomial. */\nconst TABLE = ((): Uint32Array => {\n const POLY = 0x82f63b78; // bit-reflected 0x1EDC6F41\n const table = new Uint32Array(256);\n for (let n = 0; n < 256; n++) {\n let c = n;\n for (let k = 0; k < 8; k++) {\n c = c & 1 ? POLY ^ (c >>> 1) : c >>> 1;\n }\n table[n] = c >>> 0;\n }\n return table;\n})();\n\n/**\n * CRC32C of `bytes` (optionally continuing from a previous `seed`, for streaming over multiple\n * buffers). Returns an unsigned 32-bit integer.\n */\nexport function crc32c(bytes: Uint8Array, seed = 0): number {\n let crc = (seed ^ 0xffffffff) >>> 0;\n for (let i = 0; i < bytes.length; i++) {\n crc = (TABLE[(crc ^ bytes[i]!)! & 0xff]! ^ (crc >>> 8)) >>> 0;\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n","/**\n * LEB128 unsigned varint codec for the `.crbm` chunk index.\n *\n * The index is delta+varint encoded so a full 16-bit span stays ~400–650 KB instead of ~900 KB of\n * fixed triplets (finding B6). All index varint values are small (chunk-key deltas ≤ 65535,\n * cardinalities ≤ 65536, payload lengths bounded by a size cap) — well within 32 bits — so this codec\n * accepts unsigned integers in `[0, 0xffffffff]` and rejects anything wider as a programming error.\n */\nimport { IntegrityError } from '../errors';\n\nconst U32_CEIL = 0x1_0000_0000; // 2^32\n\n/** Append the LEB128 encoding of a u32 `value` to `out`. */\nexport function writeVarint(out: number[], value: number): void {\n if (!Number.isInteger(value) || value < 0 || value >= U32_CEIL) {\n throw new RangeError(`varint value must be a u32; got ${value}`);\n }\n let v = value;\n while (v > 0x7f) {\n out.push((v & 0x7f) | 0x80);\n v >>>= 7;\n }\n out.push(v);\n}\n\nexport interface VarintRead {\n readonly value: number;\n /** Offset just past the bytes consumed. */\n readonly next: number;\n}\n\n/**\n * Decode a LEB128 varint from `bytes` starting at `offset`. Throws `IntegrityError` on a truncated or\n * over-long (> 5-byte / > u32) encoding — the bytes are untrusted, so a malformed index must fail\n * cleanly, never loop or overflow.\n */\nexport function readVarint(bytes: Uint8Array, offset: number): VarintRead {\n let result = 0;\n let shift = 0;\n let pos = offset;\n for (let i = 0; i < 5; i++) {\n if (pos >= bytes.length) {\n throw new IntegrityError('varint truncated past end of buffer');\n }\n const byte = bytes[pos]!;\n pos += 1;\n // The 5th byte may contribute at most 4 bits (32 total); reject wider.\n if (i === 4 && byte > 0x0f) {\n throw new IntegrityError('varint exceeds u32 range');\n }\n result += (byte & 0x7f) * 2 ** shift;\n if ((byte & 0x80) === 0) {\n return { value: result, next: pos };\n }\n shift += 7;\n }\n throw new IntegrityError('varint exceeds u32 range');\n}\n","/**\n * Frozen `.crbm` v1.0 layout constants.\n *\n * These byte widths/offsets are pinned by the Phase-2a golden corpus and must never change for v1 —\n * a new layout is a new format version. All multi-byte integers are little-endian (v1 fixes LE).\n */\n\n/** 4-byte magic at both file ends: \"CRBM\". */\nexport const MAGIC = Uint8Array.of(0x43, 0x52, 0x42, 0x4d);\n\nexport const VERSION_MAJOR = 1;\nexport const VERSION_MINOR = 0;\n\n/** Front preamble: magic(4) + version_major(1) + version_minor(1) + reserved(2). */\nexport const PREAMBLE_BYTES = 8;\n\n/** Payloads begin immediately after the preamble. */\nexport const PAYLOAD_START = PREAMBLE_BYTES;\n\n/** Fixed footer size (v1.0). */\nexport const FOOTER_BYTES = 104;\n\n/** Byte offsets of each field within the 104-byte footer. */\nexport const FOOTER = {\n indexOffset: 0, // u64\n indexLength: 8, // u64\n indexCrc32c: 16, // u32\n flags: 20, // u32\n roaringSerializationId: 24, // u16\n elementWidth: 26, // u8\n containerCodec: 27, // u8\n versionMajor: 28, // u8\n versionMinor: 29, // u8\n reserved2: 30, // u16\n generation: 32, // u64\n indexNonce: 40, // 12 B\n indexTag: 52, // 16 B\n keyId: 68, // 16 B\n chunkCount: 84, // u32\n totalCardinality: 88, // u64\n footerCrc32c: 96, // u32 — covers footer bytes [0, 96)\n endMagic: 100, // char[4]\n} as const;\n\n/** Footer bytes covered by `footer_crc32c` (everything before the CRC field). */\nexport const FOOTER_CRC_COVERAGE = FOOTER.footerCrc32c; // 96\n\n/** `flags` bit positions. */\nexport const FLAG_ENCRYPTED = 1 << 0;\nexport const FLAG_INDEX_COMPRESSED = 1 << 1; // reserved\nexport const FLAG_LITTLE_ENDIAN = 1 << 2; // =1 in v1\n\n/** Flag bits a v1 reader understands; any bit outside this mask is an unsupported feature. */\nexport const KNOWN_FLAGS = FLAG_ENCRYPTED | FLAG_LITTLE_ENDIAN;\n\n/**\n * Default element width: 32-bit ids (the u32 member space). `64` is the *reserved* escape above the\n * ~4.29 B-ids/segment u32 ceiling; a v1 (32-bit) reader must **reject** a 64-bit generation rather than feed\n * it to the 32-bit deserializer (which would mis-count fleet-wide). A future 64-bit generation is therefore a\n * **major**-version bump (auto-rejected by old readers), never a silent minor one — see\n * {@link CrbmReader.open} validates this.\n */\nexport const ELEMENT_WIDTH_32 = 32;\n\n/**\n * CRoaring \"portable\" serialization id recorded in the footer. Phase 1's `SafeBitmap` serializes with\n * the portable format; this records that choice so a reader can confirm it can decode the payloads. A\n * generation stamped with any other id is rejected ({@link UnsupportedError}) — a different serialization is\n * a format change, not a payload a v1 reader may guess at.\n */\nexport const ROARING_PORTABLE_ID = 1;\n\n/**\n * The only container codec v1 defines: `0` = none (payloads are stored as the portable roaring serialization\n * with no extra container-level transform). A non-zero codec is a future format feature; a v1 reader rejects\n * it ({@link UnsupportedError}) rather than mis-decode. Stamped by the writer, validated by the reader.\n */\nexport const CONTAINER_CODEC_NONE = 0;\n\n/**\n * Default speculative-tail-read size. The spec's worst-case index (a full 16-bit span) is ~400–650 KB,\n * so 256 KB collapses the read to a single GET for the vast majority of real (sparse/medium) segments;\n * only near-full-span segments take the documented second GET.\n */\nexport const DEFAULT_TAIL_BYTES = 256 * 1024;\n\n/**\n * Hard cap on the index region a reader will fetch/parse from one (untrusted) object. The index is read\n * whole on the cheap `open()`/`count()` path, so it must be bounded before allocation — generously\n * above the ~650 KB full-span worst case, well below a denial-of-wallet allocation.\n */\nexport const DEFAULT_MAX_INDEX_BYTES = 8 * 1024 * 1024;\n\n/** Hard cap on a single chunk payload, defending the native deserializer against oversized input. */\nexport const DEFAULT_MAX_PAYLOAD_BYTES = 16 * 1024 * 1024;\n\n/** A chunk's cardinality is in `[1, 65536]` (empty chunks are never written). */\nexport const MAX_CHUNK_CARDINALITY = 0x1_0000;\n\n/** Fixed width of a per-chunk CRC32C field in the index (high-entropy → not varint). */\nexport const CRC32C_BYTES = 4;\n\n/**\n * v1 AEAD framing sizes (AES-256-GCM), fixed by the format exactly like the roaring serialization id — a\n * different cipher is a new format version. An encrypted chunk payload is stored as `nonce ‖ ciphertext ‖ tag`;\n * the encrypted **index**'s nonce/tag live in the footer's reserved `indexNonce`/`indexTag` slots. Matches\n * {@link FOOTER.indexNonce} (12 B) and {@link FOOTER.indexTag} (16 B).\n */\nexport const AEAD_NONCE_BYTES = 12;\nexport const AEAD_TAG_BYTES = 16;\n","/**\n * `CrbmReader` — speculative-tail-read reader for one `.crbm` generation.\n *\n * `open()` fetches the object's tail in **one GET** (footer + usually the whole index), verifies the\n * footer/index CRCs, and parses the delta+varint index into a map. `getChunk()` then range-GETs a single\n * payload and verifies its CRC32C **before** any native deserialize — every byte from storage is\n * untrusted (F3/F4).\n *\n * **Encryption (Phase 4e).** When the footer's `FLAG_ENCRYPTED` is set, a {@link CrbmCrypto} must be supplied:\n * the index is AES-256-GCM-decrypted (nonce/tag from the footer) and each chunk payload is decrypted after its\n * on-disk CRC passes. The footer's `chunkCount`/`totalCardinality` are zero on an encrypted object (metadata is\n * hidden), so both are derived from the decrypted index; AEAD authentication (incl. the per-location AAD)\n * replaces the cleartext-count cross-check.\n */\nimport { IntegrityError, UnsupportedError, ValidationError } from '../errors';\nimport type { BlobReader } from '../blob';\nimport type { CrbmCrypto } from '../crypto';\nimport { crc32c } from './crc32c';\nimport { readVarint } from './varint';\nimport {\n AEAD_NONCE_BYTES,\n AEAD_TAG_BYTES,\n CONTAINER_CODEC_NONE,\n CRC32C_BYTES,\n DEFAULT_MAX_INDEX_BYTES,\n DEFAULT_MAX_PAYLOAD_BYTES,\n DEFAULT_TAIL_BYTES,\n ELEMENT_WIDTH_32,\n FLAG_ENCRYPTED,\n FLAG_LITTLE_ENDIAN,\n FOOTER,\n FOOTER_BYTES,\n FOOTER_CRC_COVERAGE,\n KNOWN_FLAGS,\n MAGIC,\n MAX_CHUNK_CARDINALITY,\n PAYLOAD_START,\n PREAMBLE_BYTES,\n ROARING_PORTABLE_ID,\n VERSION_MAJOR,\n} from './format';\n\nexport interface CrbmIndexEntry {\n readonly chunkKey: number;\n readonly offset: number;\n readonly length: number;\n readonly cardinality: number;\n readonly crc32c: number;\n}\n\n/**\n * Estimated retained JS heap for one parsed index entry, used to weight the reader-cache byte bound\n * ({@link CrbmReader.retainedIndexBytes}). In V8 an entry costs: a `Map` slot (~48–64 B: two pointer slots +\n * hash chaining), the {@link CrbmIndexEntry} object (~40–56 B: header + 5 fields, where `offset`/`crc32c`\n * routinely exceed the 2³¹ SMI range and box as heap doubles, +16 B each), and one `orderedKeys` array slot\n * (~8 B) — realistically ~130–160 B. Rounded UP to 160 so the bound **over-counts** (a configured N-byte\n * ceiling pins ≤ N of real heap, never more), keeping the aggregate memory guarantee on the safe side. A\n * stable upper proxy, not an exact figure.\n */\nconst RETAINED_BYTES_PER_INDEX_ENTRY = 160;\n\nexport interface CrbmReaderOptions {\n /** Speculative tail size in bytes (default 256 KB; clamped up to at least the footer size). */\n readonly tailBytes?: number;\n /** Hard cap on a single chunk payload length (default 16 MB). */\n readonly maxPayloadBytes?: number;\n /** Hard cap on the whole index region fetched/parsed from one object (default 8 MB). */\n readonly maxIndexBytes?: number;\n /** Decryption context for an encrypted object (its DEK's AEAD + AAD builder). Required iff `FLAG_ENCRYPTED`. */\n readonly crypto?: CrbmCrypto;\n}\n\nfunction magicMatches(bytes: Uint8Array, offset: number): boolean {\n return (\n bytes[offset] === MAGIC[0] &&\n bytes[offset + 1] === MAGIC[1] &&\n bytes[offset + 2] === MAGIC[2] &&\n bytes[offset + 3] === MAGIC[3]\n );\n}\n\n/** Read a u64 footer field, rejecting values past JS safe-integer range (precision would be lost). */\nfunction readU64(view: DataView, offset: number, field: string): number {\n const big = view.getBigUint64(offset, true);\n if (big > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new IntegrityError(`.crbm ${field} ${big} exceeds safe-integer range`);\n }\n return Number(big);\n}\n\nexport class CrbmReader {\n private constructor(\n private readonly blob: BlobReader,\n private readonly objectSize: number,\n readonly generation: number,\n readonly totalCardinality: number,\n private readonly entries: Map<number, CrbmIndexEntry>,\n private readonly orderedKeys: number[],\n /** True when `open()` satisfied the index from the tail GET alone (no second range read). */\n readonly servedFromTail: boolean,\n /** Set iff the object is encrypted — used to decrypt each chunk payload in {@link getChunk}. */\n private readonly crypto: CrbmCrypto | undefined,\n ) {}\n\n /** Total object bytes (from the one-GET tail read) — for grounded storage cost (Phase 5b). */\n get sizeBytes(): number {\n return this.objectSize;\n }\n\n /**\n * Estimated retained JS heap of this reader's parsed index — the weight the cold reader cache bounds on\n * (gap #1: a wide segment's index dominates the reader's footprint). `entries.size` scales with the number\n * of resident chunks (≤ 65536), so this is `entries.size × {@link RETAINED_BYTES_PER_INDEX_ENTRY}`.\n */\n get retainedIndexBytes(): number {\n return this.entries.size * RETAINED_BYTES_PER_INDEX_ENTRY;\n }\n\n /** Per-chunk cardinality (`chunkKey → count`) from the parsed index — no payload reads (Phase 5c cheap count). */\n cardinalities(): Map<number, number> {\n const out = new Map<number, number>();\n for (const [chunkKey, entry] of this.entries) out.set(chunkKey, entry.cardinality);\n return out;\n }\n\n static async open(blob: BlobReader, options: CrbmReaderOptions = {}): Promise<CrbmReader> {\n // Always fetch at least a footer's worth, regardless of a smaller caller request.\n const tailBytes = Math.max(options.tailBytes ?? DEFAULT_TAIL_BYTES, FOOTER_BYTES);\n const maxPayloadBytes = options.maxPayloadBytes ?? DEFAULT_MAX_PAYLOAD_BYTES;\n const maxIndexBytes = options.maxIndexBytes ?? DEFAULT_MAX_INDEX_BYTES;\n const { bytes: tail, size } = await blob.getTail(tailBytes);\n\n if (size < PREAMBLE_BYTES + FOOTER_BYTES || tail.length < FOOTER_BYTES) {\n throw new IntegrityError(`.crbm too small: ${size}B`);\n }\n\n // --- Footer (last 104 bytes of the tail) ---\n const footer = tail.subarray(tail.length - FOOTER_BYTES);\n if (!magicMatches(footer, FOOTER.endMagic)) {\n throw new IntegrityError('.crbm end magic mismatch');\n }\n const fview = new DataView(footer.buffer, footer.byteOffset, footer.byteLength);\n const storedFooterCrc = fview.getUint32(FOOTER.footerCrc32c, true);\n if (crc32c(footer.subarray(0, FOOTER_CRC_COVERAGE)) !== storedFooterCrc) {\n throw new IntegrityError('.crbm footer CRC mismatch');\n }\n const versionMajor = footer[FOOTER.versionMajor]!;\n if (versionMajor !== VERSION_MAJOR) {\n throw new UnsupportedError(`.crbm major version ${versionMajor} not supported`);\n }\n const flags = fview.getUint32(FOOTER.flags, true);\n const encrypted = (flags & FLAG_ENCRYPTED) !== 0;\n if (encrypted && options.crypto === undefined) {\n throw new ValidationError('.crbm is encrypted but no decryption key (crypto) was provided');\n }\n if ((flags & FLAG_LITTLE_ENDIAN) === 0) {\n throw new UnsupportedError('.crbm big-endian layout not supported (v1 is little-endian)');\n }\n if ((flags & ~KNOWN_FLAGS) !== 0) {\n throw new UnsupportedError(`.crbm has unknown flag bits set: 0x${flags.toString(16)}`);\n }\n\n // Payload-decoding contract (DECISIONS #34): the\n // reader must decode with the *same* element width, roaring serialization, and container codec the writer\n // stamped — a mismatch means the payloads are a format this v1 (32-bit, portable, uncompressed) reader can't\n // safely deserialize, so reject up front rather than feed them to the 32-bit deserializer and mis-count\n // fleet-wide. A 64-bit generation is the reserved >4.29 B-ids/segment escape and is a **major**-version bump\n // (auto-rejected here), never a silent minor one. All three fields are inside FOOTER_CRC_COVERAGE (verified).\n const elementWidth = footer[FOOTER.elementWidth]!;\n if (elementWidth !== ELEMENT_WIDTH_32) {\n throw new UnsupportedError(\n `.crbm element_width ${elementWidth} not supported (v1 reads 32-bit ids; 64-bit is a future major version)`,\n );\n }\n const serializationId = fview.getUint16(FOOTER.roaringSerializationId, true);\n if (serializationId !== ROARING_PORTABLE_ID) {\n throw new UnsupportedError(\n `.crbm roaring_serialization_id ${serializationId} not supported (v1 is portable=${ROARING_PORTABLE_ID})`,\n );\n }\n const containerCodec = footer[FOOTER.containerCodec]!;\n if (containerCodec !== CONTAINER_CODEC_NONE) {\n throw new UnsupportedError(\n `.crbm container_codec ${containerCodec} not supported (v1 defines only ${CONTAINER_CODEC_NONE}=none)`,\n );\n }\n\n const indexOffset = readU64(fview, FOOTER.indexOffset, 'index_offset');\n const indexLength = readU64(fview, FOOTER.indexLength, 'index_length');\n const indexCrc = fview.getUint32(FOOTER.indexCrc32c, true);\n const chunkCount = fview.getUint32(FOOTER.chunkCount, true);\n const totalCardinality = readU64(fview, FOOTER.totalCardinality, 'total_cardinality');\n const generation = readU64(fview, FOOTER.generation, 'generation');\n\n // Bounds + size cap on the index region before trusting/fetching it.\n if (indexOffset < PAYLOAD_START || indexOffset + indexLength > size - FOOTER_BYTES) {\n throw new IntegrityError(\n `.crbm index region [${indexOffset}, +${indexLength}) out of bounds`,\n );\n }\n if (indexLength > maxIndexBytes) {\n throw new IntegrityError(`.crbm index ${indexLength}B exceeds cap ${maxIndexBytes}B`);\n }\n\n // Validate the front preamble too, but only when this GET already covers it (no extra request).\n const tailCoversFrom = size - tail.length;\n if (tailCoversFrom === 0) {\n if (!magicMatches(tail, 0) || tail[4] !== versionMajor) {\n throw new IntegrityError('.crbm preamble magic/version mismatch with footer');\n }\n }\n\n // --- Index: already in the tail, or one more GET ---\n let indexBytes: Uint8Array;\n let servedFromTail: boolean;\n if (indexOffset >= tailCoversFrom) {\n const start = indexOffset - tailCoversFrom;\n indexBytes = tail.subarray(start, start + indexLength);\n servedFromTail = true;\n } else {\n indexBytes = await blob.getRange(indexOffset, indexLength);\n servedFromTail = false;\n }\n if (crc32c(indexBytes) !== indexCrc) {\n throw new IntegrityError('.crbm index CRC mismatch');\n }\n\n // Decrypt the index (nonce/tag from the footer) before parsing; AAD binds it to this (segment, generation).\n // A wrong key / tampered index / wrong context fails here as an IntegrityError — never a wrong parse.\n const indexForParse = encrypted\n ? options.crypto!.aead.open(\n {\n nonce: footer.subarray(FOOTER.indexNonce, FOOTER.indexNonce + AEAD_NONCE_BYTES),\n ciphertext: indexBytes,\n tag: footer.subarray(FOOTER.indexTag, FOOTER.indexTag + AEAD_TAG_BYTES),\n },\n options.crypto!.aadFor('index'),\n )\n : indexBytes;\n\n const { entries, orderedKeys, cardinalitySum } = parseIndex(\n indexForParse,\n size,\n maxPayloadBytes,\n );\n if (encrypted) {\n // Footer count/cardinality are zeroed on an encrypted object; the decrypted index is authoritative (and\n // already AEAD-authenticated, AAD-bound to this object), so derive the total from it.\n if (chunkCount !== 0 || totalCardinality !== 0) {\n throw new IntegrityError(\n '.crbm encrypted footer must zero chunk_count + total_cardinality',\n );\n }\n } else {\n // F2 (cleartext): the footer total + count must match the index — don't trust the footer blindly.\n if (entries.size !== chunkCount) {\n throw new IntegrityError(\n `.crbm chunk_count ${chunkCount} != ${entries.size} index entries`,\n );\n }\n if (cardinalitySum !== totalCardinality) {\n throw new IntegrityError(\n `.crbm total_cardinality ${totalCardinality} != Σ index cardinality ${cardinalitySum}`,\n );\n }\n }\n\n return new CrbmReader(\n blob,\n size,\n generation,\n cardinalitySum,\n entries,\n orderedKeys,\n servedFromTail,\n options.crypto,\n );\n }\n\n /** Chunk keys present in this generation, ascending. */\n chunkKeys(): number[] {\n return this.orderedKeys.slice();\n }\n\n /** Segment cardinality from the footer (no payload reads) — the cheap `count()` path. */\n count(): number {\n return this.totalCardinality;\n }\n\n has(chunkKey: number): boolean {\n return this.entries.has(chunkKey);\n }\n\n /**\n * Range-GET one chunk's payload, verifying its CRC32C before returning. Returns `null` if the chunk is\n * absent. Throws `IntegrityError` on a CRC mismatch (the bytes must never reach the native\n * deserializer). The returned buffer is a **read-only view** owned by the reader/driver — callers must\n * not mutate it.\n */\n async getChunk(chunkKey: number): Promise<Uint8Array | null> {\n const e = this.entries.get(chunkKey);\n if (e === undefined) return null;\n // Re-validate bounds at read time (defense in depth — a buggy caller or future mutable index path).\n if (e.offset < PAYLOAD_START || e.offset + e.length > this.objectSize - FOOTER_BYTES) {\n throw new IntegrityError(`chunk ${chunkKey} payload out of bounds`);\n }\n const bytes = await this.blob.getRange(e.offset, e.length);\n if (crc32c(bytes) !== e.crc32c) {\n throw new IntegrityError(`chunk ${chunkKey} payload CRC mismatch`);\n }\n if (this.crypto === undefined) return bytes;\n // Encrypted: on-disk frame is nonce ‖ ciphertext ‖ tag. Decrypt (AAD-bound to this chunkKey) after the CRC\n // passes — a wrong key / tamper / relocated chunk fails as an IntegrityError, never a wrong payload.\n if (bytes.length < AEAD_NONCE_BYTES + AEAD_TAG_BYTES) {\n throw new IntegrityError(`chunk ${chunkKey} encrypted payload too short`);\n }\n return this.crypto.aead.open(\n {\n nonce: bytes.subarray(0, AEAD_NONCE_BYTES),\n ciphertext: bytes.subarray(AEAD_NONCE_BYTES, bytes.length - AEAD_TAG_BYTES),\n tag: bytes.subarray(bytes.length - AEAD_TAG_BYTES),\n },\n this.crypto.aadFor(chunkKey),\n );\n }\n}\n\n// Exported for the coverage-guided fuzz harness (test-strategy T3), which fuzzes the hand-written index parser\n// directly on raw bytes — bypassing the CRC wall that mutational fuzzing can't cross. NOT part of the public\n// API surface (`src/index.ts`); reached only via `src/testing/fuzz-support.ts` → the gitignored `fuzz/build/`.\nexport function parseIndex(\n indexBytes: Uint8Array,\n objectSize: number,\n maxPayloadBytes: number,\n): { entries: Map<number, CrbmIndexEntry>; orderedKeys: number[]; cardinalitySum: number } {\n const entries = new Map<number, CrbmIndexEntry>();\n const orderedKeys: number[] = [];\n let pos = 0;\n let prevKey = 0;\n let prevEnd = PAYLOAD_START;\n let cardinalitySum = 0;\n\n // Parse entries until the index region is exactly consumed (chunk_count is hidden on encrypted objects, so\n // the byte length is the bound — readVarint throws on any overrun, so a malformed index fails cleanly).\n for (let i = 0; pos < indexBytes.length; i++) {\n const keyDelta = readVarint(indexBytes, pos);\n const offDelta = readVarint(indexBytes, keyDelta.next);\n const len = readVarint(indexBytes, offDelta.next);\n const card = readVarint(indexBytes, len.next);\n pos = card.next;\n if (pos + CRC32C_BYTES > indexBytes.length) {\n throw new IntegrityError('.crbm index truncated (missing payload CRC)');\n }\n const crc =\n (indexBytes[pos]! |\n (indexBytes[pos + 1]! << 8) |\n (indexBytes[pos + 2]! << 16) |\n (indexBytes[pos + 3]! << 24)) >>>\n 0;\n pos += CRC32C_BYTES;\n\n const chunkKey = prevKey + keyDelta.value;\n const offset = prevEnd + offDelta.value;\n // Unsigned deltas mean keys can only stay flat or rise; a 0 delta after the first is a duplicate.\n if (i > 0 && keyDelta.value === 0) {\n throw new IntegrityError(`.crbm index has a duplicate chunkKey ${chunkKey}`);\n }\n if (chunkKey > 0xffff) throw new IntegrityError(`.crbm chunkKey ${chunkKey} out of range`);\n if (len.value === 0 || len.value > maxPayloadBytes) {\n throw new IntegrityError(`.crbm chunk ${chunkKey} length ${len.value} invalid`);\n }\n if (card.value < 1 || card.value > MAX_CHUNK_CARDINALITY) {\n throw new IntegrityError(`.crbm chunk ${chunkKey} cardinality ${card.value} invalid`);\n }\n if (offset < PAYLOAD_START || offset + len.value > objectSize - FOOTER_BYTES) {\n throw new IntegrityError(`.crbm chunk ${chunkKey} payload out of bounds`);\n }\n\n entries.set(chunkKey, {\n chunkKey,\n offset,\n length: len.value,\n cardinality: card.value,\n crc32c: crc,\n });\n orderedKeys.push(chunkKey);\n cardinalitySum += card.value;\n prevKey = chunkKey;\n prevEnd = offset + len.value;\n }\n // The loop ends only when pos === indexBytes.length exactly (each entry consumes a whole record; a partial\n // trailing record makes readVarint or the CRC bound throw), so there are never unconsumed trailing bytes.\n return { entries, orderedKeys, cardinalitySum };\n}\n","/**\n * `CrbmWriter` — streaming, constant-memory writer for one immutable `.crbm` generation.\n *\n * Chunks are appended in **ascending chunkKey order**; the writer holds only the small index in memory\n * (offsets aren't known until payloads are written — which is exactly why the index is a footer).\n *\n * **Encryption (Phase 4e, opt-in via `crypto`).** When a {@link CrbmCrypto} is supplied, each chunk payload is\n * AES-256-GCM-sealed (`nonce ‖ ciphertext ‖ tag`, AAD = its chunkKey) and the whole index is sealed too (its\n * nonce/tag go in the footer). The footer then sets `FLAG_ENCRYPTED` and **zeroes `chunkCount` +\n * `totalCardinality`** so a leaked object reveals neither how many chunks nor how many ids it holds — the\n * reader derives both from the decrypted index. The per-chunk CRC covers the *encrypted* on-disk bytes.\n */\nimport { ValidationError } from '../errors';\nimport type { CrbmCrypto } from '../crypto';\nimport { crc32c } from './crc32c';\nimport { writeVarint } from './varint';\nimport type { BlobSink } from '../blob';\nimport {\n CONTAINER_CODEC_NONE,\n ELEMENT_WIDTH_32,\n FLAG_ENCRYPTED,\n FLAG_LITTLE_ENDIAN,\n FOOTER,\n FOOTER_BYTES,\n FOOTER_CRC_COVERAGE,\n MAGIC,\n MAX_CHUNK_CARDINALITY,\n PAYLOAD_START,\n PREAMBLE_BYTES,\n ROARING_PORTABLE_ID,\n VERSION_MAJOR,\n VERSION_MINOR,\n} from './format';\n\nexport interface CrbmWriterOptions {\n /** Self-describing generation number (also encoded in the object key). */\n readonly generation: number;\n readonly roaringSerializationId?: number;\n readonly elementWidth?: number;\n /** When set, payloads + index are AES-256-GCM-encrypted, bound to `(segment, generation, scope)` via AAD. */\n readonly crypto?: CrbmCrypto;\n}\n\ninterface IndexEntry {\n readonly chunkKey: number;\n readonly offset: number;\n readonly length: number;\n readonly cardinality: number;\n readonly crc32c: number;\n}\n\nexport class CrbmWriter {\n private readonly entries: IndexEntry[] = [];\n private offset = PAYLOAD_START;\n private lastKey = -1;\n private totalCardinality = 0;\n private preambleWritten = false;\n private finished = false;\n\n constructor(\n private readonly sink: BlobSink,\n private readonly options: CrbmWriterOptions,\n ) {\n if (!Number.isInteger(options.generation) || options.generation < 0) {\n throw new ValidationError(\n `generation must be a non-negative integer; got ${options.generation}`,\n );\n }\n }\n\n /**\n * Append one chunk's payload (the roaring-serialized bytes) with its cardinality. `chunkKey` must be\n * strictly greater than the previous one (ascending, no duplicates); `cardinality` is `[1, 65536]`.\n */\n async addChunk(chunkKey: number, payload: Uint8Array, cardinality: number): Promise<void> {\n if (this.finished) throw new ValidationError('CrbmWriter already finished');\n if (!Number.isInteger(chunkKey) || chunkKey < 0 || chunkKey > 0xffff) {\n throw new ValidationError(`chunkKey must be a u16; got ${chunkKey}`);\n }\n if (chunkKey <= this.lastKey) {\n throw new ValidationError(\n `chunkKey ${chunkKey} not strictly ascending (last ${this.lastKey})`,\n );\n }\n if (!Number.isInteger(cardinality) || cardinality < 1 || cardinality > MAX_CHUNK_CARDINALITY) {\n throw new ValidationError(\n `cardinality must be in [1, ${MAX_CHUNK_CARDINALITY}]; got ${cardinality}`,\n );\n }\n if (payload.length === 0) throw new ValidationError('chunk payload must be non-empty');\n\n await this.ensurePreamble();\n // Encrypt (if configured) to the on-disk bytes; the CRC + index length cover what actually lands on disk.\n const stored = this.options.crypto ? this.sealChunk(chunkKey, payload) : payload;\n await this.sink.write(stored);\n this.entries.push({\n chunkKey,\n offset: this.offset,\n length: stored.length,\n cardinality,\n crc32c: crc32c(stored),\n });\n this.offset += stored.length;\n this.totalCardinality += cardinality;\n this.lastKey = chunkKey;\n }\n\n /** Seal one chunk payload into the on-disk frame `nonce ‖ ciphertext ‖ tag`, bound to its chunkKey. */\n private sealChunk(chunkKey: number, payload: Uint8Array): Uint8Array {\n const crypto = this.options.crypto!;\n const sealed = crypto.aead.seal(payload, crypto.aadFor(chunkKey));\n const out = new Uint8Array(sealed.nonce.length + sealed.ciphertext.length + sealed.tag.length);\n out.set(sealed.nonce, 0);\n out.set(sealed.ciphertext, sealed.nonce.length);\n out.set(sealed.tag, sealed.nonce.length + sealed.ciphertext.length);\n return out;\n }\n\n /** Write the index region + the fixed footer. After this the object is complete and immutable. */\n async finish(): Promise<void> {\n if (this.finished) throw new ValidationError('CrbmWriter already finished');\n await this.ensurePreamble();\n\n const indexPlain = this.encodeIndex();\n // Encrypt the index too (its nonce/tag go in the footer); a leaked object then reveals no chunk metadata.\n let indexRegion = indexPlain;\n let indexNonce: Uint8Array | undefined;\n let indexTag: Uint8Array | undefined;\n if (this.options.crypto !== undefined) {\n const sealed = this.options.crypto.aead.seal(indexPlain, this.options.crypto.aadFor('index'));\n indexRegion = sealed.ciphertext;\n indexNonce = sealed.nonce;\n indexTag = sealed.tag;\n }\n const indexOffset = this.offset;\n await this.sink.write(indexRegion);\n this.offset += indexRegion.length;\n\n const footer = this.buildFooter(indexOffset, indexRegion, indexNonce, indexTag);\n await this.sink.write(footer);\n this.finished = true;\n }\n\n private async ensurePreamble(): Promise<void> {\n if (this.preambleWritten) return;\n const preamble = new Uint8Array(PREAMBLE_BYTES);\n preamble.set(MAGIC, 0);\n preamble[4] = VERSION_MAJOR;\n preamble[5] = VERSION_MINOR;\n // bytes 6-7 reserved = 0\n await this.sink.write(preamble);\n this.preambleWritten = true;\n }\n\n private encodeIndex(): Uint8Array {\n const out: number[] = [];\n let prevKey = 0;\n let prevEnd = PAYLOAD_START;\n for (const e of this.entries) {\n writeVarint(out, e.chunkKey - prevKey);\n writeVarint(out, e.offset - prevEnd);\n writeVarint(out, e.length);\n writeVarint(out, e.cardinality);\n // crc32c is high-entropy → fixed 4-byte LE, not varint.\n out.push(\n e.crc32c & 0xff,\n (e.crc32c >>> 8) & 0xff,\n (e.crc32c >>> 16) & 0xff,\n (e.crc32c >>> 24) & 0xff,\n );\n prevKey = e.chunkKey;\n prevEnd = e.offset + e.length;\n }\n return Uint8Array.from(out);\n }\n\n private buildFooter(\n indexOffset: number,\n indexRegion: Uint8Array,\n indexNonce: Uint8Array | undefined,\n indexTag: Uint8Array | undefined,\n ): Uint8Array {\n const encrypted = this.options.crypto !== undefined;\n const footer = new Uint8Array(FOOTER_BYTES);\n const view = new DataView(footer.buffer);\n view.setBigUint64(FOOTER.indexOffset, BigInt(indexOffset), true);\n view.setBigUint64(FOOTER.indexLength, BigInt(indexRegion.length), true);\n view.setUint32(FOOTER.indexCrc32c, crc32c(indexRegion), true);\n view.setUint32(FOOTER.flags, FLAG_LITTLE_ENDIAN | (encrypted ? FLAG_ENCRYPTED : 0), true);\n view.setUint16(\n FOOTER.roaringSerializationId,\n this.options.roaringSerializationId ?? ROARING_PORTABLE_ID,\n true,\n );\n footer[FOOTER.elementWidth] = this.options.elementWidth ?? ELEMENT_WIDTH_32;\n footer[FOOTER.containerCodec] = CONTAINER_CODEC_NONE;\n footer[FOOTER.versionMajor] = VERSION_MAJOR;\n footer[FOOTER.versionMinor] = VERSION_MINOR;\n // When encrypted, the index's AEAD nonce/tag live in these reserved slots; key_id stays zero (the wrapped\n // DEKs live in the registry, not the object). Unencrypted: all crypto fields stay zero.\n if (indexNonce !== undefined) footer.set(indexNonce, FOOTER.indexNonce);\n if (indexTag !== undefined) footer.set(indexTag, FOOTER.indexTag);\n view.setBigUint64(FOOTER.generation, BigInt(this.options.generation), true);\n // Hide chunk count + cardinality on an encrypted object (a leak reveals neither); the reader derives both\n // from the decrypted index. Cleartext objects keep them for the O(1) count()/validation path.\n view.setUint32(FOOTER.chunkCount, encrypted ? 0 : this.entries.length, true);\n view.setBigUint64(FOOTER.totalCardinality, BigInt(encrypted ? 0 : this.totalCardinality), true);\n view.setUint32(FOOTER.footerCrc32c, crc32c(footer.subarray(0, FOOTER_CRC_COVERAGE)), true);\n footer.set(MAGIC, FOOTER.endMagic);\n return footer;\n }\n}\n","/**\n * Bridges the `.crbm` archive format to the engine's Cold seam (decision 4).\n *\n * `CrbmColdChunkSource` implements the Phase-1 {@link ColdChunkSource} over an {@link IColdDriver}: it\n * pins a segment's latest generation, opens its {@link CrbmReader} once, and serves per-chunk payloads —\n * so the **engine is unchanged**, it just reads real on-disk generations now. `writeCrbmGeneration` is\n * the inverse seed primitive (a generation built from in-memory bitmaps), the basis for the Phase-3\n * bulk-load and Phase-4 compaction writers.\n */\nimport { type IAuditSink, NOOP_AUDIT, safeAudit } from './audit';\nimport {\n CapabilityError,\n KeyUnavailableError,\n ValidationError,\n WriteConflictError,\n isNotFoundError,\n isWriteConflictError,\n} from './errors';\nimport type { BlobReader } from './blob';\nimport type { Clock } from './determinism';\nimport { BoundedLru } from './lru';\nimport { splitId } from './bit-route';\nimport { segmentKey } from './keys';\nimport { aadFor } from './crypto';\nimport type { CrbmCrypto, IKeystore, WrappedDek } from './crypto';\nimport { validateChunkRef, validateSegmentRef } from './validate';\nimport type {\n ChunkRef,\n ColdChunkSource,\n GenKey,\n IColdDriver,\n IRegistryDriver,\n SegmentRef,\n SegmentSize,\n} from './ports';\nimport { CrbmReader } from './crbm/reader';\nimport type { CrbmReaderOptions } from './crbm/reader';\nimport { CrbmWriter } from './crbm/writer';\nimport type { CodecBitmap, CodecInterface } from './codec';\nimport { requireCodec } from './codec';\n\nexport interface CrbmColdChunkSourceOptions extends CrbmReaderOptions {\n /**\n * Optional {@link IRegistryDriver}. When provided, the current generation is resolved via the registry's\n * authoritative `currentGen` (one cheap strong read) instead of a `list` scan of every generation — the\n * Phase-4c retirement of that scan. When absent, the source falls back to the `list`-scan (so the\n * in-memory / simple setups keep working with no registry). The resolved generation is cached and\n * **re-resolved on a short TTL** ({@link currentGenTtlMs}, needs a {@link clock}) so a long-lived source\n * observes a compaction's new generation within the TTL instead of pinning one generation forever (gap #4).\n */\n readonly registry?: IRegistryDriver;\n /**\n * Optional {@link IKeystore} for reading **encrypted** segments (Phase 4e). When a segment's registry record\n * carries wrapped DEK(s), the source unwraps the DEK via this keystore and decrypts each chunk/index. Reading\n * an encrypted segment without a keystore throws {@link KeyUnavailableError}; cleartext segments ignore it.\n * Requires a `registry` (that's where the wrapped DEKs live).\n */\n readonly keystore?: IKeystore;\n /**\n * Enforce that every segment read is encrypted (Phase 4e). When true, resolving a **cleartext** segment (no\n * wrapped DEKs) throws {@link KeyUnavailableError} — a guard against silently reading a segment that should\n * have been encrypted. Off by default (encryption is opt-in).\n */\n readonly requireEncryption?: boolean;\n /**\n * Time source for the current-generation TTL refresh (gap #4) — the determinism seam; `core/` never reads\n * ambient time. Refresh needs **both** a clock and a `registry`; without either the source **pins** the\n * first-resolved generation for its lifetime (the pre-Phase-B behaviour). The `CloudRoaring` facade passes its\n * clock automatically, so wiring a `registry` is enough to get live cross-generation invalidation.\n */\n readonly clock?: Pick<Clock, 'now'>;\n /**\n * How long (ms) a resolved `currentGen` is trusted before the next read re-resolves it (default 2000) — the\n * bound on read staleness after a compaction: a reader may serve the prior generation for up to this long,\n * then converges. Lazy (checked on read — no timer); ≤ one cheap registry read per segment per window, and a\n * new {@link CrbmReader} is opened only when the generation actually changed. `0` (or no clock) ⇒ pin forever.\n */\n readonly currentGenTtlMs?: number;\n /**\n * Hard ceiling on how many segments' readers (each holding a fully-parsed `.crbm` index) are cached at once\n * (default 1024) — a memory bound for a long-running server (gap #1). Past it, the least-recently-used\n * segment's reader is evicted; the next read of an evicted segment re-opens it (one cheap tail GET, since\n * generations are immutable). Raise it for a big hot working set of small segments.\n */\n readonly maxOpenSegments?: number;\n /**\n * Aggregate byte ceiling on the parsed `.crbm` indices resident in the reader cache (default 64 MiB) — the\n * **second half of the gap #1 fix**. `maxOpenSegments` alone bounds by *count*, but a wide/dense segment's\n * parsed index can be several MB, so 1024 wide indices could pin ~GBs and blow a small heap (e.g. a 128 MB\n * Lambda) while the count is nominally \"in bounds\". This caps the summed {@link CrbmReader.retainedIndexBytes}\n * across cached readers; the least-recently-used reader is evicted once the total would exceed it — whichever\n * of the count/byte bounds binds first. Lower it for memory-tight deployments with wide segments; a single\n * segment whose index alone exceeds the budget is still cached (it can't be shrunk) but nothing else alongside.\n */\n readonly maxOpenIndexBytes?: number;\n}\n\n/** Adapt one `(driver, key)` pair to the codec's `BlobReader` seam. */\nfunction coldBlobReader(driver: IColdDriver, key: GenKey): BlobReader {\n return {\n getRange(offset, length) {\n return driver.getRange(key, offset, length);\n },\n getTail(maxBytes) {\n return driver.getTail(key, maxBytes);\n },\n };\n}\n\n/** The generation target `resolveTarget` produces: which generation is current + its DEK wrappings (if encrypted). */\ntype Target = { generation: number; wrappedDeks?: readonly WrappedDek[] };\n\n/** A memoized per-segment reader plus the time it was installed, for the current-generation TTL refresh (gap #4). */\ninterface Snapshot {\n readonly reader: Promise<CrbmReader | null>;\n readonly installedAtMs: number;\n}\n\n/** Default TTL (ms) for re-resolving a segment's `currentGen` — the bound on post-compaction read staleness. */\nconst DEFAULT_CURRENT_GEN_TTL_MS = 2000;\n\n/** Default ceiling on cached segment readers (each holds a parsed `.crbm` index) — the steady-state count bound. */\nconst DEFAULT_MAX_OPEN_SEGMENTS = 1024;\n\n/** Default aggregate ceiling (bytes) on resident parsed indices in the reader cache — the steady-state byte bound. */\nconst DEFAULT_MAX_OPEN_INDEX_BYTES = 64 * 1024 * 1024;\n\nexport class CrbmColdChunkSource implements ColdChunkSource {\n /**\n * One resolved reader per segment, re-resolved on a short TTL ({@link CrbmColdChunkSourceOptions.currentGenTtlMs},\n * needs a clock). Within the TTL a segment's Cold bytes are treated as an immutable snapshot; when the TTL\n * elapses the next read cheaply re-resolves `currentGen` and, only if it advanced (a compaction committed),\n * opens the new generation — so a long-lived source observes new generations within the TTL rather than\n * pinning one forever (gap #4). The engine pairs this with a **generation-keyed** HOT cache so a bump never\n * serves a stale decoded chunk. Without a clock or a registry the source pins the first generation for its\n * lifetime (pre-Phase-B behaviour). A segment with no generation yet is not memoized, so it's re-checked until\n * one exists. **Bounded** by a {@link BoundedLru} ({@link CrbmColdChunkSourceOptions.maxOpenSegments}, default\n * 1024): past the ceiling the least-recently-used segment's reader (and its parsed index) is evicted — the\n * steady-state memory bound (gap #1); re-opening an evicted segment is one cheap tail GET.\n */\n private readonly snapshots: BoundedLru<string, Snapshot>;\n private readonly registry: IRegistryDriver | undefined;\n private readonly keystore: IKeystore | undefined;\n private readonly requireEncryption: boolean;\n private readonly readerOptions: CrbmReaderOptions;\n private readonly clock: Pick<Clock, 'now'> | undefined;\n private readonly currentGenTtlMs: number;\n\n constructor(\n private readonly driver: IColdDriver,\n options: CrbmColdChunkSourceOptions = {},\n ) {\n if (!driver.capabilities().rangeRead) {\n throw new CapabilityError('Cold driver must support range reads (rangeRead)');\n }\n const {\n registry,\n keystore,\n requireEncryption,\n clock,\n currentGenTtlMs,\n maxOpenSegments,\n maxOpenIndexBytes,\n ...readerOptions\n } = options;\n if (keystore !== undefined && registry === undefined) {\n throw new CapabilityError(\n 'a keystore needs a registry (that is where wrapped DEKs are stored)',\n );\n }\n if (requireEncryption === true && registry === undefined) {\n // Without a registry the source can't see wrapped DEKs or `destroyed` tombstones (it list-scans cold),\n // so encryption can't be enforced or even observed here — fail fast rather than mislead.\n throw new CapabilityError('requireEncryption needs a registry');\n }\n this.registry = registry;\n this.keystore = keystore;\n this.requireEncryption = requireEncryption ?? false;\n this.readerOptions = readerOptions;\n this.clock = clock;\n this.currentGenTtlMs = currentGenTtlMs ?? DEFAULT_CURRENT_GEN_TTL_MS;\n // Bound the reader cache by BOTH count and aggregate parsed-index bytes (gap #1). No TTL on the LRU itself —\n // the currentGen TTL is handled separately via each snapshot's `installedAtMs`; these ceilings only bound how\n // many segment readers/indices stay resident. Each reader's byte weight is reported once it resolves (below).\n // The cache never compares against wall-clock, so a zero clock is fine when none is injected.\n this.snapshots = new BoundedLru<string, Snapshot>({\n maxEntries: maxOpenSegments ?? DEFAULT_MAX_OPEN_SEGMENTS,\n maxBytes: maxOpenIndexBytes ?? DEFAULT_MAX_OPEN_INDEX_BYTES,\n clock: clock ?? { now: () => 0 },\n });\n }\n\n /** The current resolved reader for a segment, refreshing on the TTL (gap #4). Cheap within the TTL window. */\n private resolvedReader(ref: SegmentRef): Promise<CrbmReader | null> {\n const key = segmentKey(ref);\n const existing = this.snapshots.get(key);\n if (existing === undefined) return this.install(key, this.resolveLatest(ref)).reader;\n if (!this.expired(existing.installedAtMs)) return existing.reader;\n // Expired: install the in-flight refresh **synchronously** (before any await) so concurrent readers in this\n // window coalesce onto the one re-resolve — ≤ one registry read + at most one reopen per segment per window\n // (no boundary thundering-herd). computeRefreshedReader reuses the prior reader unless the generation moved.\n return this.install(key, this.computeRefreshedReader(ref, existing)).reader;\n }\n\n /** TTL elapsed: cheaply re-resolve `currentGen`; reopen only if it actually changed, else reuse the prior reader. */\n private async computeRefreshedReader(\n ref: SegmentRef,\n existing: Snapshot,\n ): Promise<CrbmReader | null> {\n const current = await existing.reader.catch(() => null);\n let target: Target | null | undefined;\n try {\n target = await this.resolveTarget(ref);\n } catch {\n target = undefined; // transient resolve fault\n }\n // Transient resolve fault: keep serving the prior reader if it's alive; if it's dead (null/failed open),\n // reopen rather than re-arm a dead snapshot (else the segment reads empty for a whole TTL window).\n if (target === undefined) return current ?? this.resolveLatest(ref);\n if (target === null) return null; // segment gone / destroyed\n if (current !== null && target.generation === current.generation) return current; // unchanged — reuse\n return this.openForTarget(ref, target); // advanced / appeared / prior open was dead — reopen fresh\n }\n\n /**\n * Memoize a reader-promise as the segment's snapshot at `now()`, forgetting it later if it resolves to\n * null / throws (identity-guarded, so a stale cleanup never clobbers a fresher snapshot). Installing the\n * (pending) promise **synchronously** is what lets concurrent callers coalesce onto one in-flight resolve.\n */\n private install(key: string, reader: Promise<CrbmReader | null>): Snapshot {\n const snap: Snapshot = { reader, installedAtMs: this.now() };\n this.snapshots.set(key, snap);\n const forgetIfStale = (): void => {\n if (this.snapshots.get(key) === snap) this.snapshots.delete(key);\n };\n reader.then((r) => {\n if (r === null) {\n forgetIfStale();\n return;\n }\n // Report the parsed index's footprint so the cache can bound aggregate resident bytes (gap #1). Identity-\n // guarded via `peek` (no recency change) so a since-replaced snapshot doesn't mis-weight the fresh entry.\n if (this.snapshots.peek(key) === snap) this.snapshots.setWeight(key, r.retainedIndexBytes);\n }, forgetIfStale);\n return snap;\n }\n\n private now(): number {\n return this.clock ? this.clock.now() : 0;\n }\n\n private expired(installedAtMs: number): boolean {\n // Refresh needs a clock (the TTL) AND a registry (the *cheap* `currentGen` read the design assumes —\n // without one, re-resolution is a full cold `list`-scan, and a registry-less setup is single-process\n // local, not the separate-daemon Topology-B where stale reads arise). Otherwise: pin for the lifetime.\n return (\n this.clock !== undefined &&\n this.registry !== undefined &&\n this.currentGenTtlMs > 0 &&\n this.clock.now() - installedAtMs >= this.currentGenTtlMs\n );\n }\n\n /**\n * The segment's current generation number (gap #4) — the engine keys its HOT chunk cache by this so a\n * compaction bump is observed instead of serving a stale decoded chunk. Served from the (TTL-refreshed)\n * snapshot, so no extra backend read within the TTL window. `null` if the segment has no committed generation.\n */\n async currentGeneration(ref: SegmentRef): Promise<number | null> {\n const reader = await this.resolvedReader(ref);\n return reader?.generation ?? null;\n }\n\n private async resolveLatest(ref: SegmentRef): Promise<CrbmReader | null> {\n const target = await this.resolveTarget(ref);\n if (target === null) return null;\n return this.openForTarget(ref, target);\n }\n\n /** Open a {@link CrbmReader} for an already-resolved generation target (decrypting if the segment is encrypted). */\n private async openForTarget(ref: SegmentRef, target: Target): Promise<CrbmReader | null> {\n const genKey: GenKey = {\n namespace: ref.namespace,\n segment: ref.segment,\n generation: target.generation,\n };\n const crypto = await this.cryptoForRead(ref, target.generation, target.wrappedDeks);\n return CrbmReader.open(coldBlobReader(this.driver, genKey), { ...this.readerOptions, crypto });\n }\n\n /**\n * The current generation + its DEK wrappings: the registry's authoritative record (one strong read), or a\n * `list` scan for the max generation when there's no registry (a registry-less source can only read cleartext\n * — there's nowhere a wrapped DEK could live).\n */\n private async resolveTarget(ref: SegmentRef): Promise<Target | null> {\n if (this.registry !== undefined) {\n const record = await this.registry.get(ref);\n if (record === null) return null;\n // A crypto-shredded segment reads as empty — its DEK is gone, so its Cold bytes are unrecoverable.\n if (record.status === 'destroyed') return null;\n return { generation: record.currentGen, wrappedDeks: record.wrappedDeks };\n }\n let maxGen = -1;\n for await (const key of this.driver.list(ref)) {\n if (key.generation > maxGen) maxGen = key.generation;\n }\n return maxGen < 0 ? null : { generation: maxGen };\n }\n\n /** Build the per-generation decryption context for an encrypted segment (undefined for cleartext). */\n private async cryptoForRead(\n ref: SegmentRef,\n generation: number,\n wrappedDeks: readonly WrappedDek[] | undefined,\n ): Promise<CrbmCrypto | undefined> {\n if (wrappedDeks === undefined || wrappedDeks.length === 0) {\n if (this.requireEncryption) {\n throw new KeyUnavailableError(\n `requireEncryption: segment \"${ref.segment}\" is cleartext but encryption is required`,\n );\n }\n return undefined; // cleartext segment\n }\n if (this.keystore === undefined) {\n throw new KeyUnavailableError(\n `segment \"${ref.segment}\" is encrypted but this CrbmColdChunkSource has no keystore`,\n );\n }\n const aead = await this.keystore.openDek(wrappedDeks);\n return { aead, aadFor: (scope) => aadFor(ref, generation, scope) };\n }\n\n async getChunk(ref: ChunkRef): Promise<Uint8Array | null> {\n validateChunkRef(ref);\n return this.withFreshSnapshot(ref, (reader) => reader.getChunk(ref.chunkKey), null);\n }\n\n async listChunkKeys(ref: SegmentRef): Promise<number[]> {\n validateSegmentRef(ref);\n return this.withFreshSnapshot(ref, (reader) => reader.chunkKeys(), []);\n }\n\n async sizeOf(ref: SegmentRef): Promise<SegmentSize | null> {\n validateSegmentRef(ref);\n return this.withFreshSnapshot<SegmentSize | null>(\n ref,\n (reader) => ({ sizeBytes: reader.sizeBytes }),\n null,\n );\n }\n\n async cardinalities(ref: SegmentRef): Promise<ReadonlyMap<number, number> | null> {\n validateSegmentRef(ref);\n return this.withFreshSnapshot<ReadonlyMap<number, number> | null>(\n ref,\n (reader) => reader.cardinalities(),\n null,\n );\n }\n\n /**\n * Run `read` against the pinned snapshot, healing the one torn-read window compaction's GC can open: if the\n * generation we pinned was superseded *and* swept (the grace window elapsed) mid-read, the Cold driver throws\n * {@link NotFoundError}. Rather than surface that as a query failure (**I5**), we drop the stale snapshot,\n * re-resolve `currentGen`, and retry once — the read then serves the newer (committed, immutable) generation,\n * a monotonic move forward. A *second* NotFound is pathological (GC outrunning resolution) and propagates\n * rather than fabricate an absent answer — never return a wrong result. `ifGone` is returned only when the\n * segment legitimately has no committed generation at all (cold is empty). The single retry is bounded.\n */\n private async withFreshSnapshot<T>(\n ref: SegmentRef,\n read: (reader: CrbmReader) => T | Promise<T>,\n ifGone: T,\n ): Promise<T> {\n const key = segmentKey(ref);\n for (let attempt = 0; attempt < 2; attempt++) {\n const pending = this.resolvedReader(ref);\n const reader = await pending;\n if (reader === null) return ifGone;\n try {\n return await read(reader);\n } catch (err) {\n // Only a vanished pinned generation is recoverable here, and only on the first try; anything else\n // (corruption, a real second miss) propagates / falls through.\n if (!isNotFoundError(err) || attempt === 1) throw err;\n // Force re-resolution to the current generation — but only evict the exact stale snapshot we just read\n // from (matched by its reader promise), so we don't clobber a fresher one a concurrent call installed.\n const cur = this.snapshots.get(key);\n if (cur !== undefined && cur.reader === pending) this.snapshots.delete(key);\n }\n }\n return ifGone;\n }\n}\n\n/**\n * Write one immutable generation from in-memory bitmaps (the seed / bulk-load primitive). Chunks are\n * sorted ascending and empty bitmaps skipped (empty chunks are never stored). Returns the driver's\n * `{ size, sha256 }` for the written object. Pass `options.crypto` to AES-256-GCM-encrypt the generation\n * (the caller builds it from the segment's DEK + a `(segment, generation)`-bound {@link aadFor}).\n */\nexport function writeCrbmGeneration(\n driver: IColdDriver,\n key: GenKey,\n chunks: Iterable<{ chunkKey: number; bitmap: CodecBitmap }>,\n options: { crypto?: CrbmCrypto } = {},\n): Promise<{ size: number; sha256: string }> {\n const sorted = [...chunks].sort((a, b) => a.chunkKey - b.chunkKey);\n return driver.putImmutable(key, async (sink) => {\n const writer = new CrbmWriter(sink, { generation: key.generation, crypto: options.crypto });\n for (const { chunkKey, bitmap } of sorted) {\n if (bitmap.isEmpty) continue;\n await writer.addChunk(chunkKey, bitmap.serialize(), bitmap.size);\n }\n await writer.finish();\n });\n}\n\n/** What {@link writeCrbmGenerationStream} wrote: the driver's `{ size, sha256 }` + a tally of the generation. */\nexport interface StreamWriteResult {\n readonly size: number;\n readonly sha256: string;\n /** Non-empty chunk keys written, in ascending order (for the compaction verify, since the stream is consumed). */\n readonly chunkKeys: number[];\n /** Total ids written. */\n readonly cardinality: number;\n}\n\n/**\n * Streaming variant of {@link writeCrbmGeneration} for **constant-memory** compaction (Phase 4f): consumes an\n * **already-ascending** async stream of `{ chunkKey, bitmap }`, feeding each to the codec and freeing it,\n * instead of materializing the whole generation. Paired with a streaming cold sink (S3 multipart / LocalFs temp\n * file), peak memory is ~one chunk + one part. Returns a tally so the caller can verify the re-opened object\n * without re-iterating the (now-consumed) stream. Input **must** be ascending by `chunkKey` — the codec rejects\n * an out-of-order chunk; empty bitmaps are skipped.\n */\nexport async function writeCrbmGenerationStream(\n driver: IColdDriver,\n key: GenKey,\n chunks: AsyncIterable<{ chunkKey: number; bitmap: CodecBitmap }>,\n options: { crypto?: CrbmCrypto } = {},\n): Promise<StreamWriteResult> {\n const chunkKeys: number[] = [];\n let cardinality = 0;\n const { size, sha256 } = await driver.putImmutable(key, async (sink) => {\n const writer = new CrbmWriter(sink, { generation: key.generation, crypto: options.crypto });\n for await (const { chunkKey, bitmap } of chunks) {\n if (bitmap.isEmpty) continue;\n await writer.addChunk(chunkKey, bitmap.serialize(), bitmap.size);\n chunkKeys.push(chunkKey);\n cardinality += bitmap.size;\n }\n await writer.finish();\n });\n return { size, sha256, chunkKeys, cardinality };\n}\n\n/**\n * Point a segment's registry `currentGen` at `key.generation` — the publish step that makes a freshly-written\n * generation the authoritative latest (so registry-aware readers see it). **Forward-only and idempotent:**\n * if the registry has no row it creates one; if it's already at/ahead of `key.generation` it's a no-op (an\n * out-of-order/duplicate publish never regresses the pointer); otherwise it advances via compare-and-swap,\n * retrying a few times under contention. Separated from the Cold write so callers can publish atomically\n * after the immutable object is durable (write-then-publish).\n */\nexport async function publishGeneration(\n registry: IRegistryDriver,\n key: GenKey,\n options: { wrappedDeks?: readonly WrappedDek[] } = {},\n): Promise<boolean> {\n for (let attempt = 0; attempt < 5; attempt++) {\n const record = await registry.get(key);\n try {\n if (record === null) {\n // First publish for the segment — carry the wrapped DEK(s) so encrypted reads can resolve the key.\n await registry.create(key, {\n currentGen: key.generation,\n wrappedDeks: options.wrappedDeks,\n });\n } else if (record.currentGen > key.generation) {\n return false; // a newer generation is already current — forward-only, never regress\n } else if (record.currentGen === key.generation) {\n return true; // already exactly current (an idempotent re-publish) — nothing to advance\n } else {\n await registry.compareAndSwap(key, record.token, { currentGen: key.generation });\n }\n return true; // created or advanced the pointer to key.generation → it is now current\n } catch (err) {\n if (isWriteConflictError(err)) continue; // lost the race — re-read and retry\n throw err;\n }\n }\n // Exhausted: only possible if competing writers kept advancing currentGen — which likely already satisfies\n // the forward-only goal. Confirm before reporting failure, so a lost-every-race-but-already-current case\n // isn't a spurious error. Whether *this* generation is the current one decides the returned flag.\n const final = await registry.get(key);\n if (final !== null && final.currentGen >= key.generation)\n return final.currentGen === key.generation;\n throw new WriteConflictError(\n `publishGeneration: contention setting currentGen for ${key.segment}`,\n );\n}\n\n/** What a bulk-load wrote — the driver's `{ size, sha256 }` plus a summary of the built generation. */\nexport interface BulkLoadResult {\n /** Bytes written to the Cold object. */\n readonly size: number;\n /** The driver's content hash of the object. */\n readonly sha256: string;\n /** Distinct non-empty chunks written (≤ 65536). */\n readonly chunkCount: number;\n /** Total distinct ids in the generation (post-dedup). */\n readonly cardinality: number;\n}\n\n/**\n * **Bulk-load** a whole immutable generation from a flat id source — the batch \"seed/sweep\" entry point.\n * Unlike {@link writeCrbmGeneration} (which takes pre-grouped bitmaps), this\n * consumes an arbitrary, **unsorted** stream of u32 ids (sync or async) and routes each into its chunk's\n * Roaring bitmap as it goes. The input is consumed lazily and ids dedup on insert, so memory is bounded by\n * the **built generation** — the in-memory Roaring representation of the *distinct* set (≤ one bitmap per\n * non-empty chunk) — not by the input length: you can stream a billion duplicate-heavy ids and hold only the\n * distinct result. Note this is `O(distinct set)`, **not** window-bounded like {@link SegmentEngine.intersect}:\n * bulk-load holds the whole generation in RAM, which suits batch seed/sweep jobs but not an\n * unbounded-cardinality stream (a segment larger than RAM needs external-merge / pre-sorted input — later phase).\n *\n * Each id must be an integer in `[0, 2³²)` ({@link splitId} throws {@link ValidationError} otherwise) — the\n * source is consumed lazily, so a bad id aborts mid-stream without writing a partial object (the driver\n * commits only after the callback resolves). An empty source writes a valid empty generation.\n *\n * Writing a fresh full snapshot of a segment; merging a new delta into the *existing* Cold (compaction) is\n * Phase 4. The caller picks the generation number in `key` and a `ColdChunkSource` serves the **highest**, so\n * pick a known-fresh number (on an empty segment, `0`): a too-high number silently shadows real data, and\n * re-using an existing generation throws {@link WriteConflictError} (write-once). Registry-assigned\n * generations arrive in Phase 4.\n */\nexport async function bulkLoadCrbmGeneration(\n driver: IColdDriver,\n key: GenKey,\n ids: Iterable<number> | AsyncIterable<number>,\n options: {\n registry?: IRegistryDriver;\n keystore?: IKeystore;\n requireEncryption?: boolean;\n audit?: IAuditSink;\n /** Bitmap codec ([DECISIONS #58]). Optional in the type; a **flavor** package binds it ({@link requireCodec}). */\n codec?: CodecInterface;\n } = {},\n): Promise<BulkLoadResult> {\n if (options.keystore === undefined && options.requireEncryption === true) {\n throw new ValidationError('requireEncryption: bulk-load needs a keystore to write encrypted');\n }\n const codec = requireCodec(options.codec, 'bulkLoadCrbmGeneration');\n const byChunk = new Map<number, CodecBitmap>();\n for await (const id of toAsyncIterable(ids)) {\n const { chunkKey, remainder } = splitId(id); // validates the u32 range\n let bitmap = byChunk.get(chunkKey);\n if (bitmap === undefined) {\n bitmap = codec.empty();\n byChunk.set(chunkKey, bitmap);\n }\n bitmap.add(remainder);\n }\n\n let cardinality = 0;\n const chunks: Array<{ chunkKey: number; bitmap: CodecBitmap }> = [];\n for (const [chunkKey, bitmap] of byChunk) {\n // Every chunk in the map received at least one id, so no bitmap here is empty.\n cardinality += bitmap.size;\n chunks.push({ chunkKey, bitmap });\n }\n\n if (options.keystore !== undefined && options.registry === undefined) {\n throw new ValidationError('bulk-load encryption requires a registry to store the wrapped DEK');\n }\n // Read the segment's record once (when a registry is wired): to refuse writing to a crypto-shredded segment\n // (which would create unreadable/unreachable bytes), and to reuse its DEK if it's encrypted.\n const existing = options.registry !== undefined ? await options.registry.get(key) : null;\n if (existing?.status === 'destroyed') {\n throw new ValidationError(\n `segment \"${key.segment}\" is destroyed (crypto-shredded) — refusing to write; use a new segment`,\n );\n }\n\n // Encryption (opt-in): reuse the segment's existing DEK, or mint a fresh one on first write.\n let crypto: CrbmCrypto | undefined;\n let newWrapped: readonly WrappedDek[] | undefined;\n if (options.keystore !== undefined) {\n if (existing?.wrappedDeks !== undefined && existing.wrappedDeks.length > 0) {\n const aead = await options.keystore.openDek(existing.wrappedDeks); // reuse the segment's DEK\n crypto = { aead, aadFor: (scope) => aadFor(key, key.generation, scope) };\n } else {\n const minted = await options.keystore.createDek();\n newWrapped = minted.wrapped;\n crypto = { aead: minted.aead, aadFor: (scope) => aadFor(key, key.generation, scope) };\n }\n }\n\n const { size, sha256 } = await writeCrbmGeneration(driver, key, chunks, { crypto });\n // Publish only after the immutable object is durable (write-then-publish): a registry-aware reader should\n // never point at a generation that isn't fully written. A freshly minted DEK is stored on this publish.\n if (options.registry !== undefined) {\n const becameCurrent = await publishGeneration(options.registry, key, {\n wrappedDeks: newWrapped,\n });\n // Audit the publish only when this generation actually *became* the current one — not when a\n // forward-only publish no-oped because a newer generation was already current (the event's contract is\n // \"became the segment's current generation\"). Needs a registry to have a \"current generation\" at all.\n if (becameCurrent) {\n safeAudit(options.audit ?? NOOP_AUDIT).onEvent({\n kind: 'segment.publish',\n namespace: key.namespace,\n segment: key.segment,\n generation: key.generation,\n });\n }\n }\n return { size, sha256, chunkCount: chunks.length, cardinality };\n}\n\n/** Normalize a sync-or-async iterable into an async one (so the loader streams either input). */\nasync function* toAsyncIterable<T>(src: Iterable<T> | AsyncIterable<T>): AsyncGenerator<T> {\n if (Symbol.asyncIterator in src) {\n yield* src as AsyncIterable<T>;\n } else {\n yield* src as Iterable<T>;\n }\n}\n","/**\n * Crash-safe compaction — the 2-phase commit that folds Warm deltas into a fresh immutable Cold generation\n * (invariants I3/I4/I5).\n *\n * Memory (Phase 4f): a generation is merged **and written as a stream** — {@link mergeChunksStream} yields one\n * merged chunk at a time and {@link writeCrbmGenerationStream} feeds each to a streaming cold sink (S3 multipart\n * / LocalFs temp file), freeing it. The cold generation is merged and written as a stream, so peak COLD-side\n * memory is ~one chunk + one upload part + the cold reader's index. Caveat: `collectDirty` first materializes\n * the whole dirty Warm delta set in memory, so total peak also scales with the dirty-warm working set (up to a\n * whole segment for an all-warm/never-compacted segment) — pinning only `{chunkKey,token}` + lazy re-read is a\n * deferred fix (gap #12).\n *\n * The algorithm, per chunk: `newCold(k) = (cold_g(k) ∪ adds(k)) \\ removes(k)` — exactly the read-time\n * effective set ({@link effective}), so the segment's visible set is unchanged (**I3**). Steps:\n *\n * 1. LEASE acquire the per-segment compaction lease (status→compacting; steal an expired one)\n * 2. PIN g := registry.currentGen; archive each dirty chunk's OCC token (`v_archived`)\n * 3. RECONCILE delete orphan Cold generations > g (a crashed prior stage), safe under the lease\n * 4. MERGE build gen g+1: dirty chunks merged, clean chunks copied through\n * 5. STAGE write segment.<g+1>.crbm (immutable, write-once)\n * 6. VERIFY re-open it; its chunk-key set + footer cardinality must equal the merge (+ the codec's CRC checks)\n * 7. SWAP registry.currentGen := g+1, release the lease — CONDITIONAL on the lease token (atomic commit)\n * 8. PURGE delete each archived Warm row CONDITIONAL on token == v_archived (a write after the scan has a\n * newer token → its purge fails → it survives into the next dirty set: **no lost writes, I4**)\n *\n * **Correctness without a lock:** the commit is the conditional `currentGen` swap; write-once generations +\n * version-fenced purge make even two concurrent compactions safe (the loser's staged generation is an orphan\n * GC'd later; no torn read — readers are pinned to a committed generation, **I5**). The lease only avoids that\n * wasted duplicate work (see DECISIONS #18).\n *\n * Pure orchestration over the injected driver interfaces + an injected {@link Clock} (timer-free; the daemon\n * layer owns scheduling/heartbeat). A crash at *any* step is recoverable: nothing is destructive until after\n * the commit, and the swap is atomic.\n */\nimport { type IAuditSink, NOOP_AUDIT, safeAudit } from './audit';\nimport type { CodecBitmap, CodecInterface } from './codec';\nimport { requireCodec } from './codec';\nimport { decodeDelta, effective, emptyDelta } from './chunk';\nimport type { ChunkDelta } from './chunk';\nimport type { BlobReader } from './blob';\nimport type { Clock } from './determinism';\nimport type { IMetricsSink } from './metrics';\nimport {\n KeyUnavailableError,\n ValidationError,\n WriteConflictError,\n isWriteConflictError,\n} from './errors';\nimport { segmentKey } from './keys';\nimport { aadFor } from './crypto';\nimport type { Aead, CrbmCrypto, IKeystore, WrappedDek } from './crypto';\nimport { writeCrbmGenerationStream } from './crbm-cold-source';\nimport { CrbmReader } from './crbm/reader';\nimport type {\n ChunkRef,\n GenKey,\n IColdDriver,\n IRegistryDriver,\n IWarmDriver,\n SegmentRef,\n Token,\n} from './ports';\n\nconst DEFAULT_MAX_BITMAP_BYTES = 1 << 20;\n/** Default compaction-lease duration. Generous: a compaction longer than this risks being stolen (safe — the\n * commit is fenced on the lease token — but wasteful). The daemon layer can renew (heartbeat) for big segments. */\nconst DEFAULT_LEASE_MS = 60_000;\n/** Default consecutive-failure count at/after which discovery quarantines (skips) a poison segment (gap #2). */\nconst DEFAULT_QUARANTINE_THRESHOLD = 5;\n/** Default cooldown before a quarantined segment is retried once, so a transient fault can self-heal (gap #2). */\nconst DEFAULT_QUARANTINE_COOLDOWN_MS = 5 * 60_000;\n\nexport interface CompactionDeps {\n readonly cold: IColdDriver;\n readonly warm: IWarmDriver;\n readonly registry: IRegistryDriver;\n /** Injected time source for lease expiry (the determinism seam — `core/` never reads ambient time). */\n readonly clock: Pick<Clock, 'now'>;\n readonly maxBitmapBytes?: number;\n /**\n * Bitmap codec ([DECISIONS #58]) — compaction only merges bitmaps through it. Optional in the type so this\n * stays call-compatible public API; a **flavor** package binds it (see {@link requireCodec}).\n */\n readonly codec?: CodecInterface;\n /**\n * Keystore for **encrypted** segments (Phase 4e). An encrypted segment (its registry record carries wrapped\n * DEK(s)) reuses that same DEK: compaction unwraps it to decrypt the old generation and encrypt the new one.\n * A bootstrap (gen 0) with a keystore mints a fresh DEK. Compacting an encrypted segment without a keystore\n * throws {@link KeyUnavailableError}. Absent ⇒ cleartext compaction (unless {@link requireEncryption}).\n */\n readonly keystore?: IKeystore;\n /** When true, refuse to write a cleartext generation — a segment without a keystore-backed DEK throws. */\n readonly requireEncryption?: boolean;\n /**\n * Optional observability sink (Phase D, gap #2). `compactSegment` emits one `compaction` event per attempt\n * (committed or not, timed). Assumed exception-safe (the `CloudRoaring` facade wraps the user sink); the emit\n * is additionally guarded so a throwing sink can never break compaction. Absent ⇒ no emission.\n */\n readonly metrics?: IMetricsSink;\n}\n\nexport interface CompactionOptions {\n /** Opaque id of this worker — the lease owner (e.g. `host:pid:uuid`). Required so a steal is attributable. */\n readonly owner: string;\n /** Lease duration in ms (default 60s). */\n readonly leaseMs?: number;\n /**\n * Optional audit sink (Phase 5d). A `segment.compact` event is emitted once per **committed** generation\n * (never on a no-op/contention path). Exception-safe; the default records nothing.\n */\n readonly audit?: IAuditSink;\n}\n\nexport interface CompactionResult {\n readonly segment: string;\n readonly namespace?: string;\n /** True iff a new generation was committed. */\n readonly compacted: boolean;\n /**\n * Why nothing was committed, when `compacted` is false: `'clean'` (no dirty rows), `'leased-by-other'`\n * (a live lease elsewhere), `'lease-lost'` (our lease was stolen before the commit — staged gen is an\n * orphan, no rows purged), `'superseded'` (a concurrent publish/bulk-load advanced `currentGen` past the\n * generation we pinned — we abort so RECONCILE never deletes the just-published generation; the next cycle\n * re-pins the new current gen; gap #5), `'bootstrap-raced'` (another worker wrote gen 0; our rows are left\n * for the next compaction), `'stage-conflict'` (a generation write-conflict we couldn't reconcile),\n * `'destroyed'` (the segment was crypto-shredded — terminal), or `'error'` (an isolated per-segment fault\n * recorded by {@link runCompactionCycle}).\n */\n readonly reason?: string;\n /** The fault message when `reason === 'error'` (a per-segment failure isolated by {@link runCompactionCycle}). */\n readonly error?: string;\n readonly fromGen: number | null;\n readonly toGen?: number;\n readonly dirtyChunks: number;\n /** Archived Warm rows actually purged (≤ dirtyChunks; the rest were rewritten post-scan and survive). */\n readonly purged: number;\n readonly survived: number;\n}\n\n/** A dirty chunk pinned at scan time: its merged delta + the OCC token to fence its purge against. */\ninterface PinnedChunk {\n readonly chunkKey: number;\n readonly delta: ChunkDelta;\n readonly token: Token;\n}\n\n/**\n * Fail fast on bad lease config at the boundary: an empty owner makes a lease steal unattributable, and a\n * non-positive/NaN leaseMs would produce a lease that's already expired (or never), silently defeating the\n * lease's whole job. Cheap to check once, up front, so a misconfigured daemon errors immediately. Exported so\n * callers that mutate **before** compacting (e.g. `CloudRoaring.eraseSubject`, which writes a `remove` tombstone\n * first) can validate the options up front rather than after the tombstone is written.\n */\nexport function validateCompactionOptions(options: CompactionOptions): void {\n if (typeof options.owner !== 'string' || options.owner.length === 0) {\n throw new ValidationError(\n 'compaction: options.owner must be a non-empty string (the lease owner id)',\n );\n }\n if (\n options.leaseMs !== undefined &&\n (!Number.isFinite(options.leaseMs) || options.leaseMs <= 0)\n ) {\n throw new ValidationError(\n `compaction: options.leaseMs must be a positive finite number; got ${options.leaseMs}`,\n );\n }\n}\n\n/**\n * Compact one segment. A no-op (returns `compacted: false`) if it has no dirty Warm rows or another worker\n * holds a live lease. Never throws on the normal contention/lease-loss paths — those are reported in `reason`.\n * Emits a `compaction` metric event per attempt (Phase D, gap #2) when a sink is wired, timing the attempt.\n */\nexport async function compactSegment(\n ref: SegmentRef,\n deps: CompactionDeps,\n options: CompactionOptions,\n): Promise<CompactionResult> {\n validateCompactionOptions(options);\n const startedAt = deps.clock.now();\n const emit = (\n r: Pick<CompactionResult, 'compacted' | 'reason' | 'dirtyChunks' | 'purged'>,\n ): void => {\n if (deps.metrics === undefined) return;\n try {\n deps.metrics.onEvent({\n kind: 'compaction',\n namespace: ref.namespace,\n segment: ref.segment,\n compacted: r.compacted,\n reason: r.reason,\n dirtyChunks: r.dirtyChunks,\n purged: r.purged,\n ms: Math.max(0, deps.clock.now() - startedAt),\n });\n } catch {\n /* metrics must never break compaction */\n }\n };\n try {\n const result = await compactSegmentInner(ref, deps, options);\n emit(result);\n return result;\n } catch (err) {\n // A genuine fault (non-contention) — surface it, but still record the attempt (reason 'error') so a\n // poison segment is visible; `runCompactionCycle` isolates it + bumps consecutiveFailures.\n emit({ compacted: false, reason: 'error', dirtyChunks: 0, purged: 0 });\n throw err;\n }\n}\n\nasync function compactSegmentInner(\n ref: SegmentRef,\n deps: CompactionDeps,\n options: CompactionOptions,\n): Promise<CompactionResult> {\n const now = (): number => deps.clock.now();\n const maxBytes = deps.maxBitmapBytes ?? DEFAULT_MAX_BITMAP_BYTES;\n const leaseMs = options.leaseMs ?? DEFAULT_LEASE_MS;\n const base = { segment: ref.segment, namespace: ref.namespace };\n const audit = safeAudit(options.audit ?? NOOP_AUDIT);\n // Emit the audit record the moment a generation is *durably committed* — before the (idempotent, fenced,\n // resumable-next-cycle) Warm purge, so a post-commit purge fault can never drop the compliance record for a\n // generation that is already the authoritative current one. Called only on the two committed paths.\n const auditCompacted = (generation: number): void =>\n audit.onEvent({\n kind: 'segment.compact',\n namespace: ref.namespace,\n segment: ref.segment,\n generation,\n });\n // The crypto context for one generation of this segment, given its DEK's AEAD (undefined ⇒ cleartext). The\n // AAD binds each chunk/index to (segment, generation), so reading gen g and writing gen g+1 use distinct\n // contexts over the same DEK.\n const cryptoAt = (aead: Aead | undefined, generation: number): CrbmCrypto | undefined =>\n aead === undefined ? undefined : { aead, aadFor: (scope) => aadFor(ref, generation, scope) };\n const record = await deps.registry.get(ref);\n\n // A crypto-shredded segment is terminal — never resurrect it by compacting (that would re-encrypt under a\n // DEK whose wrappings are gone, or re-acquire a lease on a `destroyed` row). Leave it as the tombstone it is.\n if (record !== null && record.status === 'destroyed') {\n return {\n ...base,\n compacted: false,\n reason: 'destroyed',\n fromGen: record.currentGen,\n dirtyChunks: 0,\n purged: 0,\n survived: 0,\n };\n }\n\n // ── Bootstrap: a segment with no registry row (never compacted / bulk-loaded). No cold base, no lease\n // needed — the registry `create` is the exclusivity point. Two workers can race here, and gen 0 is\n // write-once, so at most one *writes* it; the other(s) only see a conflict. Critically, an adopter must NOT\n // purge its pinned Warm rows against a gen 0 it didn't write — that gen may not reflect them, which would be\n // a lost write (**I4**). So only the worker that actually wrote gen 0 purges; an adopter just ensures the\n // pointer exists and leaves its Warm rows for the next (normal) compaction to fold over the committed gen 0. ──\n if (record === null) {\n const pinned = await collectDirty(\n deps.warm,\n ref,\n maxBytes,\n requireCodec(deps.codec, 'compactSegment'),\n );\n if (pinned.length === 0)\n return {\n ...base,\n compacted: false,\n reason: 'clean',\n fromGen: null,\n dirtyChunks: 0,\n purged: 0,\n survived: 0,\n };\n // Encryption: mint a fresh per-segment DEK for gen 0 (or write cleartext). If we lose the gen-0 write race\n // our minted DEK is simply discarded — the winner's DEK (in the winning registry.create) is authoritative.\n let aead: Aead | undefined;\n let wrappedDeks: readonly WrappedDek[] | undefined;\n if (deps.keystore !== undefined) {\n const minted = await deps.keystore.createDek();\n aead = minted.aead;\n wrappedDeks = minted.wrapped;\n } else if (deps.requireEncryption === true) {\n throw new ValidationError(\n `requireEncryption: segment \"${ref.segment}\" needs a keystore to bootstrap encrypted`,\n );\n }\n const gen0: GenKey = { namespace: ref.namespace, segment: ref.segment, generation: 0 };\n const stream = mergeChunksStream(ref, null, pinned, deps, maxBytes, undefined);\n let wrote = true;\n let tally: { chunkKeys: number[]; cardinality: number } | undefined;\n try {\n tally = await writeCrbmGenerationStream(deps.cold, gen0, stream, {\n crypto: cryptoAt(aead, 0),\n });\n } catch (err) {\n // A concurrent bootstrap (or a crashed prior attempt) already wrote gen 0 — adopt it, don't fail.\n if (!isWriteConflictError(err)) throw err;\n wrote = false;\n }\n if (wrote && tally !== undefined) {\n await verifyGeneration(deps.cold, gen0, tally, cryptoAt(aead, 0)); // verify only bytes we wrote\n }\n try {\n await deps.registry.create(ref, {\n currentGen: 0,\n dirtyChunkCount: 0,\n status: 'active',\n wrappedDeks,\n });\n } catch (err) {\n if (!isWriteConflictError(err)) throw err; // a concurrent bootstrap published the pointer first\n }\n if (!wrote)\n // We adopted another worker's gen 0; our Warm rows may not be in it, so purging them could lose data.\n // Leave them — the next normal compaction merges them over the now-committed gen 0. No loss, no torn read.\n return {\n ...base,\n compacted: false,\n reason: 'bootstrap-raced',\n fromGen: null,\n dirtyChunks: pinned.length,\n purged: 0,\n survived: pinned.length,\n };\n auditCompacted(0); // gen 0 is now the committed current generation (write-once object + registry row)\n const { purged, survived } = await purgeAfterCommit(deps.warm, ref, pinned);\n return {\n ...base,\n compacted: true,\n fromGen: null,\n toGen: 0,\n dirtyChunks: pinned.length,\n purged,\n survived,\n };\n }\n\n // ── Normal path: acquire/steal the lease. ──\n const expired = record.leaseExpiresAt === undefined || record.leaseExpiresAt <= now();\n const ownedByOther =\n record.status === 'compacting' && !expired && record.leaseOwner !== options.owner;\n if (ownedByOther) {\n return {\n ...base,\n compacted: false,\n reason: 'leased-by-other',\n fromGen: record.currentGen,\n dirtyChunks: 0,\n purged: 0,\n survived: 0,\n };\n }\n let leaseToken: Token;\n try {\n const res = await deps.registry.compareAndSwap(ref, record.token, {\n status: 'compacting',\n leaseOwner: options.owner,\n leaseExpiresAt: now() + leaseMs,\n });\n leaseToken = res.token;\n } catch (err) {\n if (isWriteConflictError(err)) {\n return {\n ...base,\n compacted: false,\n reason: 'leased-by-other',\n fromGen: record.currentGen,\n dirtyChunks: 0,\n purged: 0,\n survived: 0,\n };\n }\n throw err;\n }\n\n const g = record.currentGen;\n try {\n // Resolve the segment's DEK first (encrypted segments reuse it across generations). Doing it BEFORE the\n // gap-#5 re-read keeps a potentially slow keystore/KMS `openDek` OUT of the fence window below. Inside the\n // try so a failure releases the lease; KeyUnavailableError here is a genuine fault (lost key) — it propagates.\n let aead: Aead | undefined;\n if (record.wrappedDeks !== undefined && record.wrappedDeks.length > 0) {\n if (deps.keystore === undefined) {\n throw new KeyUnavailableError(\n `segment \"${ref.segment}\" is encrypted but compaction has no keystore`,\n );\n }\n aead = await deps.keystore.openDek(record.wrappedDeks);\n } else if (deps.requireEncryption === true) {\n throw new ValidationError(`requireEncryption: segment \"${ref.segment}\" is cleartext`);\n }\n\n // Fence RECONCILE against a concurrent publish/bulk-load (gap #5). `publishGeneration` /\n // `bulkLoadCrbmGeneration` CAS on the *current* token, NOT the lease, so one can advance `currentGen`\n // past `g` after our pre-lease read. Re-read it now that we hold the lease: if it moved, our compaction\n // basis (g) is stale and RECONCILE (`deleteGenerationsAbove(g)`) would delete the just-published\n // generation. Abort cleanly (nothing destructive has run) and let the next cycle re-pin.\n //\n // This closes the publish-completed-before-RECONCILE window. RESIDUAL (deferred — only lease-aware\n // publishing, the heavier option (a), fully closes it): a publish that lands *during* the sweep below,\n // after this re-read, is not caught, and its blast radius is NOT merely \"a narrower lost update\" — if the\n // raced publish picks gen == g+1 it's a silent whole-generation lost update; if it picks gen > g+1 the\n // sweep deletes the object `currentGen` now points at, leaving a dangling pointer (reads AND the next\n // compaction both throw, with no self-heal). Self-healing recovery here is a known deferral.\n const live = await deps.registry.get(ref);\n if (live === null || live.currentGen !== g) {\n // Best-effort: in this very race the superseding publish already bumped the record's token, so this CAS\n // typically conflicts and no-ops (swallowed) — the lease then recovers via expiry/steal, not here.\n await releaseLease(deps, ref, leaseToken);\n return {\n ...base,\n compacted: false,\n reason: 'superseded',\n fromGen: g,\n dirtyChunks: 0,\n purged: 0,\n survived: 0,\n };\n }\n\n // RECONCILE: drop orphan generations > g (a crashed prior stage). Safe — we hold the lease (exclusive), `g`\n // was just re-confirmed current, and readers are pinned to a committed gen ≤ g, so nothing references a gen > g.\n await deleteGenerationsAbove(deps.cold, ref, g);\n\n const pinned = await collectDirty(\n deps.warm,\n ref,\n maxBytes,\n requireCodec(deps.codec, 'compactSegment'),\n );\n if (pinned.length === 0) {\n await releaseLease(deps, ref, leaseToken); // nothing to do — give the lease back\n return {\n ...base,\n compacted: false,\n reason: 'clean',\n fromGen: g,\n dirtyChunks: 0,\n purged: 0,\n survived: 0,\n };\n }\n\n const newGen = g + 1;\n // Read the old generation under its (gen g) crypto; stream-write the new one under its (gen g+1) crypto.\n const stream = mergeChunksStream(ref, g, pinned, deps, maxBytes, cryptoAt(aead, g));\n await stageGeneration(\n deps.cold,\n { namespace: ref.namespace, segment: ref.segment, generation: newGen },\n stream,\n cryptoAt(aead, newGen),\n );\n\n // SWAP (commit) — conditional on the lease token. If our lease was stolen/expired-and-taken, this fails and\n // we abort *before* purging: the staged generation becomes an orphan (GC'd later), and not one Warm row was\n // deleted, so there is no data loss. We must NOT release the lease here — it belongs to the thief now.\n try {\n await deps.registry.compareAndSwap(ref, leaseToken, {\n currentGen: newGen,\n status: 'active',\n leaseOwner: undefined,\n leaseExpiresAt: undefined,\n dirtyChunkCount: 0,\n lastCompactedAt: now(), // dead-man's-switch (gap #2): a stale value = a stuck segment\n consecutiveFailures: 0, // a successful commit clears any prior poison-quarantine streak\n });\n } catch (err) {\n if (isWriteConflictError(err)) {\n return {\n ...base,\n compacted: false,\n reason: 'lease-lost',\n fromGen: g,\n dirtyChunks: pinned.length,\n purged: 0,\n survived: 0,\n };\n }\n throw err;\n }\n\n // The conditional currentGen swap above is the atomic commit — audit here, before purge.\n auditCompacted(newGen);\n const { purged, survived } = await purgeAfterCommit(deps.warm, ref, pinned);\n return {\n ...base,\n compacted: true,\n fromGen: g,\n toGen: newGen,\n dirtyChunks: pinned.length,\n purged,\n survived,\n };\n } catch (err) {\n // Abnormal exit before the commit (corrupt Warm row, cold I/O fault, or a stage write-conflict): release\n // the lease so the segment isn't stuck `compacting` until expiry. A WriteConflict here is a staging\n // conflict (an orphan we couldn't reconcile) — report it cleanly; any other error is a genuine fault, so\n // propagate it for the caller to handle (`runCompactionCycle` isolates per-segment failures).\n await releaseLease(deps, ref, leaseToken).catch(() => undefined);\n if (isWriteConflictError(err)) {\n return {\n ...base,\n compacted: false,\n reason: 'stage-conflict',\n fromGen: g,\n dirtyChunks: 0,\n purged: 0,\n survived: 0,\n };\n }\n throw err;\n }\n}\n\n/**\n * Garbage-collect superseded Cold generations for a segment: everything strictly below `currentGen`, keeping\n * the most recent `keep` of them as a grace window for in-flight readers pinned to a just-superseded\n * generation (**I5**). Generations ≥ `currentGen` are never touched. Returns the generations deleted.\n */\nexport async function gcOrphanGenerations(\n ref: SegmentRef,\n deps: Pick<CompactionDeps, 'cold' | 'registry'>,\n options: { keep?: number } = {},\n): Promise<number[]> {\n const keep = Math.max(0, options.keep ?? 1);\n const record = await deps.registry.get(ref);\n if (record === null) return []; // no authoritative pointer → don't delete anything\n const current = record.currentGen;\n const gens: number[] = [];\n for await (const key of deps.cold.list(ref)) gens.push(key.generation);\n // Delete generations below current, except the newest `keep` of them (the grace window).\n const below = gens.filter((g) => g < current).sort((a, b) => b - a); // newest-first\n const toDelete = below.slice(keep);\n for (const generation of toDelete) {\n await deps.cold.delete({ namespace: ref.namespace, segment: ref.segment, generation });\n }\n return toDelete;\n}\n\n/** Collect + decode every live Warm row, pinning each chunk's OCC token for the fenced purge. */\nasync function collectDirty(\n warm: IWarmDriver,\n ref: SegmentRef,\n maxBytes: number,\n codec: CodecInterface,\n): Promise<PinnedChunk[]> {\n const out: PinnedChunk[] = [];\n for await (const row of warm.listChunks(ref)) {\n out.push({\n chunkKey: row.chunkKey,\n token: row.token,\n delta: decodeDelta(row.bytes, maxBytes, codec),\n });\n }\n return out;\n}\n\n/**\n * Yield the new generation's chunks **ascending**: dirty chunks merged `(cold ∪ adds) \\ removes`, clean chunks\n * copied through. An async generator so the writer streams them in constant memory (Phase 4f) — only one merged\n * chunk + the cold reader's index are live at a time, never the whole cold generation. (The pinned\n * Warm-delta map is still fully in memory — see the module caveat.)\n */\nasync function* mergeChunksStream(\n ref: SegmentRef,\n g: number | null,\n pinned: PinnedChunk[],\n deps: CompactionDeps,\n maxBytes: number,\n readCrypto: CrbmCrypto | undefined,\n): AsyncGenerator<{ chunkKey: number; bitmap: CodecBitmap }> {\n const codec = requireCodec(deps.codec, 'compactSegment');\n const dirty = new Map(pinned.map((p) => [p.chunkKey, p.delta]));\n const reader =\n g === null\n ? null\n : await openReader(\n deps.cold,\n { namespace: ref.namespace, segment: ref.segment, generation: g },\n readCrypto,\n );\n // The union of cold keys + dirty keys (a clean cold chunk is copied through unchanged), ascending.\n const keys = new Set<number>(dirty.keys());\n if (reader !== null) for (const k of reader.chunkKeys()) keys.add(k);\n\n for (const chunkKey of [...keys].sort((a, b) => a - b)) {\n const coldBytes = reader === null ? null : await reader.getChunk(chunkKey);\n const cold = coldBytes === null ? codec.empty() : codec.safeDeserialize(coldBytes, maxBytes);\n const merged = effective(cold, dirty.get(chunkKey) ?? emptyDelta(codec));\n if (!merged.isEmpty) yield { chunkKey, bitmap: merged };\n }\n}\n\n/** Stream-write the new generation (write-once), then re-open it to verify it round-trips what we merged. */\nasync function stageGeneration(\n cold: IColdDriver,\n key: GenKey,\n chunks: AsyncIterable<{ chunkKey: number; bitmap: CodecBitmap }>,\n crypto: CrbmCrypto | undefined,\n): Promise<void> {\n // The normal path deletes orphan generations > g first, so a write-conflict here is a real race (a\n // concurrent compaction beat us to this generation) — let it surface as the staging conflict it is.\n const tally = await writeCrbmGenerationStream(cold, key, chunks, { crypto });\n await verifyGeneration(cold, key, tally, crypto);\n}\n\n/**\n * Re-open a freshly written generation and assert it round-trips exactly what we merged: same per-chunk key\n * set *and* same total cardinality (on top of the codec's own per-chunk CRC + footer checks). `expected` is the\n * streaming writer's tally (the stream is consumed, so we can't re-iterate it) — the key-set comparison catches\n * a dropped/extra chunk that a cardinality-only check could miss when two errors cancel out.\n */\nasync function verifyGeneration(\n cold: IColdDriver,\n key: GenKey,\n expected: { chunkKeys: number[]; cardinality: number },\n crypto: CrbmCrypto | undefined,\n): Promise<void> {\n const expectedCount = expected.cardinality;\n const expectedKeys = [...expected.chunkKeys].sort((a, b) => a - b);\n const reader = await openReader(cold, key, crypto);\n const actualKeys = [...reader.chunkKeys()].sort((a, b) => a - b);\n const keysMatch =\n actualKeys.length === expectedKeys.length && actualKeys.every((k, i) => k === expectedKeys[i]);\n if (!keysMatch) {\n throw new WriteConflictError(\n `compaction verify failed for ${key.segment}.${key.generation}: chunk-key set mismatch (${actualKeys.length} vs ${expectedKeys.length})`,\n );\n }\n if (reader.count() !== expectedCount) {\n throw new WriteConflictError(\n `compaction verify failed for ${key.segment}.${key.generation}: cardinality ${reader.count()} != ${expectedCount}`,\n );\n }\n}\n\n/** Version-fenced purge: delete each archived Warm row iff its token is unchanged; a newer one survives (I4). */\nasync function purge(\n warm: IWarmDriver,\n ref: SegmentRef,\n pinned: PinnedChunk[],\n): Promise<{ purged: number; survived: number }> {\n let purged = 0;\n let survived = 0;\n for (const { chunkKey, token } of pinned) {\n const chunkRef: ChunkRef = { namespace: ref.namespace, segment: ref.segment, chunkKey };\n try {\n await warm.deleteConditional(chunkRef, token);\n purged += 1;\n } catch (err) {\n if (!isWriteConflictError(err)) throw err;\n survived += 1; // rewritten after the scan → keep it for the next dirty set\n }\n }\n return { purged, survived };\n}\n\n/**\n * Purge archived Warm rows **after** a durable commit. Best-effort: the generation is already committed, and the\n * purge is fenced + idempotent (any row left behind simply re-folds — unchanged — on the next cycle, **I4**), so\n * a transient Warm fault here must NOT be attributed to compaction, which succeeded. Swallow it and report the\n * commit; the next cycle purges the remainder. Returns 0-purged on fault (the pinned rows survive, to be retried).\n * (Mirrors the best-effort `gcOrphanGenerations` call in {@link runCompactionCycle} — both are post-commit cleanup.)\n */\nasync function purgeAfterCommit(\n warm: IWarmDriver,\n ref: SegmentRef,\n pinned: PinnedChunk[],\n): Promise<{ purged: number; survived: number }> {\n return purge(warm, ref, pinned).catch(() => ({ purged: 0, survived: pinned.length }));\n}\n\n/**\n * Delete every Cold generation strictly greater than `g` (crashed-stage orphans). Called under the lease with\n * `g` == the generation just **re-confirmed current** (gap #5) — never a stale pre-lease value, or a\n * concurrently published generation could be deleted. currentGen and below (which readers may be pinned to)\n * are never touched.\n */\nasync function deleteGenerationsAbove(\n cold: IColdDriver,\n ref: SegmentRef,\n g: number,\n): Promise<void> {\n for await (const key of cold.list(ref)) {\n if (key.generation > g) await cold.delete(key);\n }\n}\n\n/** Best-effort lease release (set status back to active). Swallows a conflict — the lease will simply expire. */\nasync function releaseLease(\n deps: CompactionDeps,\n ref: SegmentRef,\n leaseToken: Token,\n): Promise<void> {\n try {\n await deps.registry.compareAndSwap(ref, leaseToken, {\n status: 'active',\n leaseOwner: undefined,\n leaseExpiresAt: undefined,\n });\n } catch (err) {\n if (!isWriteConflictError(err)) throw err;\n }\n}\n\n/** Open a {@link CrbmReader} for one generation over the cold driver's range/tail reads (decrypting if `crypto`). */\nfunction openReader(\n cold: IColdDriver,\n key: GenKey,\n crypto: CrbmCrypto | undefined,\n): Promise<CrbmReader> {\n const blob: BlobReader = {\n getRange: (offset, length) => cold.getRange(key, offset, length),\n getTail: (maxBytes) => cold.getTail(key, maxBytes),\n };\n return CrbmReader.open(blob, { crypto });\n}\n\n// ──────────────────────────────────────────────────────────────────────────────────────────────────────\n// Discovery + daemon cycle (Option A: no hot-path coupling — the write path never touches the registry). To\n// scale toward 100K segments (gap #3), discovery is **shardable** (each worker drains ~1/N of Warm), consumes\n// the `dirtyChunkCount` hint for change-guarded CAS + urgency ordering, and **quarantines** poison segments\n// (gap #2). It still drains Warm per in-shard segment to *count* dirty rows for correctness (O(total warm /\n// shards)); turning that into O(dirty) needs the deferred cheap-enumeration seam (GSI/Select:COUNT — gap #3).\n// ──────────────────────────────────────────────────────────────────────────────────────────────────────\n\nexport interface DiscoveryOptions {\n /** Scope discovery to one namespace (registry `list(namespace)`). */\n readonly namespace?: string;\n /** Minimum dirty Warm rows for a segment to be a candidate (default 1). */\n readonly threshold?: number;\n /**\n * Extra segments to consider beyond the registry's known set. Discovery enumerates `registry.list()`, which\n * only contains segments that have a committed generation — a brand-new **all-warm** segment isn't there\n * yet, so name it here (or bulk-load it once) for the daemon to pick it up.\n */\n readonly candidates?: readonly SegmentRef[];\n /**\n * Shard this worker's slice of the fleet (gap #3). With `totalShards > 1`, discovery considers only segments\n * whose **stable hash** (FNV-1a of the segment key, mod `totalShards`) falls in `shard` (0-based). Run N\n * daemons with `{ shard: i, totalShards: N }` to partition the fleet N ways — each **drains and compacts** only\n * its ~1/N of segments per cycle. NB: the registry enumeration + in-memory candidate set stay O(total segments)\n * per worker (the hash needs the key, which only the scan yields); only the Warm drain + compaction shard. The\n * O(dirty) indexed-enumeration seam that would shard the scan too is deferred (gap #3). Default: handle all.\n */\n readonly shard?: number;\n readonly totalShards?: number;\n /**\n * Poison-segment quarantine (gap #2): a segment whose `consecutiveFailures` has reached this threshold is\n * skipped by discovery (not even drained) until `quarantineCooldownMs` since its last registry update has\n * elapsed — then it's retried once (a transient fault self-heals; a persistent one re-quarantines). Default 5.\n */\n readonly quarantineThreshold?: number;\n /** Cooldown (ms) before a quarantined segment is retried once (default 5 min). */\n readonly quarantineCooldownMs?: number;\n}\n\nexport interface CompactionCandidate {\n readonly ref: SegmentRef;\n readonly dirtyChunks: number;\n readonly currentGen: number | null;\n /** Epoch-ms of the segment's last successful compaction (undefined = never) — the urgency tie-break. */\n readonly lastCompactedAt?: number;\n}\n\nfunction validateShard(shard: number, totalShards: number): void {\n if (!Number.isInteger(totalShards) || totalShards < 1) {\n throw new ValidationError(`totalShards must be a positive integer; got ${totalShards}`);\n }\n if (!Number.isInteger(shard) || shard < 0 || shard >= totalShards) {\n throw new ValidationError(`shard must be an integer in [0, ${totalShards}); got ${shard}`);\n }\n}\n\n/** Deterministic FNV-1a shard assignment for a segment key — dependency-free, stable across workers/restarts. */\nfunction shardOf(key: string, totalShards: number): number {\n let h = 0x811c9dc5;\n for (let i = 0; i < key.length; i++) {\n h ^= key.charCodeAt(i);\n h = Math.imul(h, 0x0100_0193);\n }\n return (h >>> 0) % totalShards;\n}\n\ninterface KnownSegment {\n readonly ref: SegmentRef;\n readonly currentGen: number | null;\n readonly token?: Token;\n readonly dirtyHint: number;\n readonly consecutiveFailures: number;\n readonly updatedAt: number;\n readonly lastCompactedAt?: number;\n}\n\n/**\n * Find segments worth compacting: those in this worker's shard with ≥ `threshold` dirty Warm rows, excluding\n * quarantined poison segments (gap #2). Enumerates the registry (optionally one namespace) plus explicit\n * `candidates`, then for each in-shard, non-quarantined segment drains `warm.listChunks` to count dirty rows —\n * O(total warm / shards) (turning that into O(dirty) needs the deferred GSI/Select:COUNT seam, gap #3). Refreshes\n * the `dirtyChunkCount` hint only when it **changed** (change-guarded CAS — no idle-segment write storm).\n */\nexport async function findCompactable(\n deps: Pick<CompactionDeps, 'warm' | 'registry' | 'clock'>,\n options: DiscoveryOptions = {},\n): Promise<CompactionCandidate[]> {\n const threshold = Math.max(1, options.threshold ?? 1);\n const totalShards = options.totalShards ?? 1;\n const shard = options.shard ?? 0;\n validateShard(shard, totalShards);\n const quarantineThreshold = options.quarantineThreshold ?? DEFAULT_QUARANTINE_THRESHOLD;\n const cooldownMs = options.quarantineCooldownMs ?? DEFAULT_QUARANTINE_COOLDOWN_MS;\n const now = deps.clock.now();\n\n const known = new Map<string, KnownSegment>();\n for await (const rec of deps.registry.list(options.namespace)) {\n known.set(segmentKey(rec), {\n ref: { namespace: rec.namespace, segment: rec.segment },\n currentGen: rec.currentGen,\n token: rec.token,\n dirtyHint: rec.dirtyChunkCount,\n consecutiveFailures: rec.consecutiveFailures ?? 0,\n updatedAt: rec.updatedAt,\n lastCompactedAt: rec.lastCompactedAt,\n });\n }\n for (const ref of options.candidates ?? []) {\n const k = segmentKey(ref);\n if (!known.has(k)) {\n known.set(k, { ref, currentGen: null, dirtyHint: 0, consecutiveFailures: 0, updatedAt: 0 });\n }\n }\n\n const out: CompactionCandidate[] = [];\n for (const [key, seg] of known) {\n // Shard filter (gap #3): a worker handles only its slice, so it drains ~1/N of Warm per cycle.\n if (totalShards > 1 && shardOf(key, totalShards) !== shard) continue;\n // Poison-segment quarantine (gap #2): skip a repeatedly-failing segment — don't even drain it — until the\n // cooldown since its last update elapses, then let it retry once. Transient faults self-heal; persistent\n // ones re-quarantine on the next failure.\n if (seg.consecutiveFailures >= quarantineThreshold && now - seg.updatedAt < cooldownMs)\n continue;\n\n let dirty = 0;\n for await (const row of deps.warm.listChunks(seg.ref)) {\n void row;\n dirty += 1;\n }\n // Change-guarded CAS (gap #3): rewrite the hint only when it actually moved — no per-idle-segment write.\n if (seg.token !== undefined && dirty !== seg.dirtyHint) {\n try {\n await deps.registry.compareAndSwap(seg.ref, seg.token, { dirtyChunkCount: dirty });\n } catch (err) {\n if (!isWriteConflictError(err)) throw err;\n }\n }\n if (dirty >= threshold) {\n out.push({\n ref: seg.ref,\n dirtyChunks: dirty,\n currentGen: seg.currentGen,\n lastCompactedAt: seg.lastCompactedAt,\n });\n }\n }\n return out;\n}\n\n/** What one {@link runCompactionCycle} did: candidates found, how many committed, how many the budget deferred. */\nexport interface CompactionCycleResult {\n /** In-shard, non-quarantined segments over threshold this cycle. */\n readonly candidates: number;\n /** How many committed a new generation. */\n readonly compacted: number;\n /** Candidates left unprocessed by the `maxSegments` budget — run again to drain them. */\n readonly deferred: number;\n readonly results: CompactionResult[];\n}\n\n/**\n * Run one discovery → compact → GC cycle. The CLI/daemon calls this once (Lambda) or on a loop (K8s/ECS).\n * Candidates are processed **most-dirty first** (tie-broken by oldest/never-compacted), and an optional\n * `maxSegments` budget caps the **compact/GC** work per cycle — the rest are `deferred` to the next cycle\n * (urgency ordering keeps the hottest from starving). The budget bounds only compaction: discovery (the registry\n * scan + in-shard Warm drain + urgency sort) is paid in full each cycle, so at very large fleets discovery — not\n * compaction — is the per-cycle floor; the deferred resumable cursor (gap #3) is what will bound it. Per-segment\n * faults are isolated **and** counted toward quarantine (gap #2), so one poison segment can neither abort the\n * cycle nor silently freeze.\n */\nexport async function runCompactionCycle(\n deps: CompactionDeps,\n options: CompactionOptions & DiscoveryOptions & { keep?: number; maxSegments?: number },\n): Promise<CompactionCycleResult> {\n validateCompactionOptions(options); // fail fast even when discovery finds zero candidates\n if (\n options.maxSegments !== undefined &&\n (!Number.isInteger(options.maxSegments) || options.maxSegments < 1)\n ) {\n // A positive integer or nothing. (0 as \"compact none\" is a footgun; negatives were silently \"unlimited\".)\n throw new ValidationError(`maxSegments must be a positive integer; got ${options.maxSegments}`);\n }\n const found = await findCompactable(deps, options);\n // Urgency ordering (gap #3): most-dirty first, tie-broken by oldest/never-compacted (undefined ⇒ 0 ⇒ first),\n // so a limited budget spends where it matters and the backlog can't starve the hottest segments.\n found.sort(\n (a, b) => b.dirtyChunks - a.dirtyChunks || (a.lastCompactedAt ?? 0) - (b.lastCompactedAt ?? 0),\n );\n const budget = options.maxSegments; // validated to a positive integer (or undefined) above\n const picked = budget !== undefined ? found.slice(0, budget) : found;\n\n const results: CompactionResult[] = [];\n let compacted = 0;\n for (const { ref } of picked) {\n // Isolate per-segment faults: a poison-pill segment (corrupt Warm row, cold I/O error) must not abort the\n // whole cycle — record it, count it toward quarantine, and move on to the healthy segments.\n try {\n const result = await compactSegment(ref, deps, options);\n results.push(result);\n if (result.compacted) {\n compacted += 1;\n // Orphan GC is best-effort cleanup (the next cycle's GC catches up the backlog), and the new generation is\n // already durably committed — so a GC fault must NOT be attributed to compaction. Isolate it from the\n // fault path below: otherwise a transient cold/registry error here would bump this *healthy* segment's\n // consecutiveFailures toward quarantine and push a phantom `error` result for a segment that succeeded.\n await gcOrphanGenerations(ref, deps, { keep: options.keep }).catch(() => undefined);\n }\n } catch (err) {\n await bumpFailure(deps, ref).catch(() => undefined); // best-effort; quarantine only needs it eventually\n results.push({\n segment: ref.segment,\n namespace: ref.namespace,\n compacted: false,\n reason: 'error',\n error: err instanceof Error ? err.message : String(err),\n fromGen: null,\n dirtyChunks: 0,\n purged: 0,\n survived: 0,\n });\n }\n }\n return { candidates: found.length, compacted, deferred: found.length - picked.length, results };\n}\n\n/**\n * Increment a segment's `consecutiveFailures` toward poison-quarantine (gap #2) after an isolated compaction\n * fault. Best-effort + conditional: a lost CAS (a concurrent writer) is harmless — the count just advances on a\n * later failing cycle. A successful compaction resets it to 0 (in the commit swap).\n */\nasync function bumpFailure(deps: Pick<CompactionDeps, 'registry'>, ref: SegmentRef): Promise<void> {\n const rec = await deps.registry.get(ref);\n if (rec === null) return; // no row yet (a bootstrap fault) — nothing to quarantine against\n try {\n await deps.registry.compareAndSwap(ref, rec.token, {\n consecutiveFailures: (rec.consecutiveFailures ?? 0) + 1,\n });\n } catch (err) {\n if (!isWriteConflictError(err)) throw err;\n }\n}\n","/**\n * Segment **export (\"eject\")** — dump every registered segment's current *effective* set to a portable file,\n * using only public read APIs, so your data is readable **without CloudRoaring** (a first-class exit path;\n * see the README \"Your data stays yours\" section).\n *\n * Two formats:\n * - `'roaring'` (default) — one **portable RoaringBitmap32** per segment (the cross-language CRoaring format,\n * loadable by any roaring library in Java/Go/Python/Rust/C++/…). Compact; builds one bitmap in memory per\n * segment.\n * - `'ndjson'` — newline-delimited ids, streamed (constant memory, any segment size); zero dependencies to read.\n *\n * The engine is **storage-agnostic and I/O-free**: it enumerates via an {@link IRegistryDriver}, reads the\n * tier-merged effective set via a store's `segment(...).iterate()`, and writes bytes through an injected\n * {@link ExportSink} — so it never imports `node:fs` (the `export-segments` CLI supplies a filesystem sink; a\n * test supplies an in-memory one; you could supply an S3 uploader). Crypto-shredded (`destroyed`) segments are\n * skipped (their bytes are unrecoverable); an encrypted segment is decrypted transparently **iff** the store was\n * wired with its keystore — so the export is **cleartext**, and protecting it is on you.\n *\n * **Enumeration** = the registry's known set (segments with a committed cold generation) **plus** any explicit\n * {@link ExportOptions.candidates}. A brand-new **all-warm** segment — written only via real-time\n * `add()`/`remove()`, never compacted — isn't in the registry yet, so name it in `candidates` (CLI:\n * `CR_EXPORT_SEGMENTS`) to include it, or compact/bulk-load it once first. This mirrors the compaction daemon's\n * discovery contract (see `findCompactable`).\n *\n * **Per-segment fault isolation:** a segment that can't be read (a corrupt cold object, or an encrypted segment\n * when the store has no keystore) is recorded in the manifest's {@link ExportManifest.failed} list and the export\n * **continues** — one bad segment never blocks the rest. Its partial output is aborted, so a truncated file never\n * masquerades as complete. Therefore \"a manifest exists\" means *the run finished*, not that every segment\n * succeeded — check `failed` (the CLI also exits non-zero when it's non-empty).\n */\nimport type { CodecInterface } from '../core/codec';\nimport { requireCodec } from '../core/codec';\nimport type { IRegistryDriver, SegmentRef } from '../core/ports';\nimport { validateSegmentRef } from '../core/validate';\n\n/** Output format for {@link runExport} / `CloudRoaring.exportSegments`. */\nexport type ExportFormat = 'roaring' | 'ndjson';\n\n/** A writer for one segment's output — inject a filesystem file, an S3 upload, stdout, or a test buffer. */\nexport interface ExportWriter {\n /** Append bytes (called one or more times; for `ndjson`, batched line chunks; for `roaring`, once). */\n write(bytes: Uint8Array): Promise<void> | void;\n /** **Commit** the output — called once, only on success (all bytes written). Finalize/flush/rename here. */\n close(): Promise<void> | void;\n /**\n * **Discard** a partial output — called instead of `close()` if a fault occurs mid-segment, so a truncated file\n * never masquerades as complete (e.g. delete the temp file). Optional; sinks with nothing to undo can omit it.\n */\n abort?(): Promise<void> | void;\n}\n\n/** A destination the export writes each segment to. `ext` is `.roaring` or `.ndjson`. */\nexport interface ExportSink {\n open(ref: SegmentRef, ext: string): Promise<ExportWriter> | ExportWriter;\n}\n\nexport interface ExportOptions {\n /** Output format; defaults to `'roaring'`. */\n readonly format?: ExportFormat;\n /**\n * Bitmap codec used to build the exported bitmap for the `'roaring'` format ([DECISIONS #58]). Optional in the\n * type so this stays call-compatible public API; a **flavor** package binds it (see `requireCodec`). Not needed\n * for `'ndjson'`, which streams plain ids.\n */\n readonly codec?: CodecInterface;\n /** Scope the export to one namespace; omit to export every registered segment. */\n readonly namespace?: string;\n /** `ndjson` flush threshold in ~bytes (ids are ASCII, so ≈ chars); defaults to 64 KiB. */\n readonly ndjsonBatchBytes?: number;\n /**\n * Extra segments to export beyond the registry's known set. The registry only lists segments with a committed\n * cold generation, so an **all-warm** segment (written via real-time `add()`/`remove()`, never compacted) must\n * be named here to be included (CLI: `CR_EXPORT_SEGMENTS`). Deduped against the registry set; when `namespace`\n * is set, only candidates in that namespace are exported.\n */\n readonly candidates?: readonly SegmentRef[];\n}\n\n/** Per-segment result recorded in the {@link ExportManifest}. */\nexport interface ExportedSegment {\n readonly segment: string;\n readonly namespace?: string;\n /** Ids written (the segment's effective cardinality at export time). */\n readonly count: number;\n /** Bytes written to the sink for this segment. */\n readonly bytes: number;\n}\n\n/**\n * A segment that could **not** be exported — recorded rather than aborting the whole run (fault isolation), so a\n * single corrupt/undecryptable segment never blocks the rest of the dump.\n */\nexport interface ExportFailure {\n readonly segment: string;\n readonly namespace?: string;\n /** Why it failed (an error message) — e.g. a corrupt cold object, or an encrypted segment with no keystore. */\n readonly error: string;\n}\n\n/** What {@link runExport} produced — a self-describing summary the CLI persists as `manifest.json`. */\nexport interface ExportManifest {\n /** Schema version of this manifest shape (currently `1`) — insurance for evolving the format post-1.0. */\n readonly version: number;\n readonly format: ExportFormat;\n readonly totalSegments: number;\n readonly totalIds: number;\n readonly segments: readonly ExportedSegment[];\n /**\n * Segments that could not be read (empty when everything succeeded). Its presence in the manifest is the point:\n * \"a manifest exists\" ⇒ the run finished, **not** that every segment succeeded — always check this list.\n */\n readonly failed: readonly ExportFailure[];\n}\n\n/** The minimal read surface the export needs from a store — a `CloudRoaring` satisfies this structurally. */\nexport interface SegmentReader {\n segment(name: string, options?: { namespace?: string }): { iterate(): AsyncIterable<number> };\n}\n\nconst DEFAULT_NDJSON_BATCH_BYTES = 64 * 1024;\n\nconst errMessage = (err: unknown): string => (err instanceof Error ? err.message : String(err));\n/** A dedup key for a ref; namespace can't contain a space (grammar), and '' uniquely denotes the default ns. */\nconst refKey = (ref: SegmentRef): string => `${ref.namespace ?? ''} ${ref.segment}`;\n\n/**\n * Export every enumerated segment's effective set through `sink`. Enumerates via `registry` (+ any\n * `options.candidates`), reads via `reader` (the store). Returns a manifest. `CloudRoaring.exportSegments` is the\n * public entry — it calls this with its own store + registry (so enumeration and the read path provably share one\n * registry).\n *\n * **Fault isolation:** a per-segment read/write fault aborts that segment's partial (so a truncated file never\n * looks complete), records it in `failed`, and the run continues — one bad segment never blocks the rest. A\n * `close()` fault is likewise recorded (never triggering `abort()` — they're mutually exclusive).\n *\n * Re-running overwrites the segments it re-exports but does **not** prune files for segments that have since\n * disappeared — export to a fresh directory for a clean dump. For a *current* image, run against a\n * freshly-constructed store: a store's cold source pins each segment's generation for its lifetime, so a\n * long-lived store that has since been compacted would export the pinned (stale) view.\n */\nexport async function runExport(\n reader: SegmentReader,\n registry: IRegistryDriver,\n sink: ExportSink,\n options: ExportOptions = {},\n): Promise<ExportManifest> {\n const format = options.format ?? 'roaring';\n const ext = format === 'roaring' ? '.roaring' : '.ndjson';\n const batchCap = options.ndjsonBatchBytes ?? DEFAULT_NDJSON_BATCH_BYTES;\n const candidates = options.candidates ?? [];\n const segments: ExportedSegment[] = [];\n const failed: ExportFailure[] = [];\n let totalIds = 0;\n // Only track seen keys when there are candidates to dedup against — keeps the common (no-candidates) path from\n // building a set over the whole registry.\n const seen = candidates.length > 0 ? new Set<string>() : null;\n\n const exportRef = async (ref: SegmentRef): Promise<void> => {\n let writer: ExportWriter | undefined;\n let count = 0;\n let bytes = 0;\n try {\n validateSegmentRef(ref); // defense-in-depth: registry rows AND user-named candidates are untrusted here\n const ids = reader.segment(ref.segment, { namespace: ref.namespace }).iterate();\n writer = await sink.open(ref, ext);\n if (format === 'roaring') {\n const bm = requireCodec(options.codec, \"runExport({ format: 'roaring' })\").empty();\n for await (const id of ids) {\n bm.add(id);\n count += 1;\n }\n const out = bm.serialize(); // portable RoaringBitmap32 — the cross-language CRoaring format\n await writer.write(out);\n bytes = out.length;\n } else {\n let buf = '';\n for await (const id of ids) {\n buf += `${id}\\n`;\n count += 1;\n if (buf.length >= batchCap) {\n const b = Buffer.from(buf, 'utf8');\n await writer.write(b);\n bytes += b.length;\n buf = '';\n }\n }\n if (buf.length > 0) {\n const b = Buffer.from(buf, 'utf8');\n await writer.write(b);\n bytes += b.length;\n }\n }\n } catch (err) {\n // Read/write fault: discard the partial (best-effort, so a failing cleanup can't mask the real fault),\n // record it, and move on — one bad segment never blocks the rest.\n if (writer !== undefined) {\n try {\n await writer.abort?.();\n } catch {\n /* best-effort cleanup */\n }\n }\n failed.push({ segment: ref.segment, namespace: ref.namespace, error: errMessage(err) });\n return;\n }\n // Commit outside the write try: a `close()` failure must NOT also trigger `abort()` (they're mutually\n // exclusive — abort on a write fault, close on success — so a custom sink never double-finalizes). A close\n // fault is still isolated: recorded, not thrown.\n try {\n await writer.close();\n } catch (err) {\n failed.push({ segment: ref.segment, namespace: ref.namespace, error: errMessage(err) });\n return;\n }\n segments.push({ segment: ref.segment, namespace: ref.namespace, count, bytes });\n totalIds += count;\n };\n\n for await (const rec of registry.list(options.namespace)) {\n if (rec.status === 'destroyed') continue; // crypto-shredded → bytes unrecoverable; nothing to export\n if (seen !== null) seen.add(refKey(rec));\n await exportRef({ segment: rec.segment, namespace: rec.namespace });\n }\n for (const ref of candidates) {\n if (options.namespace !== undefined && ref.namespace !== options.namespace) continue; // respect the ns filter\n const key = refKey(ref);\n if (seen !== null && seen.has(key)) continue; // already exported via the registry (or a duplicate candidate)\n seen?.add(key);\n await exportRef(ref);\n }\n return { version: 1, format, totalSegments: segments.length, totalIds, segments, failed };\n}\n","/**\n * The byte-IO seam the `.crbm` codec reads/writes through.\n *\n * Deliberately tiny and driver-independent: a `BlobSink` is a streaming append target (the writer needs\n * no random access), a `BlobReader` supports the speculative tail read + bounded range reads. An\n * `IColdDriver` (Phase 2b) adapts a `GenKey` to these; the in-memory impls below let the format be\n * golden-tested and let the in-memory cold tier hold a real `.crbm` with no filesystem.\n */\nimport { ValidationError } from './errors';\n\n/** Streaming append target for a single object being written. */\nexport interface BlobSink {\n write(bytes: Uint8Array): Promise<void>;\n}\n\n/**\n * Random/tail read access to a single finished object. The total size comes back from `getTail` (the\n * codec's entry point), so there's no separate `size()` — keeping the seam minimal for driver authors.\n */\nexport interface BlobReader {\n /** Exactly `length` bytes starting at `offset`. Out-of-range is a `ValidationError`, never a short read. */\n getRange(offset: number, length: number): Promise<Uint8Array>;\n /** The last `min(maxBytes, size)` bytes plus the total size — the one-GET footer+index path. */\n getTail(maxBytes: number): Promise<{ bytes: Uint8Array; size: number }>;\n}\n\n/** In-memory `BlobSink` that accumulates written bytes; `bytes()` returns the concatenation. */\nexport class BufferSink implements BlobSink {\n private readonly chunks: Uint8Array[] = [];\n private length = 0;\n\n write(bytes: Uint8Array): Promise<void> {\n // Copy: callers may reuse their buffer after write() resolves.\n this.chunks.push(bytes.slice());\n this.length += bytes.length;\n return Promise.resolve();\n }\n\n bytes(): Uint8Array {\n const out = new Uint8Array(this.length);\n let offset = 0;\n for (const chunk of this.chunks) {\n out.set(chunk, offset);\n offset += chunk.length;\n }\n return out;\n }\n}\n\n/** In-memory `BlobReader` over a fixed byte buffer. */\nexport class BufferReader implements BlobReader {\n constructor(private readonly buffer: Uint8Array) {}\n\n getRange(offset: number, length: number): Promise<Uint8Array> {\n if (\n !Number.isInteger(offset) ||\n !Number.isInteger(length) ||\n offset < 0 ||\n length < 0 ||\n offset + length > this.buffer.length\n ) {\n throw new ValidationError(\n `range [${offset}, ${offset + length}) out of bounds for ${this.buffer.length}-byte blob`,\n );\n }\n return Promise.resolve(this.buffer.subarray(offset, offset + length));\n }\n\n getTail(maxBytes: number): Promise<{ bytes: Uint8Array; size: number }> {\n const size = this.buffer.length;\n const take = Math.min(Math.max(maxBytes, 0), size);\n return Promise.resolve({ bytes: this.buffer.subarray(size - take), size });\n }\n}\n","/**\n * In-memory drivers — the Phase-1 backing for the engine.\n * They store **serialized bytes + an OCC token** (not live objects), so the engine's\n * serialize / safe-deserialize / size-cap / OCC paths are genuinely exercised. In Phase 2 these\n * become the conformance-suite's first target and the simulator's fault-injecting fakes.\n *\n * Not in `core/` (this is a driver), so it may hold concrete state.\n */\nimport { createHash } from 'node:crypto';\nimport { BufferSink } from '../core/blob';\nimport type { BlobSink } from '../core/blob';\nimport { NotFoundError, ValidationError, WriteConflictError } from '../core/errors';\nimport { chunkRefKey, segmentKey, segmentPrefix } from '../core/keys';\nimport { validateChunkRef, validateSegmentRef } from '../core/validate';\nimport { NO_ROW } from '../core/ports';\nimport type {\n ChunkRef,\n ColdCaps,\n ColdChunkSource,\n GenKey,\n IColdDriver,\n IRegistryDriver,\n IWarmDriver,\n NewRegistryRecord,\n NoRow,\n RegCaps,\n RegistryPatch,\n RegistryRecord,\n SegmentRef,\n SegmentSize,\n Token,\n WarmRow,\n} from '../core/ports';\nimport {\n applyRegistryPatch,\n recordFromNew,\n validateNewRegistryRecord,\n validateRegistryPatch,\n} from './_shared/registry';\n\ninterface StoredRow {\n token: Token;\n bytes: Uint8Array;\n chunkKey: number;\n prefix: string;\n}\n\nexport class MemoryWarmDriver implements IWarmDriver {\n private readonly rows = new Map<string, StoredRow>();\n private seq = 0;\n\n // Monotonic, unique-per-write token → equality-safe and ABA-free.\n private nextToken(): Token {\n this.seq += 1;\n return String(this.seq);\n }\n\n // In-memory reads are always strongly consistent — the `WarmReadOptions` hint would be a no-op, so the\n // structurally-optional param is simply omitted (still satisfies IWarmDriver).\n async get(ref: ChunkRef): Promise<WarmRow | null> {\n validateChunkRef(ref);\n const row = this.rows.get(chunkRefKey(ref));\n return row ? { token: row.token, bytes: row.bytes } : null;\n }\n\n async putConditional(\n ref: ChunkRef,\n bytes: Uint8Array,\n expected: Token | NoRow,\n ): Promise<{ token: Token }> {\n validateChunkRef(ref);\n const key = chunkRefKey(ref);\n const existing = this.rows.get(key);\n if (expected === NO_ROW) {\n if (existing) throw new WriteConflictError(`row already exists for chunk ${ref.chunkKey}`);\n } else if (!existing || existing.token !== expected) {\n throw new WriteConflictError(`OCC token mismatch for chunk ${ref.chunkKey}`);\n }\n const token = this.nextToken();\n this.rows.set(key, { token, bytes, chunkKey: ref.chunkKey, prefix: segmentPrefix(ref) });\n return { token };\n }\n\n async deleteConditional(ref: ChunkRef, expected: Token): Promise<void> {\n validateChunkRef(ref);\n const key = chunkRefKey(ref);\n const existing = this.rows.get(key);\n if (!existing || existing.token !== expected) {\n throw new WriteConflictError(`OCC token mismatch for chunk ${ref.chunkKey}`);\n }\n this.rows.delete(key);\n }\n\n async *listChunks(ref: SegmentRef): AsyncIterable<{ chunkKey: number } & WarmRow> {\n validateSegmentRef(ref);\n const prefix = segmentPrefix(ref);\n const rows = [...this.rows.values()].filter((r) => r.prefix === prefix);\n rows.sort((a, b) => a.chunkKey - b.chunkKey); // ascending chunkKey\n for (const row of rows) {\n yield { chunkKey: row.chunkKey, token: row.token, bytes: row.bytes };\n }\n }\n}\n\nexport class MemoryColdChunkSource implements ColdChunkSource {\n private readonly chunks = new Map<string, Uint8Array>();\n\n async getChunk(ref: ChunkRef): Promise<Uint8Array | null> {\n validateChunkRef(ref);\n return this.chunks.get(chunkRefKey(ref)) ?? null;\n }\n\n async listChunkKeys(ref: SegmentRef): Promise<number[]> {\n validateSegmentRef(ref);\n const prefix = segmentPrefix(ref);\n const keys: number[] = [];\n for (const key of this.chunks.keys()) {\n if (key.startsWith(prefix)) keys.push(Number(key.slice(prefix.length)));\n }\n return keys;\n }\n\n async sizeOf(ref: SegmentRef): Promise<SegmentSize | null> {\n validateSegmentRef(ref);\n const prefix = segmentPrefix(ref);\n let sizeBytes = 0;\n let found = false;\n for (const [key, bytes] of this.chunks) {\n if (!key.startsWith(prefix)) continue;\n found = true;\n sizeBytes += bytes.length;\n }\n return found ? { sizeBytes } : null;\n }\n\n /** Test/seed helper — populate immutable Cold bytes for a chunk (no bulk-load path until Phase 3). */\n seed(ref: ChunkRef, bytes: Uint8Array): void {\n validateChunkRef(ref); // keep seed symmetric with the validated read path\n this.chunks.set(chunkRefKey(ref), bytes);\n }\n}\n\nexport interface MemoryRegistryDriverOptions {\n /** Injected clock for `createdAt`/`updatedAt`; defaults to `Date.now` (drivers may use ambient time). */\n readonly now?: () => number;\n}\n\n/**\n * In-memory {@link IRegistryDriver} — one record per segment under OCC. The token is a single global,\n * monotonic, never-reused counter (so a record recreated after `delete` always gets a strictly-greater\n * token → ABA-safe even though `delete` removes the row physically). Mirrors {@link MemoryWarmDriver}.\n */\nexport class MemoryRegistryDriver implements IRegistryDriver {\n private readonly rows = new Map<string, RegistryRecord>();\n private readonly now: () => number;\n private seq = 0;\n\n constructor(options: MemoryRegistryDriverOptions = {}) {\n this.now = options.now ?? (() => Date.now());\n }\n\n private nextToken(): Token {\n this.seq += 1;\n return String(this.seq);\n }\n\n capabilities(): RegCaps {\n return { strongRead: true };\n }\n\n async get(ref: SegmentRef): Promise<RegistryRecord | null> {\n validateSegmentRef(ref);\n const row = this.rows.get(segmentKey(ref));\n return row ? structuredClone(row) : null; // clone out: callers can't mutate stored (nested) state\n }\n\n async create(ref: SegmentRef, record: NewRegistryRecord): Promise<{ token: Token }> {\n validateSegmentRef(ref);\n validateNewRegistryRecord(record);\n const key = segmentKey(ref);\n if (this.rows.has(key)) {\n throw new WriteConflictError(`registry row already exists for segment ${ref.segment}`);\n }\n const token = this.nextToken();\n // clone in: the caller's (nested) retention/residency can't alias stored state (value semantics, parity\n // with the serialize-based persistent drivers).\n this.rows.set(key, structuredClone(recordFromNew(ref, record, this.now(), token)));\n return { token };\n }\n\n async compareAndSwap(\n ref: SegmentRef,\n expected: Token,\n patch: RegistryPatch,\n ): Promise<{ token: Token }> {\n validateSegmentRef(ref);\n validateRegistryPatch(patch);\n const key = segmentKey(ref);\n const existing = this.rows.get(key);\n if (!existing || existing.token !== expected) {\n throw new WriteConflictError(`OCC token mismatch for registry row ${ref.segment}`);\n }\n const token = this.nextToken();\n this.rows.set(key, structuredClone(applyRegistryPatch(existing, patch, this.now(), token)));\n return { token };\n }\n\n async *list(namespace?: string): AsyncIterable<RegistryRecord> {\n for (const row of this.rows.values()) {\n if (namespace === undefined || row.namespace === namespace) yield structuredClone(row);\n }\n }\n\n async delete(ref: SegmentRef): Promise<void> {\n validateSegmentRef(ref);\n this.rows.delete(segmentKey(ref)); // idempotent; token uniqueness is global so a recreate is ABA-safe\n }\n}\n\n/**\n * In-memory {@link IColdDriver} — write-once immutable generation objects as opaque bytes. A \"dumb byte\n * mover\" (understands neither roaring nor `.crbm`), so it's a faithful cold backend for tests, the compaction\n * simulator, and a zero-setup local cold tier. Mirrors the LocalFs/S3 contract (write-once, range/tail reads).\n */\nexport class MemoryColdDriver implements IColdDriver {\n private readonly objects = new Map<string, Uint8Array>();\n\n capabilities(): ColdCaps {\n return { rangeRead: true, maxObjectBytes: Number.MAX_SAFE_INTEGER, conditionalPut: true };\n }\n\n async putImmutable(\n key: GenKey,\n write: (sink: BlobSink) => Promise<void>,\n ): Promise<{ size: number; sha256: string }> {\n const k = genObjectKey(key); // validates ref + generation\n const sink = new BufferSink();\n await write(sink);\n const body = sink.bytes();\n if (this.objects.has(k)) {\n throw new WriteConflictError(\n `generation already exists (write-once): ${key.segment}.${key.generation}`,\n );\n }\n this.objects.set(k, body);\n return { size: body.length, sha256: createHash('sha256').update(body).digest('hex') };\n }\n\n async getRange(key: GenKey, offset: number, length: number): Promise<Uint8Array> {\n if (!Number.isInteger(offset) || !Number.isInteger(length) || offset < 0 || length < 0) {\n throw new ValidationError(`invalid range offset=${offset} length=${length}`);\n }\n const body = this.require(key);\n if (offset + length > body.length) {\n throw new ValidationError(\n `range [${offset}, ${offset + length}) out of bounds for ${body.length}B`,\n );\n }\n return body.slice(offset, offset + length);\n }\n\n async getTail(key: GenKey, maxBytes: number): Promise<{ bytes: Uint8Array; size: number }> {\n const body = this.require(key);\n const take = Math.min(Math.max(maxBytes, 0), body.length);\n return { bytes: body.slice(body.length - take), size: body.length };\n }\n\n async delete(key: GenKey): Promise<void> {\n this.objects.delete(genObjectKey(key)); // idempotent\n }\n\n async *list(ref: SegmentRef): AsyncIterable<GenKey> {\n validateSegmentRef(ref);\n const prefix = `${segmentKey(ref)} `;\n for (const k of this.objects.keys()) {\n if (k.startsWith(prefix)) {\n yield {\n namespace: ref.namespace,\n segment: ref.segment,\n generation: Number(k.slice(prefix.length)),\n };\n }\n }\n }\n\n private require(key: GenKey): Uint8Array {\n const body = this.objects.get(genObjectKey(key));\n if (body === undefined) {\n throw new NotFoundError(`no such generation: ${key.segment}.${key.generation}`);\n }\n return body;\n }\n}\n\n/** Collision-proof object key for a generation: `<segmentKey> <generation>` (space is forbidden in names). */\nfunction genObjectKey(key: GenKey): string {\n validateSegmentRef(key);\n if (!Number.isInteger(key.generation) || key.generation < 0) {\n throw new ValidationError(`generation must be a non-negative integer; got ${key.generation}`);\n }\n return `${segmentKey(key)} ${key.generation}`;\n}\n","/**\n * Logical-ref → filesystem-path mapping for the LocalFs drivers (decision 6).\n *\n * Names are re-validated here at the driver boundary — defense in depth, even though the engine already\n * validates (S2) — so a driver is safe against traversal/injection even if driven directly. The default\n * (absent) namespace maps to `_default`, which can never collide with a real namespace because the name\n * grammar forbids a leading underscore.\n */\nimport { join } from 'node:path';\nimport { ValidationError } from '@/core/errors';\nimport { validateChunkRef, validateSegmentRef } from '@/core/validate';\nimport type { ChunkRef, GenKey, SegmentRef } from '@/core/ports';\nimport { namespacePart } from '../_shared/keys';\n\n/** Directory holding all of a namespace's segment objects. */\nexport function segmentsDir(root: string, ref: SegmentRef): string {\n validateSegmentRef(ref);\n return join(root, namespacePart(ref.namespace), 'segments');\n}\n\n/** Absolute path of one `.crbm` generation object. */\nexport function coldObjectPath(root: string, key: GenKey): string {\n validateSegmentRef(key);\n if (!Number.isInteger(key.generation) || key.generation < 0) {\n throw new ValidationError(`generation must be a non-negative integer; got ${key.generation}`);\n }\n return join(segmentsDir(root, key), `${key.segment}.${key.generation}.crbm`);\n}\n\n/** Filename pattern for a segment's generations: `<segment>.<gen>.crbm`. */\nexport function coldObjectFilename(segment: string, generation: number): string {\n return `${segment}.${generation}.crbm`;\n}\n\n/** Parse a generation number out of a `<segment>.<gen>.crbm` filename, or `null` if it doesn't match. */\nexport function parseGeneration(segment: string, filename: string): number | null {\n const prefix = `${segment}.`;\n const suffix = '.crbm';\n if (!filename.startsWith(prefix) || !filename.endsWith(suffix)) return null;\n const middle = filename.slice(prefix.length, filename.length - suffix.length);\n // Canonical decimal only: no leading zeros (so `s.07.crbm` can't alias `s.7.crbm`), and within\n // safe-integer range. The writer only ever emits the canonical form.\n if (!/^(0|[1-9]\\d*)$/.test(middle)) return null;\n const gen = Number(middle);\n return Number.isSafeInteger(gen) ? gen : null;\n}\n\nconst WARM_ROW_SUFFIX = '.row';\nconst CHUNK_KEY_MAX = 0xffff;\n\n/** Directory holding a segment's Warm rows (one file per dirty chunk). */\nexport function warmSegmentDir(root: string, ref: SegmentRef): string {\n validateSegmentRef(ref);\n return join(root, namespacePart(ref.namespace), 'warm', ref.segment);\n}\n\n/** Absolute path of one chunk's Warm row file. */\nexport function warmRowPath(root: string, ref: ChunkRef): string {\n validateChunkRef(ref); // segment/namespace grammar + chunkKey range, one source of truth\n return join(warmSegmentDir(root, ref), `${ref.chunkKey}${WARM_ROW_SUFFIX}`);\n}\n\nconst REGISTRY_SUFFIX = '.reg';\n\n/** Directory holding a namespace's registry rows (one file per segment). */\nexport function registryDir(root: string, namespace: string | undefined): string {\n return join(root, namespacePart(namespace), 'registry');\n}\n\n/** Absolute path of one segment's registry row file: `<ns>/registry/<segment>.reg`. */\nexport function registryRowPath(root: string, ref: SegmentRef): string {\n validateSegmentRef(ref);\n return join(registryDir(root, ref.namespace), `${ref.segment}${REGISTRY_SUFFIX}`);\n}\n\n/**\n * Parse a segment name out of a `<segment>.reg` filename, or `null` if it doesn't match — including any\n * file whose stem isn't a valid segment name. A stricter parser (mirroring `parseChunkRow`) means a stray\n * or planted `.reg` file makes `list()` *skip* it, never abort the whole enumeration on a boundary throw.\n */\nexport function parseRegistryRow(filename: string): string | null {\n if (!filename.endsWith(REGISTRY_SUFFIX)) return null;\n const segment = filename.slice(0, filename.length - REGISTRY_SUFFIX.length);\n try {\n validateSegmentRef({ segment });\n } catch {\n return null;\n }\n return segment;\n}\n\n/** Parse a chunk key out of a `<chunkKey>.row` filename, or `null` if it doesn't match (canonical only). */\nexport function parseChunkRow(filename: string): number | null {\n if (!filename.endsWith(WARM_ROW_SUFFIX)) return null;\n const middle = filename.slice(0, filename.length - WARM_ROW_SUFFIX.length);\n if (!/^(0|[1-9]\\d*)$/.test(middle)) return null;\n const chunkKey = Number(middle);\n return chunkKey <= CHUNK_KEY_MAX ? chunkKey : null;\n}\n","/**\n * Shared filesystem helpers for the LocalFs drivers (cold/warm, and the Phase-4 registry) — one source\n * of truth for error-code matching, the symlink-refusal flag, and directory durability.\n */\nimport { constants as FS } from 'node:fs';\nimport { open } from 'node:fs/promises';\nimport { TransientError } from '@/core/errors';\n\ninterface NodeError extends Error {\n code?: string;\n}\n\n/** True when `err` is a Node system error with the given `code` (e.g. `'ENOENT'`, `'EEXIST'`). */\nexport const isCode = (err: unknown, code: string): boolean =>\n err instanceof Error && (err as NodeError).code === code;\n\n/**\n * Filesystem error codes that are transient — a retry after a brief backoff often succeeds: the resource is\n * busy (`EBUSY`), the OS asked us to retry (`EAGAIN`), or we hit the open-file-descriptor ceiling\n * (`EMFILE`/`ENFILE`, common under heavy concurrency once earlier handles close). A networked FS may also\n * surface `ETIMEDOUT`.\n */\nconst TRANSIENT_FS_CODES = new Set(['EBUSY', 'EAGAIN', 'EMFILE', 'ENFILE', 'ETIMEDOUT']);\n\nexport const isFsTransient = (err: unknown): boolean =>\n err instanceof Error && TRANSIENT_FS_CODES.has((err as NodeError).code ?? '');\n\n/**\n * Reclassify a transient filesystem fault as a retryable {@link TransientError} (so the retry decorator can\n * ride it out); everything else — including the driver's own typed errors — propagates unchanged.\n */\nexport const mapFsError = (err: unknown): unknown =>\n isFsTransient(err)\n ? new TransientError(`transient filesystem fault: ${(err as NodeError).code}`, { cause: err })\n : err;\n\n/**\n * `O_NOFOLLOW` where the platform supports it (absent on Windows → 0). OR it into an `open` flag set so a\n * symlink **at the final path component** is refused rather than followed outside the storage root.\n * Containment of symlinked *directory* components assumes the root itself is not attacker-writable.\n */\nexport const O_NOFOLLOW = FS.O_NOFOLLOW ?? 0;\n\n/** Best-effort parent-directory fsync so a just-published `rename`/`link` survives a crash (C13). */\nexport async function fsyncDir(dir: string): Promise<void> {\n try {\n const handle = await open(dir, 'r');\n try {\n await handle.sync();\n } finally {\n await handle.close();\n }\n } catch {\n // Some platforms reject directory fsync; durability of the entry is then best-effort.\n }\n}\n","/**\n * `LocalFsColdDriver` — a zero-cloud {@link IColdDriver} backed by the local filesystem.\n *\n * Generations are write-once immutable files. A new object is streamed to a temp file (with its content\n * hashed in-flight), `fsync`-ed, then published with an atomic `link` that fails if the destination\n * already exists — so a generation can never be silently overwritten, and a crash leaves only an orphan\n * temp file, never a torn object (C13). Drivers do filesystem I/O and may use `node:crypto`; only `core/`\n * is bound by the determinism lint.\n */\nimport { constants as FS } from 'node:fs';\nimport { createHash, randomUUID } from 'node:crypto';\nimport { link, mkdir, open, readdir, unlink } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { NotFoundError, ValidationError, WriteConflictError } from '@/core/errors';\nimport type { BlobSink } from '@/core/blob';\nimport type { ColdCaps, GenKey, IColdDriver, SegmentRef } from '@/core/ports';\nimport { coldObjectPath, parseGeneration, segmentsDir } from './paths';\nimport { O_NOFOLLOW, fsyncDir, isCode, mapFsError } from './fs-util';\n\nexport class LocalFsColdDriver implements IColdDriver {\n constructor(private readonly root: string) {}\n\n capabilities(): ColdCaps {\n return { rangeRead: true, maxObjectBytes: Number.MAX_SAFE_INTEGER, conditionalPut: false };\n }\n\n async putImmutable(\n key: GenKey,\n write: (sink: BlobSink) => Promise<void>,\n ): Promise<{ size: number; sha256: string }> {\n const finalPath = coldObjectPath(this.root, key);\n await mkdir(dirname(finalPath), { recursive: true });\n\n const tmpPath = `${finalPath}.${randomUUID()}.tmp`;\n // 'wx' = O_CREAT|O_EXCL|O_WRONLY; add O_NOFOLLOW so a pre-planted symlink can't redirect the write.\n const handle = await open(tmpPath, FS.O_CREAT | FS.O_EXCL | FS.O_WRONLY | O_NOFOLLOW);\n const hash = createHash('sha256');\n let size = 0;\n const sink: BlobSink = {\n async write(bytes) {\n await handle.write(bytes);\n hash.update(bytes);\n size += bytes.length;\n },\n };\n\n try {\n await write(sink);\n await handle.sync();\n } catch (err) {\n await handle.close().catch(() => {});\n await unlink(tmpPath).catch(() => {});\n throw mapFsError(err);\n }\n await handle.close();\n\n // Atomic write-once publish: link fails with EEXIST if the generation already exists.\n try {\n await link(tmpPath, finalPath);\n } catch (err) {\n await unlink(tmpPath).catch(() => {});\n if (isCode(err, 'EEXIST')) {\n // A generation is write-once; a collision is a concurrency/state condition, not bad input.\n // Identify it by the logical key only — never leak the absolute filesystem path.\n throw new WriteConflictError(\n `generation already exists (write-once): ${key.segment}.${key.generation}`,\n );\n }\n throw mapFsError(err);\n }\n await unlink(tmpPath).catch(() => {});\n await fsyncDir(dirname(finalPath));\n return { size, sha256: hash.digest('hex') };\n }\n\n async getRange(key: GenKey, offset: number, length: number): Promise<Uint8Array> {\n if (!Number.isInteger(offset) || !Number.isInteger(length) || offset < 0 || length < 0) {\n throw new ValidationError(`invalid range offset=${offset} length=${length}`);\n }\n const handle = await this.openRead(key);\n try {\n const { size } = await handle.stat();\n if (offset + length > size) {\n throw new ValidationError(\n `range [${offset}, ${offset + length}) out of bounds for ${size}B`,\n );\n }\n const buf = Buffer.alloc(length);\n if (length > 0) await handle.read(buf, 0, length, offset);\n return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);\n } finally {\n await handle.close();\n }\n }\n\n async getTail(key: GenKey, maxBytes: number): Promise<{ bytes: Uint8Array; size: number }> {\n const handle = await this.openRead(key);\n try {\n const { size } = await handle.stat();\n const take = Math.min(Math.max(maxBytes, 0), size);\n const buf = Buffer.alloc(take);\n if (take > 0) await handle.read(buf, 0, take, size - take);\n return { bytes: new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength), size };\n } finally {\n await handle.close();\n }\n }\n\n async delete(key: GenKey): Promise<void> {\n // Idempotent: deleting an absent generation is a no-op (GC may race / retry).\n await unlink(coldObjectPath(this.root, key)).catch((err) => {\n if (!isCode(err, 'ENOENT')) throw mapFsError(err);\n });\n }\n\n async *list(ref: SegmentRef): AsyncIterable<GenKey> {\n const dir = segmentsDir(this.root, ref);\n let names: string[];\n try {\n names = await readdir(dir);\n } catch (err) {\n if (isCode(err, 'ENOENT')) return; // no generations yet\n throw mapFsError(err);\n }\n for (const name of names) {\n const generation = parseGeneration(ref.segment, name);\n if (generation !== null) {\n yield { namespace: ref.namespace, segment: ref.segment, generation };\n }\n }\n }\n\n private async openRead(key: GenKey): Promise<Awaited<ReturnType<typeof open>>> {\n try {\n return await open(coldObjectPath(this.root, key), FS.O_RDONLY | O_NOFOLLOW);\n } catch (err) {\n if (isCode(err, 'ENOENT')) {\n throw new NotFoundError(`no such generation: ${key.segment}.${key.generation}`);\n }\n // A symlink at the object path is rejected (ELOOP) — treat as not-found, don't follow it.\n if (isCode(err, 'ELOOP')) {\n throw new NotFoundError(\n `generation path is a symlink, refusing: ${key.segment}.${key.generation}`,\n );\n }\n throw mapFsError(err);\n }\n }\n}\n","/**\n * `LocalFsWarmDriver` — a zero-cloud, persistent {@link IWarmDriver} backed by the local filesystem.\n *\n * One file per dirty chunk holds `[u32 counter][u8 deleted][payload]` (an internal, unversioned row —\n * it never leaves the local FS and the driver is its sole reader/writer). The OCC token is the counter\n * stringified — monotonic, never reused: it advances even across a delete (via a **tombstone**), so a\n * deleted-then-recreated row never re-issues an old token (ABA-safe). Every mutation is\n * write-temp → fsync(file) → atomic rename → fsync(dir), and read-modify-write is serialized per row\n * in-process so concurrent writers form a single CAS chain with no lost updates. (Cross-*process* CAS on\n * a local FS is out of scope — the production OCC backends are DynamoDB et al.; LocalFs is the dev/test\n * tier. `WarmCaps`/`capabilities()` + batch paths are likewise deferred with topology validation →\n * Phase 4.)\n */\nimport { constants as FS } from 'node:fs';\nimport { randomUUID } from 'node:crypto';\nimport { mkdir, open, readdir, rename, unlink } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { IntegrityError, WriteConflictError } from '@/core/errors';\nimport { NO_ROW } from '@/core/ports';\nimport type { ChunkRef, IWarmDriver, NoRow, SegmentRef, Token, WarmRow } from '@/core/ports';\nimport { parseChunkRow, warmRowPath, warmSegmentDir } from './paths';\nimport { O_NOFOLLOW, fsyncDir, isCode, mapFsError } from './fs-util';\n\nconst HEADER_BYTES = 5; // u32 counter (LE) + u8 deleted flag\nconst COUNTER_MAX = 0xffffffff; // token counter is stored as a u32\n/** Defensive cap on a single row read from (untrusted) storage, before allocation. */\nconst DEFAULT_MAX_ROW_BYTES = 64 * 1024 * 1024;\n\ninterface Row {\n readonly counter: number;\n readonly deleted: boolean;\n readonly bytes: Uint8Array;\n}\n\nexport class LocalFsWarmDriver implements IWarmDriver {\n /** Per-row promise chain — serializes read-modify-write so an in-process CAS never loses an update. */\n private readonly chain = new Map<string, Promise<unknown>>();\n\n constructor(\n private readonly root: string,\n private readonly maxRowBytes: number = DEFAULT_MAX_ROW_BYTES,\n ) {}\n\n // Methods are `async` so boundary-validation throws (warmRowPath) surface as rejections, not sync throws.\n // LocalFs reads are always strongly consistent (single filesystem) — the `WarmReadOptions` hint would be a\n // no-op, so the structurally-optional param is simply omitted (still satisfies IWarmDriver).\n async get(ref: ChunkRef): Promise<WarmRow | null> {\n const row = await this.readRow(warmRowPath(this.root, ref));\n return row && !row.deleted ? { token: String(row.counter), bytes: row.bytes } : null;\n }\n\n async putConditional(\n ref: ChunkRef,\n bytes: Uint8Array,\n expected: Token | NoRow,\n ): Promise<{ token: Token }> {\n const path = warmRowPath(this.root, ref);\n return this.withRowLock(path, async () => {\n const current = await this.readRow(path);\n const live = current !== null && !current.deleted;\n if (expected === NO_ROW) {\n if (live) throw new WriteConflictError(`row already exists: chunk ${ref.chunkKey}`);\n const counter = current ? current.counter + 1 : 0; // advance across a tombstone (ABA-safe)\n await this.writeRow(path, counter, false, bytes);\n return { token: String(counter) };\n }\n if (!live || String(current.counter) !== expected) {\n throw new WriteConflictError(`OCC conflict on chunk ${ref.chunkKey}`);\n }\n await this.writeRow(path, current.counter + 1, false, bytes);\n return { token: String(current.counter + 1) };\n });\n }\n\n async deleteConditional(ref: ChunkRef, expected: Token): Promise<void> {\n const path = warmRowPath(this.root, ref);\n return this.withRowLock(path, async () => {\n const current = await this.readRow(path);\n if (current === null || current.deleted || String(current.counter) !== expected) {\n throw new WriteConflictError(`OCC conflict on delete of chunk ${ref.chunkKey}`);\n }\n // Tombstone (keep the counter advancing) rather than unlink — preserves ABA-safety.\n await this.writeRow(path, current.counter + 1, true, new Uint8Array());\n });\n }\n\n async *listChunks(ref: SegmentRef): AsyncIterable<{ chunkKey: number } & WarmRow> {\n const dir = warmSegmentDir(this.root, ref);\n let names: string[];\n try {\n names = await readdir(dir);\n } catch (err) {\n if (isCode(err, 'ENOENT')) return;\n throw mapFsError(err);\n }\n // Ascending chunkKey order. readdir order is unspecified, so sort.\n const keys = names\n .map((n) => parseChunkRow(n))\n .filter((k): k is number => k !== null)\n .sort((a, b) => a - b);\n for (const chunkKey of keys) {\n const row = await this.readRow(warmRowPath(this.root, { ...ref, chunkKey }));\n if (row && !row.deleted) yield { chunkKey, token: String(row.counter), bytes: row.bytes };\n }\n }\n\n private async readRow(path: string): Promise<Row | null> {\n let handle;\n try {\n handle = await open(path, FS.O_RDONLY | O_NOFOLLOW);\n } catch (err) {\n if (isCode(err, 'ENOENT') || isCode(err, 'ELOOP')) return null;\n throw mapFsError(err);\n }\n try {\n const { size } = await handle.stat();\n if (size > this.maxRowBytes) {\n throw new IntegrityError(`warm row ${size}B exceeds cap ${this.maxRowBytes}B`);\n }\n // A published row is always whole (atomic rename of a fully-written temp); a shorter-than-header\n // file means corruption/tampering — fail fast rather than silently reporting \"absent\".\n if (size < HEADER_BYTES) {\n throw new IntegrityError(`warm row truncated: ${size}B < ${HEADER_BYTES}B header`);\n }\n const buf = await handle.readFile();\n const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);\n return {\n counter: view.getUint32(0, true),\n deleted: buf[4] !== 0,\n bytes: new Uint8Array(buf.subarray(HEADER_BYTES)),\n };\n } finally {\n await handle.close();\n }\n }\n\n private async writeRow(\n path: string,\n counter: number,\n deleted: boolean,\n bytes: Uint8Array,\n ): Promise<void> {\n if (counter > COUNTER_MAX) {\n // 4 billion writes to one chunk — astronomically unreachable, but guard rather than wrap a u32\n // (which would re-issue an old token and break ABA-safety).\n throw new IntegrityError(`warm row counter overflow on ${path}`);\n }\n await mkdir(dirname(path), { recursive: true });\n const out = new Uint8Array(HEADER_BYTES + bytes.length);\n new DataView(out.buffer).setUint32(0, counter, true);\n out[4] = deleted ? 1 : 0;\n out.set(bytes, HEADER_BYTES);\n\n const tmp = `${path}.${randomUUID()}.tmp`;\n let handle;\n try {\n handle = await open(tmp, FS.O_CREAT | FS.O_EXCL | FS.O_WRONLY | O_NOFOLLOW);\n } catch (err) {\n throw mapFsError(err); // e.g. EMFILE under heavy concurrency — retryable\n }\n try {\n await handle.write(out);\n await handle.sync();\n } finally {\n await handle.close();\n }\n // Atomic replace (rows are mutable, unlike write-once Cold objects); rename replaces a symlink at\n // `path` rather than following it.\n await rename(tmp, path).catch(async (err) => {\n await unlink(tmp).catch(() => {});\n throw mapFsError(err);\n });\n await fsyncDir(dirname(path)); // make the directory-entry update durable (C13 parity with Cold)\n }\n\n /**\n * Serialize callbacks for a given row path so read-modify-write is atomic in-process. `prev.then(fn,\n * fn)` runs `fn` regardless of whether the predecessor fulfilled or rejected — a conflict on one\n * writer must not stall the row's chain.\n */\n private withRowLock<T>(key: string, fn: () => Promise<T>): Promise<T> {\n const prev = this.chain.get(key) ?? Promise.resolve();\n const result = prev.then(fn, fn);\n const tail = result.then(\n () => undefined,\n () => undefined,\n );\n this.chain.set(key, tail);\n void tail.then(() => {\n if (this.chain.get(key) === tail) this.chain.delete(key);\n });\n return result;\n }\n}\n","/**\n * `LocalFsRegistryDriver` — a zero-cloud, persistent {@link IRegistryDriver} (Phase 4c).\n *\n * One JSON file per segment at `<root>/<namespace>/registry/<segment>.reg`, holding `{ deleted, record }`.\n * OCC mirrors the Warm tier: the token is a monotonic counter (stringified), advanced on every mutation and\n * even across a `delete` (which **tombstones** rather than unlinks) so a deleted-then-recreated row never\n * re-issues an old token (ABA-safe). Every write is temp → fsync(file) → atomic rename → fsync(dir), and\n * read-modify-write is serialized per row in-process. Drivers do I/O; only `core/` is bound by determinism.\n */\nimport { constants as FS } from 'node:fs';\nimport { randomUUID } from 'node:crypto';\nimport { mkdir, open, readdir, rename, unlink } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { IntegrityError, ValidationError, WriteConflictError } from '@/core/errors';\nimport type {\n IRegistryDriver,\n NewRegistryRecord,\n RegCaps,\n RegistryPatch,\n RegistryRecord,\n SegmentRef,\n Token,\n} from '@/core/ports';\nimport {\n applyRegistryPatch,\n parseRegistryEnvelope,\n recordFromNew,\n registryCounterOf,\n serializeRegistryEnvelope,\n validateNewRegistryRecord,\n validateRegistryPatch,\n type RegistryEnvelope,\n} from '../_shared/registry';\nimport { registryDir, registryRowPath, parseRegistryRow } from './paths';\nimport { O_NOFOLLOW, fsyncDir, isCode, mapFsError } from './fs-util';\n\n/** Defensive cap on a single registry file read from storage, before allocation. */\nconst DEFAULT_MAX_ROW_BYTES = 1 * 1024 * 1024;\n\nexport interface LocalFsRegistryDriverOptions {\n /** Injected clock for `createdAt`/`updatedAt`; defaults to `Date.now`. */\n readonly now?: () => number;\n}\n\nexport class LocalFsRegistryDriver implements IRegistryDriver {\n /** Per-row promise chain — serializes read-modify-write so an in-process CAS never loses an update. */\n private readonly chain = new Map<string, Promise<unknown>>();\n private readonly now: () => number;\n\n constructor(\n private readonly root: string,\n options: LocalFsRegistryDriverOptions = {},\n ) {\n this.now = options.now ?? (() => Date.now());\n }\n\n capabilities(): RegCaps {\n return { strongRead: true };\n }\n\n async get(ref: SegmentRef): Promise<RegistryRecord | null> {\n const env = await this.readRow(registryRowPath(this.root, ref));\n return env && !env.deleted ? env.record : null;\n }\n\n async create(ref: SegmentRef, record: NewRegistryRecord): Promise<{ token: Token }> {\n validateNewRegistryRecord(record);\n const path = registryRowPath(this.root, ref);\n return this.withRowLock(path, async () => {\n const current = await this.readRow(path);\n if (current !== null && !current.deleted) {\n throw new WriteConflictError(`registry row already exists for segment ${ref.segment}`);\n }\n const counter = current ? registryCounterOf(current.record) + 1 : 0; // advance across a tombstone (ABA-safe)\n const token = String(counter);\n await this.writeRow(path, false, recordFromNew(ref, record, this.now(), token));\n return { token };\n });\n }\n\n async compareAndSwap(\n ref: SegmentRef,\n expected: Token,\n patch: RegistryPatch,\n ): Promise<{ token: Token }> {\n validateRegistryPatch(patch);\n const path = registryRowPath(this.root, ref);\n return this.withRowLock(path, async () => {\n const current = await this.readRow(path);\n if (current === null || current.deleted || current.record.token !== expected) {\n throw new WriteConflictError(`OCC token mismatch for registry row ${ref.segment}`);\n }\n const token = String(registryCounterOf(current.record) + 1);\n await this.writeRow(\n path,\n false,\n applyRegistryPatch(current.record, patch, this.now(), token),\n );\n return { token };\n });\n }\n\n async *list(namespace?: string): AsyncIterable<RegistryRecord> {\n for (const ns of await this.namespaceDirs(namespace)) {\n const dir = registryDir(this.root, ns);\n let names: string[];\n try {\n names = await readdir(dir);\n } catch (err) {\n if (isCode(err, 'ENOENT')) continue; // no registry rows in this namespace yet\n throw mapFsError(err);\n }\n for (const name of names) {\n const segment = parseRegistryRow(name);\n if (segment === null) continue;\n const env = await this.readRow(registryRowPath(this.root, { namespace: ns, segment }));\n if (env && !env.deleted) yield env.record;\n }\n }\n }\n\n async delete(ref: SegmentRef): Promise<void> {\n const path = registryRowPath(this.root, ref);\n return this.withRowLock(path, async () => {\n const current = await this.readRow(path);\n if (current === null || current.deleted) return; // idempotent\n // Tombstone (advance the counter) rather than unlink — keeps the token monotonic for ABA-safety.\n const token = String(registryCounterOf(current.record) + 1);\n await this.writeRow(path, true, { ...current.record, token, updatedAt: this.now() });\n });\n }\n\n /** Namespaces to scan: just the one requested, or every namespace dir under the root. */\n private async namespaceDirs(namespace: string | undefined): Promise<Array<string | undefined>> {\n if (namespace !== undefined) return [namespace];\n let entries: string[];\n try {\n entries = await readdir(this.root);\n } catch (err) {\n if (isCode(err, 'ENOENT')) return [];\n throw mapFsError(err);\n }\n // A namespace dir name IS the namespace; the `_default` sentinel dir maps back to \"no namespace\".\n return entries.map((e) => (e === '_default' ? undefined : e));\n }\n\n private async readRow(path: string): Promise<RegistryEnvelope | null> {\n let handle;\n try {\n handle = await open(path, FS.O_RDONLY | O_NOFOLLOW);\n } catch (err) {\n if (isCode(err, 'ENOENT') || isCode(err, 'ELOOP')) return null;\n throw mapFsError(err);\n }\n try {\n const { size } = await handle.stat();\n if (size > DEFAULT_MAX_ROW_BYTES) {\n throw new IntegrityError(`registry row ${size}B exceeds cap ${DEFAULT_MAX_ROW_BYTES}B`);\n }\n const text = (await handle.readFile()).toString('utf8');\n return parseRegistryEnvelope(text, path);\n } finally {\n await handle.close();\n }\n }\n\n private async writeRow(path: string, deleted: boolean, record: RegistryRecord): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n const out = Buffer.from(serializeRegistryEnvelope({ deleted, record }), 'utf8');\n // Cap on the write path too (the read path caps at the same size): never produce a row that would later\n // be unreadable. The governance fields are already capped by validate*, so this is a belt-and-braces guard.\n if (out.length > DEFAULT_MAX_ROW_BYTES) {\n throw new ValidationError(\n `registry row ${out.length}B exceeds cap ${DEFAULT_MAX_ROW_BYTES}B`,\n );\n }\n\n const tmp = `${path}.${randomUUID()}.tmp`;\n let handle;\n try {\n handle = await open(tmp, FS.O_CREAT | FS.O_EXCL | FS.O_WRONLY | O_NOFOLLOW);\n } catch (err) {\n throw mapFsError(err);\n }\n try {\n await handle.write(out);\n await handle.sync();\n } finally {\n await handle.close();\n }\n await rename(tmp, path).catch(async (err) => {\n await unlink(tmp).catch(() => {});\n throw mapFsError(err);\n });\n await fsyncDir(dirname(path));\n }\n\n /** Serialize callbacks for a row path so read-modify-write is atomic in-process (mirrors the Warm tier). */\n private withRowLock<T>(key: string, fn: () => Promise<T>): Promise<T> {\n const prev = this.chain.get(key) ?? Promise.resolve();\n const result = prev.then(fn, fn);\n const tail = result.then(\n () => undefined,\n () => undefined,\n );\n this.chain.set(key, tail);\n void tail.then(() => {\n if (this.chain.get(key) === tail) this.chain.delete(key);\n });\n return result;\n }\n}\n","/**\n * Concrete AES-256-GCM crypto (lives outside `core/`, which lint-bans `node:crypto`). Implements the injected\n * {@link Aead}/{@link IKeystore} seams from `core/crypto`: a `NodeAead` over `aes-256-gcm`, and an in-process\n * **BYOK** keystore that envelope-wraps a per-segment DEK under one or more operator-held KEKs.\n *\n * Default, dependency-free key management: you bring 32-byte KEK(s); we never call a cloud service. KMS/Vault\n * are future optional adapters against the same {@link IKeystore} interface (DECISIONS #19). **The KEK is the\n * one secret to back up** — lose it and that segment's at-rest bytes are unrecoverable by design (re-seed the\n * segment from your source of truth); see the getting-started \"Encryption\" section.\n */\nimport { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';\nimport type { Aead, AeadSealed, IKeystore, WrappedDek } from '../core/crypto';\nimport { IntegrityError, KeyUnavailableError, ValidationError } from '../core/errors';\n\nconst KEY_BYTES = 32; // AES-256\nconst NONCE_BYTES = 12; // GCM standard nonce\nconst TAG_BYTES = 16; // GCM tag\n\n/** AES-256-GCM AEAD bound to one 32-byte key. A fresh CSPRNG 96-bit nonce per `seal`; `aad` is authenticated,\n * never stored. Nonce-reuse safety: the random-96-bit birthday bound is ~q²/2⁹⁷, negligible below ~2³² seals\n * under one key. A per-segment DEK is **reused across all generations** (compaction re-encrypts under it), so\n * seal count is cumulative over the segment's life — a segment approaching ~2³² lifetime chunk-seals should be\n * re-seeded (a fresh segment ⇒ fresh DEK). Far beyond any realistic workload; noted for completeness. */\nexport class NodeAead implements Aead {\n private readonly key: Buffer;\n\n constructor(key: Uint8Array) {\n if (key.length !== KEY_BYTES)\n throw new ValidationError(`AEAD key must be ${KEY_BYTES} bytes, got ${key.length}`);\n this.key = Buffer.from(key);\n }\n\n seal(plaintext: Uint8Array, aad: Uint8Array): AeadSealed {\n const nonce = randomBytes(NONCE_BYTES);\n const cipher = createCipheriv('aes-256-gcm', this.key, nonce);\n cipher.setAAD(aad);\n const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);\n return { nonce, ciphertext, tag: cipher.getAuthTag() };\n }\n\n open(sealed: AeadSealed, aad: Uint8Array): Uint8Array {\n if (sealed.nonce.length !== NONCE_BYTES || sealed.tag.length !== TAG_BYTES)\n throw new IntegrityError('AEAD nonce/tag have the wrong length');\n const decipher = createDecipheriv('aes-256-gcm', this.key, sealed.nonce);\n decipher.setAAD(aad);\n decipher.setAuthTag(Buffer.from(sealed.tag));\n try {\n return Buffer.concat([decipher.update(sealed.ciphertext), decipher.final()]);\n } catch {\n // Wrong key, tampered ciphertext/tag, or mismatched AAD — never leak which, never return plaintext.\n throw new IntegrityError(\n 'AEAD authentication failed (wrong key, tampered data, or wrong context)',\n );\n }\n }\n}\n\n/** Wrap/unwrap a DEK under a KEK with AES-256-GCM, binding the wrapping to its `keyId` via AAD so a wrapping\n * can't be relabelled to another KEK. Stored blob = nonce ‖ ciphertext ‖ tag, base64. */\nfunction wrapKey(dek: Uint8Array, kek: Uint8Array, keyId: string): string {\n const sealed = new NodeAead(kek).seal(dek, new TextEncoder().encode(keyId));\n return Buffer.concat([sealed.nonce, sealed.ciphertext, sealed.tag]).toString('base64');\n}\n\nfunction unwrapKey(wrapped: string, kek: Uint8Array, keyId: string): Uint8Array {\n const blob = Buffer.from(wrapped, 'base64');\n if (blob.length < NONCE_BYTES + TAG_BYTES)\n throw new IntegrityError('wrapped DEK is too short to be valid');\n const nonce = blob.subarray(0, NONCE_BYTES);\n const tag = blob.subarray(blob.length - TAG_BYTES);\n const ciphertext = blob.subarray(NONCE_BYTES, blob.length - TAG_BYTES);\n return new NodeAead(kek).open({ nonce, ciphertext, tag }, new TextEncoder().encode(keyId));\n}\n\n/**\n * Options for {@link InProcessKeystore}. `keys` maps a `keyId` → its 32-byte KEK; `activeKeyId` names the KEK\n * new DEKs are wrapped under; an optional `recoveryKeyId` additionally wraps each new DEK under a second\n * (e.g. offline) KEK, so losing the active KEK isn't fatal. Rotating the active KEK needs no data\n * re-encryption: add the new KEK, point `activeKeyId` at it, keep the old one to unwrap existing segments.\n */\nexport interface InProcessKeystoreOptions {\n readonly keys: Readonly<Record<string, Uint8Array>>;\n readonly activeKeyId: string;\n readonly recoveryKeyId?: string;\n}\n\n/**\n * Dependency-free BYOK keystore: envelope-wraps a fresh random per-segment DEK under the active (and optional\n * recovery) KEK using `node:crypto`. No external service. The raw DEK never leaves a returned {@link NodeAead}.\n */\nexport class InProcessKeystore implements IKeystore {\n private readonly keys: Map<string, Uint8Array>;\n private readonly activeKeyId: string;\n private readonly recoveryKeyId: string | undefined;\n\n constructor(options: InProcessKeystoreOptions) {\n const entries = Object.entries(options.keys);\n if (entries.length === 0) throw new ValidationError('keystore needs at least one KEK');\n for (const [id, k] of entries) {\n if (k.length !== KEY_BYTES)\n throw new ValidationError(`KEK \"${id}\" must be ${KEY_BYTES} bytes, got ${k.length}`);\n }\n if (!(options.activeKeyId in options.keys))\n throw new ValidationError(`activeKeyId \"${options.activeKeyId}\" is not in keys`);\n if (options.recoveryKeyId !== undefined && !(options.recoveryKeyId in options.keys))\n throw new ValidationError(`recoveryKeyId \"${options.recoveryKeyId}\" is not in keys`);\n this.keys = new Map(entries.map(([id, k]) => [id, Buffer.from(k)]));\n this.activeKeyId = options.activeKeyId;\n this.recoveryKeyId =\n options.recoveryKeyId === options.activeKeyId ? undefined : options.recoveryKeyId;\n }\n\n // async to satisfy the IKeystore seam (a KMS adapter awaits a network call here); the in-process path is\n // synchronous, but staying async keeps unwrap failures as rejections, matching a remote keystore.\n async createDek(): Promise<{ wrapped: WrappedDek[]; aead: Aead }> {\n const dek = randomBytes(KEY_BYTES);\n const ids = this.recoveryKeyId ? [this.activeKeyId, this.recoveryKeyId] : [this.activeKeyId];\n const wrapped = ids.map((keyId) => ({\n keyId,\n wrapped: wrapKey(dek, this.keys.get(keyId)!, keyId),\n }));\n return { wrapped, aead: new NodeAead(dek) };\n }\n\n // async for the same reason as createDek — a synchronous unwrap failure surfaces as a promise rejection.\n async openDek(wrapped: readonly WrappedDek[]): Promise<Aead> {\n // Try EVERY held wrapping, not just the first: a DEK is wrapped under both the active KEK and (if\n // configured) the offline recovery KEK precisely so a damaged/tampered active-KEK wrapping can be\n // recovered from the other. Returning on the first held keyId and letting a corrupt unwrap throw would\n // defeat that insurance — the recovery wrapping would never be attempted. So catch a failed unwrap and\n // fall through to the next held wrapping; only give up once none succeeds.\n let anyKekHeld = false;\n let lastUnwrapError: unknown;\n for (const w of wrapped) {\n const kek = this.keys.get(w.keyId);\n if (kek === undefined) continue;\n anyKekHeld = true;\n try {\n return new NodeAead(unwrapKey(w.wrapped, kek, w.keyId));\n } catch (err) {\n lastUnwrapError = err; // held KEK but this wrapping is corrupt/tampered — try the next one\n }\n }\n // A KEK WAS held but every held wrapping failed to unwrap → the wrapping(s) are corrupt/tampered, not\n // missing. Surface that integrity failure in its original type rather than masking it as \"no held KEK\".\n if (anyKekHeld) throw lastUnwrapError;\n const have = [...this.keys.keys()].join(', ') || '(none)';\n const need = wrapped.map((w) => w.keyId).join(', ') || '(none)';\n throw new KeyUnavailableError(\n `no held KEK can unwrap this DEK — have [${have}], wrappings reference [${need}]. ` +\n `Restore the missing KEK (or its recovery KEK), or rebuild the segment from source.`,\n );\n }\n}\n","/**\n * Crypto-shred erasure (Phase 4e, [DECISIONS #19]).\n *\n * GDPR \"right to erasure\" on immutable/backed-up Cold storage: you can't delete a `.crbm` object from every\n * backup, but you can **delete its key**. `destroySegment` drops the segment's wrapped DEK(s) from the registry\n * (a CAS to a `destroyed` tombstone) — the encrypted Cold bytes are then permanently unreadable, everywhere,\n * forever — and physically deletes the segment's (cleartext) Warm rows. **Immediate + irreversible**, so it's\n * gated behind an explicit confirmation (name the exact segment/namespace). A `destroyed` segment reads as\n * empty (its DEK is gone). Only works on an **encrypted** segment; a cleartext segment has no key to shred.\n *\n * Note (scope): this shreds the Cold key + clears Warm rows present *now*. Preventing *new* writes to a\n * destroyed segment (a registry-checked write path) is a later hardening; the write path stays uncoupled today.\n */\nimport { type IAuditSink, NOOP_AUDIT, safeAudit } from './audit';\nimport { ValidationError, WriteConflictError, isWriteConflictError } from './errors';\nimport type { ChunkRef, IRegistryDriver, IWarmDriver, SegmentRef } from './ports';\n\nexport interface EraseDeps {\n readonly registry: IRegistryDriver;\n readonly warm: IWarmDriver;\n}\n\nexport interface DestroyResult {\n readonly segment: string;\n readonly namespace?: string;\n /** True iff the segment is now a `destroyed` tombstone (incl. the idempotent already-destroyed case). */\n readonly destroyed: boolean;\n /**\n * True iff **this call** performed a genuine crypto-shred — an encrypted segment whose wrapped DEK(s) were\n * dropped, so its Cold bytes are now permanently unreadable. False for a cleartext tombstone (bytes remain\n * readable), for the idempotent already-destroyed case, and for an absent segment. This is what the\n * `segment.erase` audit event keys off — a cleartext \"erase\" is not an irreversible destruction.\n */\n readonly cryptoShredded: boolean;\n /** `'absent'` (no registry row), `'already'` (already destroyed), or `'cleartext'` (no DEK to shred). */\n readonly reason?: string;\n /** Warm rows physically deleted as part of the erase. */\n readonly warmRowsDeleted: number;\n}\n\nconst MAX_CAS_ATTEMPTS = 8;\nconst MAX_WARM_PASSES = 4;\n\n/**\n * Crypto-shred one segment. **Irreversible.** `confirmSegment` must equal `ref.segment` (a guard against an\n * accidental destroy — you must name the exact segment). A non-encrypted segment is rejected unless you opt in\n * via `allowCleartext` (there's no key to shred; its Cold bytes stay readable, only Warm is cleared).\n */\nexport async function destroySegment(\n ref: SegmentRef,\n deps: EraseDeps,\n options: { confirmSegment: string; allowCleartext?: boolean; audit?: IAuditSink },\n): Promise<DestroyResult> {\n if (options.confirmSegment !== ref.segment) {\n throw new ValidationError(\n `destroySegment: confirmSegment must equal the segment name \"${ref.segment}\" (guard against accidental crypto-shred)`,\n );\n }\n const result = await shredSegment(ref, deps, options.allowCleartext ?? false);\n // Audit only a genuine crypto-shred — not the idempotent already-destroyed/absent no-ops, and not a\n // cleartext tombstone (whose Cold bytes stay readable, so it is not an irreversible erasure).\n if (result.cryptoShredded) {\n safeAudit(options.audit ?? NOOP_AUDIT).onEvent({\n kind: 'segment.erase',\n namespace: ref.namespace,\n segment: ref.segment,\n });\n }\n return result;\n}\n\n/**\n * Crypto-shred every segment in a namespace. **Irreversible.** `confirmNamespace` must equal `namespace`.\n * Returns a per-segment result (skips cleartext segments unless `allowCleartext`).\n */\nexport async function eraseNamespace(\n namespace: string,\n deps: EraseDeps,\n options: { confirmNamespace: string; allowCleartext?: boolean; audit?: IAuditSink },\n): Promise<{ destroyed: DestroyResult[] }> {\n if (typeof namespace !== 'string' || namespace.length === 0) {\n throw new ValidationError('eraseNamespace: namespace must be a non-empty string');\n }\n if (options.confirmNamespace !== namespace) {\n throw new ValidationError(\n `eraseNamespace: confirmNamespace must equal the namespace \"${namespace}\" (guard against accidental erasure)`,\n );\n }\n const refs: SegmentRef[] = [];\n for await (const rec of deps.registry.list(namespace)) {\n refs.push({ namespace: rec.namespace, segment: rec.segment });\n }\n const audit = safeAudit(options.audit ?? NOOP_AUDIT);\n const destroyed: DestroyResult[] = [];\n let segmentsShredded = 0;\n for (const ref of refs) {\n const result = await shredSegment(ref, deps, options.allowCleartext ?? false);\n destroyed.push(result);\n // A per-segment record for each genuine crypto-shred, so the trail can prove *which* segments were\n // destroyed (each carries the namespace) — not just that the command ran.\n if (result.cryptoShredded) {\n segmentsShredded += 1;\n audit.onEvent({ kind: 'segment.erase', namespace: ref.namespace, segment: ref.segment });\n }\n }\n // Plus one namespace-level record of the erasure command, carrying the honest count actually shredded\n // (may be 0 — e.g. an empty namespace, or all-cleartext without `allowCleartext`): the command ran, but\n // the count keeps the record from over-attesting a destruction that did not happen.\n audit.onEvent({ kind: 'namespace.erase', namespace, segmentsShredded });\n return { destroyed };\n}\n\n/** The shred itself: clear Warm rows, then CAS the registry row to a `destroyed` tombstone with no wrappings. */\nasync function shredSegment(\n ref: SegmentRef,\n deps: EraseDeps,\n allowCleartext: boolean,\n): Promise<DestroyResult> {\n const base = { segment: ref.segment, namespace: ref.namespace };\n for (let attempt = 0; attempt < MAX_CAS_ATTEMPTS; attempt++) {\n const record = await deps.registry.get(ref);\n if (record === null) {\n // No authoritative row → nothing to crypto-shred. Still clear any stray Warm rows.\n const warmRowsDeleted = await eraseWarm(deps.warm, ref);\n return {\n ...base,\n destroyed: false,\n cryptoShredded: false,\n reason: 'absent',\n warmRowsDeleted,\n };\n }\n if (record.status === 'destroyed') {\n const warmRowsDeleted = await eraseWarm(deps.warm, ref);\n return {\n ...base,\n destroyed: true,\n cryptoShredded: false,\n reason: 'already',\n warmRowsDeleted,\n };\n }\n const encrypted = record.wrappedDeks !== undefined && record.wrappedDeks.length > 0;\n if (!encrypted && !allowCleartext) {\n return {\n ...base,\n destroyed: false,\n cryptoShredded: false,\n reason: 'cleartext',\n warmRowsDeleted: 0,\n };\n }\n // Clear Warm first (cleartext deltas), then flip the tombstone so a reader never sees a destroyed pointer\n // with live Warm data lingering.\n const warmRowsDeleted = await eraseWarm(deps.warm, ref);\n try {\n await deps.registry.compareAndSwap(ref, record.token, {\n status: 'destroyed',\n wrappedDeks: undefined, // ← the crypto-shred: the only copy of the DEK wrappings is gone\n keyId: undefined,\n leaseOwner: undefined,\n leaseExpiresAt: undefined,\n });\n // A genuine crypto-shred only when there were wrappings to drop; a cleartext opt-in tombstone leaves the\n // Cold bytes readable, so it is not an irreversible destruction (and does not emit `segment.erase`).\n return { ...base, destroyed: true, cryptoShredded: encrypted, warmRowsDeleted };\n } catch (err) {\n if (!isWriteConflictError(err)) throw err;\n // A concurrent compaction/write advanced the row — re-read and shred again (it always converges).\n }\n }\n throw new WriteConflictError(`destroySegment: contention shredding \"${ref.segment}\" — retry`);\n}\n\n/** Physically delete a segment's Warm rows (version-fenced per row; re-list on contention). Returns the count. */\nasync function eraseWarm(warm: IWarmDriver, ref: SegmentRef): Promise<number> {\n let deleted = 0;\n for (let pass = 0; pass < MAX_WARM_PASSES; pass++) {\n const rows: Array<{ chunkKey: number; token: string }> = [];\n for await (const row of warm.listChunks(ref))\n rows.push({ chunkKey: row.chunkKey, token: row.token });\n if (rows.length === 0) break;\n let conflicts = 0;\n for (const { chunkKey, token } of rows) {\n const chunkRef: ChunkRef = { namespace: ref.namespace, segment: ref.segment, chunkKey };\n try {\n await warm.deleteConditional(chunkRef, token);\n deleted += 1;\n } catch (err) {\n if (!isWriteConflictError(err)) throw err;\n conflicts += 1; // rewritten mid-erase — caught on the next pass\n }\n }\n if (conflicts === 0) break;\n }\n return deleted;\n}\n","/**\n * Fail-safe cross-tier DR check (gap #11). The registry (`currentGen`, e.g. in\n * DynamoDB) and the immutable `.crbm` generations (e.g. in S3) back up and restore **independently**, so a\n * failover can recover the registry *ahead of* the object store — leaving `currentGen` pointing at a generation\n * whose `.crbm` isn't present yet. That's a torn restore: reads of the affected segment then throw. This scan\n * detects it up front (run it at startup after a restore) instead of discovering it on the first read.\n *\n * Read-only; bounded fan-out. `destroyed` (crypto-shredded) segments are skipped — their Cold is intentionally\n * gone/unreadable, not a torn restore. A segment whose Cold/registry can't be read this pass is recorded in\n * `errored` (never aborts the scan). Each segment is checked against its **authoritative live pointer** — one\n * strong `registry.get` per segment — never the enumeration snapshot from `registry.list`, which can be\n * eventually-consistent (an unindexed Scan) and lag a recent in-place pointer advance: trusting it would both\n * miss a torn *live* generation and cry torn on a generation the pointer has already advanced past (GC'd during\n * the scan). Residual: a full compaction+GC landing in the tiny per-segment get→list gap can still yield a\n * transient false positive — run the scan against a quiesced fleet (the documented restore procedure), or re-run\n * to confirm a reported tear.\n */\n\nimport { mapWithConcurrency } from './concurrency';\nimport { ValidationError } from './errors';\nimport type { IColdDriver, IRegistryDriver, RegistryRecord, SegmentRef } from './ports';\n\n/** Default in-flight fan-out for the consistency scan — bounded, no thundering herd. */\nconst DEFAULT_CHECK_CONCURRENCY = 8;\n\nexport interface ConsistencyIssue {\n readonly segment: string;\n readonly namespace?: string;\n /** The registry's `currentGen` for the segment — the generation whose `.crbm` is missing from Cold. */\n readonly currentGen: number;\n /** The only issue class today: `currentGen` references a Cold generation that is not present (torn restore). */\n readonly issue: 'missing-cold-generation';\n}\n\n/** A segment that could not be checked this pass (Cold/registry read fault) — not proof of a torn restore. */\nexport interface ConsistencyErrorEntry {\n readonly segment: string;\n readonly namespace?: string;\n /** The read error's message (never the raw error, so the report stays serializable/loggable). */\n readonly error: string;\n}\n\nexport interface ConsistencyReport {\n /** Registered segments scanned (a `destroyed` segment counts as scanned but is never an issue). */\n readonly checked: number;\n /** Segments whose `currentGen` `.crbm` is absent — recover the object store (or restore to a coherent point). */\n readonly inconsistent: ConsistencyIssue[];\n /**\n * Segments that couldn't be read this pass (a transient/partial object store during a restore is exactly when\n * this runs) — **triage these too**: an unread segment is neither proven-coherent nor proven-torn. Empty on a\n * clean pass.\n */\n readonly errored: ConsistencyErrorEntry[];\n}\n\n/** Collect the set of generations the object store currently lists for a segment. */\nasync function listGenerations(cold: IColdDriver, ref: SegmentRef): Promise<Set<number>> {\n const present = new Set<number>();\n for await (const key of cold.list(ref)) present.add(key.generation);\n return present;\n}\n\ntype Outcome =\n | { readonly kind: 'ok' }\n | { readonly kind: 'issue'; readonly issue: ConsistencyIssue }\n | { readonly kind: 'error'; readonly error: ConsistencyErrorEntry };\n\n/**\n * Verify every registered segment's `currentGen` `.crbm` actually exists in Cold. Enumerates the registry\n * (optionally one namespace) and, for each non-`destroyed` segment, checks the object store lists that\n * generation. Returns the torn segments in `inconsistent` (empty ⇒ coherent) and any unreadable segments in\n * `errored`.\n */\nexport async function runConsistencyCheck(\n deps: { readonly cold: IColdDriver; readonly registry: IRegistryDriver },\n options: { namespace?: string; concurrency?: number } = {},\n): Promise<ConsistencyReport> {\n const concurrency = options.concurrency ?? DEFAULT_CHECK_CONCURRENCY;\n if (!Number.isInteger(concurrency) || concurrency < 1) {\n // Fail fast before the (possibly huge) registry scan, not after.\n throw new ValidationError(`concurrency must be a positive integer; got ${concurrency}`);\n }\n const recs: RegistryRecord[] = [];\n for await (const rec of deps.registry.list(options.namespace)) recs.push(rec);\n const results = await mapWithConcurrency(recs, concurrency, async (rec): Promise<Outcome> => {\n if (rec.status === 'destroyed') return { kind: 'ok' }; // Cold intentionally gone — not a torn restore\n const ref: SegmentRef = { segment: rec.segment, namespace: rec.namespace };\n try {\n // Resolve the AUTHORITATIVE live pointer (strong read) — not the drained `rec.currentGen`, which the\n // enumeration may have read eventually-consistently and can lag the live pointer. `rec` is used only to\n // enumerate + skip destroyed segments.\n const live = await deps.registry.get(ref);\n if (!live || live.status === 'destroyed') return { kind: 'ok' }; // vanished/shredded — no live pointer\n const present = await listGenerations(deps.cold, ref);\n if (present.has(live.currentGen)) return { kind: 'ok' };\n return {\n kind: 'issue',\n issue: {\n segment: rec.segment,\n namespace: rec.namespace,\n currentGen: live.currentGen,\n issue: 'missing-cold-generation',\n },\n };\n } catch (error) {\n // Fault isolation: one unreadable segment (a partial/transient object store mid-restore) must not abort\n // the whole triage. Record it and keep scanning the rest.\n return {\n kind: 'error',\n error: {\n segment: rec.segment,\n namespace: rec.namespace,\n error: error instanceof Error ? error.message : String(error),\n },\n };\n }\n });\n const inconsistent: ConsistencyIssue[] = [];\n const errored: ConsistencyErrorEntry[] = [];\n for (const r of results) {\n if (r.kind === 'issue') inconsistent.push(r.issue);\n else if (r.kind === 'error') errored.push(r.error);\n }\n return { checked: recs.length, inconsistent, errored };\n}\n","/**\n * Retry decorators (Phase 4b).\n *\n * Transparent wrappers that add bounded, jittered retry of **transient** faults to any driver, using the one\n * shared `core/retry` primitive — so every backend (DynamoDB, S3, LocalFS, …) inherits the same, simulator-\n * replayable policy instead of each rolling its own. Pure composition over the port interfaces (no SDK, no\n * I/O of their own); the wrapped driver is responsible for *classifying* its transient faults (raising\n * {@link TransientError}); these decorators decide *whether and when* to retry.\n *\n * **Streaming methods** (`listChunks`, `list`) are retried by **re-enumerating from the start**, buffering\n * the result — a partially-consumed async iterator can't be safely resumed mid-stream (it would re-yield\n * earlier items). Their consumers in the engine already collect fully (the Warm dirty-set is small under\n * Topology-A; the cold `list` is a discovery scan), so buffering preserves current semantics. Point methods\n * are retried in place with no buffering.\n *\n * What is **not** retried here: {@link WriteConflictError} (OCC — the engine's read-modify-write loop owns\n * that; a blind replay would re-apply against a stale token), and every deterministic error\n * (`ValidationError`/`IntegrityError`/`NotFoundError`/…). Default classifier: {@link isTransient}.\n */\nimport type { Clock, Rng } from '../../core/determinism';\nimport { withRetry, isTransient, DEFAULT_RETRY_POLICY } from '../../core/retry';\nimport type { RetryPolicy } from '../../core/retry';\nimport type {\n ChunkRef,\n ColdCaps,\n ColdChunkSource,\n GenKey,\n IColdDriver,\n IRegistryDriver,\n IWarmDriver,\n NewRegistryRecord,\n NoRow,\n RegCaps,\n RegistryPatch,\n RegistryRecord,\n SegmentRef,\n SegmentSize,\n Token,\n WarmReadOptions,\n WarmRow,\n} from '../../core/ports';\nimport type { BlobSink } from '../../core/blob';\n\nexport interface RetryingOptions {\n readonly clock: Clock;\n readonly rng: Rng;\n /** Defaults to {@link DEFAULT_RETRY_POLICY}. */\n readonly policy?: RetryPolicy;\n /** Override which errors are retryable. Default: {@link isTransient} (any `TransientError`). */\n readonly isRetryable?: (err: unknown) => boolean;\n /** Observability hook fired before each backoff wait. */\n readonly onRetry?: (info: { attempt: number; delayMs: number; err: unknown }) => void;\n}\n\n/** Internal: resolve the options into the `core/retry` shape once, at construction. */\nfunction toRetry(opts: RetryingOptions): {\n policy: RetryPolicy;\n deps: {\n clock: Clock;\n rng: Rng;\n isRetryable: (e: unknown) => boolean;\n onRetry?: RetryingOptions['onRetry'];\n };\n} {\n return {\n policy: opts.policy ?? DEFAULT_RETRY_POLICY,\n deps: {\n clock: opts.clock,\n rng: opts.rng,\n isRetryable: opts.isRetryable ?? isTransient,\n onRetry: opts.onRetry,\n },\n };\n}\n\n/** Wrap a warm driver so its calls retry transient faults. OCC conflicts are deliberately not retried here. */\nexport class RetryingWarmDriver implements IWarmDriver {\n private readonly inner: IWarmDriver;\n private readonly policy: RetryPolicy;\n private readonly deps: ReturnType<typeof toRetry>['deps'];\n\n constructor(inner: IWarmDriver, opts: RetryingOptions) {\n this.inner = inner;\n const r = toRetry(opts);\n this.policy = r.policy;\n this.deps = r.deps;\n }\n\n get(ref: ChunkRef, opts?: WarmReadOptions): Promise<WarmRow | null> {\n return withRetry(() => this.inner.get(ref, opts), this.policy, this.deps);\n }\n\n putConditional(\n ref: ChunkRef,\n bytes: Uint8Array,\n expected: Token | NoRow,\n ): Promise<{ token: Token }> {\n return withRetry(() => this.inner.putConditional(ref, bytes, expected), this.policy, this.deps);\n }\n\n deleteConditional(ref: ChunkRef, expected: Token): Promise<void> {\n return withRetry(() => this.inner.deleteConditional(ref, expected), this.policy, this.deps);\n }\n\n async *listChunks(\n ref: SegmentRef,\n opts?: WarmReadOptions,\n ): AsyncIterable<{ chunkKey: number } & WarmRow> {\n const rows = await withRetry(\n async () => {\n const out: Array<{ chunkKey: number } & WarmRow> = [];\n for await (const row of this.inner.listChunks(ref, opts)) out.push(row);\n return out;\n },\n this.policy,\n this.deps,\n );\n yield* rows;\n }\n}\n\n/** Wrap a cold chunk source so its reads retry transient faults. */\nexport class RetryingColdChunkSource implements ColdChunkSource {\n private readonly inner: ColdChunkSource;\n private readonly policy: RetryPolicy;\n private readonly deps: ReturnType<typeof toRetry>['deps'];\n /** Present only when the inner source supports it — so capability detection stays honest. */\n readonly sizeOf?: (ref: SegmentRef) => Promise<SegmentSize | null>;\n readonly cardinalities?: (ref: SegmentRef) => Promise<ReadonlyMap<number, number> | null>;\n readonly currentGeneration?: (ref: SegmentRef) => Promise<number | null>;\n\n constructor(inner: ColdChunkSource, opts: RetryingOptions) {\n this.inner = inner;\n const r = toRetry(opts);\n this.policy = r.policy;\n this.deps = r.deps;\n const innerSizeOf = inner.sizeOf;\n if (innerSizeOf) {\n this.sizeOf = (ref) => withRetry(() => innerSizeOf.call(inner, ref), this.policy, this.deps);\n }\n const innerCardinalities = inner.cardinalities;\n if (innerCardinalities) {\n this.cardinalities = (ref) =>\n withRetry(() => innerCardinalities.call(inner, ref), this.policy, this.deps);\n }\n const innerCurrentGeneration = inner.currentGeneration;\n if (innerCurrentGeneration) {\n this.currentGeneration = (ref) =>\n withRetry(() => innerCurrentGeneration.call(inner, ref), this.policy, this.deps);\n }\n }\n\n getChunk(ref: ChunkRef): Promise<Uint8Array | null> {\n return withRetry(() => this.inner.getChunk(ref), this.policy, this.deps);\n }\n\n listChunkKeys(ref: SegmentRef): Promise<number[]> {\n return withRetry(() => this.inner.listChunkKeys(ref), this.policy, this.deps);\n }\n}\n\n/** Wrap a cold driver so its byte operations retry transient faults. */\nexport class RetryingColdDriver implements IColdDriver {\n private readonly inner: IColdDriver;\n private readonly policy: RetryPolicy;\n private readonly deps: ReturnType<typeof toRetry>['deps'];\n\n constructor(inner: IColdDriver, opts: RetryingOptions) {\n this.inner = inner;\n const r = toRetry(opts);\n this.policy = r.policy;\n this.deps = r.deps;\n }\n\n capabilities(): ColdCaps {\n return this.inner.capabilities(); // pure, local — no retry\n }\n\n putImmutable(\n key: GenKey,\n write: (sink: BlobSink) => Promise<void>,\n ): Promise<{ size: number; sha256: string }> {\n // Write-once + content-buffered: a retry re-runs `write` from scratch and re-issues the conditional put;\n // a phantom-success surfaces as WriteConflictError (not transient) and stops the retry. Safe to wrap.\n return withRetry(() => this.inner.putImmutable(key, write), this.policy, this.deps);\n }\n\n getRange(key: GenKey, offset: number, length: number): Promise<Uint8Array> {\n return withRetry(() => this.inner.getRange(key, offset, length), this.policy, this.deps);\n }\n\n getTail(key: GenKey, maxBytes: number): Promise<{ bytes: Uint8Array; size: number }> {\n return withRetry(() => this.inner.getTail(key, maxBytes), this.policy, this.deps);\n }\n\n delete(key: GenKey): Promise<void> {\n return withRetry(() => this.inner.delete(key), this.policy, this.deps);\n }\n\n async *list(ref: SegmentRef): AsyncIterable<GenKey> {\n const keys = await withRetry(\n async () => {\n const out: GenKey[] = [];\n for await (const k of this.inner.list(ref)) out.push(k);\n return out;\n },\n this.policy,\n this.deps,\n );\n yield* keys;\n }\n}\n\n/** Wrap a registry driver so its calls retry transient faults. CAS conflicts are not retried (caller-owned). */\nexport class RetryingRegistryDriver implements IRegistryDriver {\n private readonly inner: IRegistryDriver;\n private readonly policy: RetryPolicy;\n private readonly deps: ReturnType<typeof toRetry>['deps'];\n\n constructor(inner: IRegistryDriver, opts: RetryingOptions) {\n this.inner = inner;\n const r = toRetry(opts);\n this.policy = r.policy;\n this.deps = r.deps;\n }\n\n capabilities(): RegCaps {\n return this.inner.capabilities();\n }\n\n get(ref: SegmentRef): Promise<RegistryRecord | null> {\n return withRetry(() => this.inner.get(ref), this.policy, this.deps);\n }\n\n create(ref: SegmentRef, record: NewRegistryRecord): Promise<{ token: Token }> {\n return withRetry(() => this.inner.create(ref, record), this.policy, this.deps);\n }\n\n compareAndSwap(\n ref: SegmentRef,\n expected: Token,\n patch: RegistryPatch,\n ): Promise<{ token: Token }> {\n return withRetry(() => this.inner.compareAndSwap(ref, expected, patch), this.policy, this.deps);\n }\n\n async *list(namespace?: string): AsyncIterable<RegistryRecord> {\n const records = await withRetry(\n async () => {\n const out: RegistryRecord[] = [];\n for await (const r of this.inner.list(namespace)) out.push(r);\n return out;\n },\n this.policy,\n this.deps,\n );\n yield* records;\n }\n\n delete(ref: SegmentRef): Promise<void> {\n return withRetry(() => this.inner.delete(ref), this.policy, this.deps);\n }\n}\n"]}
|