omp-fabric 1.18.1 → 1.18.2

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/compaction/lcm-runtime.ts", "../../src/storage/lcm-ledger.ts", "../../src/storage/lcm-directory.ts", "../../src/storage/lcm-migration.ts", "../../src/compaction/lcm-maintenance.ts"],
4
- "sourcesContent": ["import fs from \"node:fs\";\nimport type { ExtensionContext } from \"@oh-my-pi/pi-coding-agent\";\nimport { canonicalLcmPayload, canonicalProjectIdentity, hashLcmPayload, LcmLedger, type RawEntry } from \"../storage/lcm-ledger.js\";\nimport { defaultLedgerRoot, hash } from \"../storage/lcm-identity.js\";\n\nimport { sweepLedgers, type LcmSweepResult } from \"../storage/lcm-directory.js\";\nimport { migrationDropReasons, reconcileSession, type MigrationDrops } from \"../storage/lcm-migration.js\";\nimport { clipUtf8, MAX_SUMMARY_BYTES, utf8Bytes } from \"./bounds.js\";\nimport { lcmSummaryAddress, renderLcmChildAddresses, renderLcmSourceAddresses } from \"./lcm-addresses.js\";\nimport { emergencyReduce, LcmModelAdapter, type LcmSummarizer } from \"./lcm-model.js\";\nimport { LCM_RECOVERY_POINTER } from \"./render.js\";\nimport { reconcileLcmState } from \"./lcm-status.js\";\nimport { lcmChecks, type LcmAutoRepair, type LcmCheck, type LcmDiagnostics, type LcmRepairId, type LcmRepairOutcome } from \"./lcm-doctor.js\";\nimport { DEFAULT_LEAF_ENTRIES, DEFAULT_MAINTENANCE_CONCURRENCY, isLcmCapacityRejection, isLcmRejection, LcmMaintenance, type LcmBudgetPolicy, type LcmJob, type LcmNode } from \"./lcm-maintenance.js\";\nimport type { LcmCompactionInput, LcmCompactionOutput } from \"./hook.js\";\nimport { decodeCompactionInstructions } from \"./instructions.js\";\n\ntype LcmMaintenanceTrigger = \"occupancy\" | \"jobs\" | \"backlog\";\n\nexport interface LcmPreview {\n text: string;\n nodes: number;\n summaryBytes: number;\n sourceBytes: number;\n coveredSources: number;\n activeSources: number;\n}\n\nexport interface LcmReconciliation {\n degraded: boolean;\n errors: number;\n raced: number;\n absent: number;\n drops: MigrationDrops;\n reasons: string[];\n}\n\nexport interface LcmReport {\n projectKey: string;\n sessionId: string | undefined;\n state: string;\n ledgerState: string;\n degraded: string | undefined;\n summaryModel: string | undefined;\n rawEntries: number;\n sessionEntries: number;\n modelNodes: number;\n emergencyNodes: number;\n pendingNodes: number;\n pendingJobs: number;\n upgradableNodes: number;\n usage: { calls: number; inputTokens: number; outputTokens: number; cost: number; wallMs: number };\n budget: { calls: number; sessionCalls: number; wallMs: number };\n reconciliation: LcmReconciliation | undefined;\n}\n\nexport interface LcmRuntimeOptions {\n rootDir?: string;\n summaryModel?: string;\n maxLeafEntries?: number;\n maxCondenseChildren?: number;\n lcmMaxInputChars?: number;\n lcmMaxOutputTokens?: number;\n lcmMaxOutputChars?: number;\n maxMaintenancePasses?: number;\n maintenanceConcurrency?: number;\n modelSummaries?: boolean;\n modelTimeoutSeconds?: number;\n maxDailyModelCalls?: number;\n maxSessionModelCalls?: number;\n maxDailyModelSeconds?: number;\n maintenanceRunSeconds?: number;\n softThresholdRatio?: number;\n}\n\nconst MAX_AUTO_REPAIR_ATTEMPTS = 5;\nconst AUTO_REPAIR_DELAY_MS = 30_000;\nconst AUTO_REPAIR_CLEAR_MS = 1_800_000;\nconst MAX_REPAIR_LOG = 8;\nconst CLAIMABLE_JOB_LIMIT = 256;\nconst FAILED_JOB_WINDOW_MS = 24 * 60 * 60 * 1_000;\nconst NODE_ADDRESS_LABEL = \"address: \";\nconst BLOCK_SEPARATOR = \"\\n\\n\";\nconst WITHHELD_EXPAND_LABEL = \"; expand: \";\n\nconst withheldHeadline = (count: number): string =>\n `\u2026 withheld ${count} frontier node${count === 1 ? \"\" : \"s\"} that did not fit`;\n\nconst withheldNotice = (nodeIds: readonly string[], budget: number): string => {\n const headline = withheldHeadline(nodeIds.length);\n const addresses = nodeIds.map(lcmSummaryAddress);\n const line = (kept: readonly string[], omitted: number): string =>\n `${headline}${WITHHELD_EXPAND_LABEL}${kept.join(\", \")}${omitted > 0 ? `, +${omitted} more` : \"\"}`;\n const kept: string[] = [];\n for (const address of addresses) {\n if (utf8Bytes(line([...kept, address], addresses.length - kept.length - 1)) > budget) break;\n kept.push(address);\n }\n return kept.length === 0 ? headline : line(kept, addresses.length - kept.length);\n};\n\nconst clipOversized = (\n blocks: ReadonlyArray<{ node: LcmNode; head: string }>,\n headBytes: readonly number[],\n footer: string,\n separator: number,\n requestBlock = \"\",\n): string => {\n let widest = 0;\n for (let index = 1; index < blocks.length; index += 1) if (headBytes[index]! > headBytes[widest]!) widest = index;\n const { node } = blocks[widest]!;\n const addressLine = `\\n${NODE_ADDRESS_LABEL}${lcmSummaryAddress(node.nodeId)}`;\n const withheld = blocks.filter((_, index) => index !== widest).map((block) => block.node.nodeId);\n const requestBytes = requestBlock ? utf8Bytes(requestBlock) + separator : 0;\n const available = MAX_SUMMARY_BYTES - utf8Bytes(footer) - utf8Bytes(addressLine) - requestBytes;\n const notice = withheld.length === 0\n ? \"\"\n : withheldNotice(withheld, Math.max(utf8Bytes(withheldHeadline(withheld.length)), Math.floor(available / 2)));\n const text = clipUtf8(node.text ?? \"\", available - (notice ? separator + utf8Bytes(notice) : 0));\n const head = text ? `${text}${addressLine}` : addressLine.slice(1);\n const parts = [...(requestBlock ? [requestBlock] : []), head, ...(notice ? [notice] : [])];\n return `${parts.join(BLOCK_SEPARATOR)}${footer}`;\n};\n\nexport const renderAddressedFrontier = (\n frontier: readonly LcmNode[],\n requestLines: readonly string[] = [],\n): string => {\n const blocks = frontier\n .filter((node) => Boolean(node.text))\n .map((node) => ({ node, head: `${node.text ?? \"\"}\\n${NODE_ADDRESS_LABEL}${lcmSummaryAddress(node.nodeId)}` }));\n if (blocks.length === 0) return \"\";\n const requestBlock = requestLines.length > 0 ? `[Compaction Request]\\n${requestLines.join(\"\\n\")}` : \"\";\n const footer = `\\n\\n${LCM_RECOVERY_POINTER}`;\n const separator = utf8Bytes(BLOCK_SEPARATOR);\n const footerBytes = utf8Bytes(footer);\n const requestBytes = requestBlock ? utf8Bytes(requestBlock) + separator : 0;\n const headBytes = blocks.map((block) => utf8Bytes(block.head));\n const floorFor = (kept: number): number =>\n kept === blocks.length ? 0 : separator + utf8Bytes(withheldHeadline(blocks.length - kept));\n\n const kept: number[] = [];\n const withheld: number[] = [];\n let body = requestBytes;\n for (let index = 0; index < blocks.length; index += 1) {\n const grown = body + headBytes[index]! + (kept.length > 0 || requestBlock ? separator : 0);\n if (grown + footerBytes + floorFor(kept.length + 1) > MAX_SUMMARY_BYTES) { withheld.push(index); continue; }\n kept.push(index);\n body = grown;\n }\n if (kept.length === 0) return clipOversized(blocks, headBytes, footer, separator, requestBlock);\n\n const room = MAX_SUMMARY_BYTES - body - footerBytes - (withheld.length === 0 ? 0 : separator);\n const notice = withheld.length === 0\n ? \"\"\n : withheldNotice(withheld.map((index) => blocks[index]!.node.nodeId), Math.max(utf8Bytes(withheldHeadline(withheld.length)), Math.floor(room / 2)));\n const perNode = Math.max(0, Math.floor((room - utf8Bytes(notice)) / kept.length) - 1);\n const rendered = kept.map((index) => {\n const { node, head } = blocks[index]!;\n const addresses = node.sources.length > 0\n ? renderLcmSourceAddresses(node.sources, perNode)\n : renderLcmChildAddresses(node.children, perNode);\n return addresses && utf8Bytes(addresses) <= perNode ? `${head}\\n${addresses}` : head;\n });\n const parts = [...(requestBlock ? [requestBlock] : []), ...rendered, ...(notice ? [notice] : [])];\n return `${parts.join(BLOCK_SEPARATOR)}${footer}`;\n};\n\nexport class LcmRuntime {\n readonly ledger: LcmLedger;\n readonly maintenance: LcmMaintenance;\n private readonly context: ExtensionContext;\n private readonly resolveOptions: () => LcmRuntimeOptions;\n private readonly abort = new AbortController();\n private writePending: Promise<void> = Promise.resolve();\n private maintenancePending: Promise<void> = Promise.resolve();\n private closed = false;\n private dirty = false;\n private degradedError: unknown;\n private activeSources = new Set<string>();\n private activeSessionId: string | undefined;\n private persisted = new WeakMap<object, { key: string; contentHash: string }>();\n private persistedSessionId: string | undefined;\n private lastReconciliation: LcmReconciliation | undefined;\n\n constructor(context: ExtensionContext, options: LcmRuntimeOptions | (() => LcmRuntimeOptions) = {}) {\n this.context = context;\n this.resolveOptions = typeof options === \"function\" ? options : () => options;\n const initial = this.resolveOptions();\n const recorded = context.sessionManager.getRecordedCwd?.();\n const liveCwd = recorded || context.cwd;\n const project = canonicalProjectIdentity({ liveCwd });\n const ledgerOptions = initial.rootDir === undefined\n ? { project: { liveCwd: project.canonicalPath ?? liveCwd } }\n : { rootDir: initial.rootDir, project: { liveCwd: project.canonicalPath ?? liveCwd } };\n this.ledger = new LcmLedger(ledgerOptions);\n this.maintenance = new LcmMaintenance(this.ledger, {\n ...initial,\n ...(initial.lcmMaxInputChars === undefined ? {} : { maxInputChars: initial.lcmMaxInputChars }),\n ...(initial.lcmMaxOutputChars === undefined ? {} : { maxOutputChars: initial.lcmMaxOutputChars }),\n ...(initial.modelTimeoutSeconds === undefined ? {} : { modelTimeoutMs: initial.modelTimeoutSeconds * 1_000 }),\n maxConcurrentJobs: () => this.resolveOptions().maintenanceConcurrency ?? DEFAULT_MAINTENANCE_CONCURRENCY,\n budget: {\n ...(initial.maxDailyModelCalls ? { calls: initial.maxDailyModelCalls } : {}),\n ...(initial.maxSessionModelCalls ? { sessionCalls: initial.maxSessionModelCalls } : {}),\n ...(initial.maxDailyModelSeconds ? { wallMs: initial.maxDailyModelSeconds * 1_000 } : {}),\n },\n });\n }\n\n private get options(): LcmRuntimeOptions { return this.resolveOptions(); }\n\n get projectKey(): string { return this.ledger.project.key; }\n get signal(): AbortSignal { return this.abort.signal; }\n get status(): \"healthy\" | \"degraded\" { return this.degradedMessage() === undefined ? \"healthy\" : \"degraded\"; }\n get error(): unknown { return this.degradedError; }\n get reconciliation(): LcmReconciliation | undefined { return this.lastReconciliation; }\n\n private degradedMessage(): string | undefined {\n const faults: string[] = [];\n if (this.degradedError !== undefined) faults.push(String(this.degradedError instanceof Error ? this.degradedError.message : this.degradedError));\n const errors = this.lastReconciliation?.errors ?? 0;\n if (errors > 0) faults.push(`LCM session reconciliation reported ${errors} error(s)`);\n const reasons = this.lastReconciliation?.reasons ?? [];\n if (reasons.length > 0) faults.push(`LCM session reconciliation dropped ${reasons.join(\"; \")}`);\n const failed = this.recentlyFailedJobs();\n if (failed > 0) faults.push(`LCM maintenance left ${failed} job${failed === 1 ? \"\" : \"s\"} failed`);\n return faults.length === 0 ? undefined : faults.join(\" \u00B7 \");\n }\n\n private recentlyFailedJobs(): number {\n try { return this.maintenance.countJobs(\"failed\", Date.now() - FAILED_JOB_WINDOW_MS); } catch { return 0; }\n }\n markDirty(): void { this.dirty = true; }\n\n private enqueueWrite(operation: () => void | Promise<void>): Promise<void> {\n const run = this.writePending.then(operation);\n this.writePending = run.catch((error) => { this.degradedError = error; });\n return run;\n }\n\n private refreshActiveSources(sessionId: string, entries: readonly { id: string }[]): void {\n const ids = new Set(entries.map((entry) => entry.id));\n const latest = new Map<string, RawEntry>();\n for (const entry of this.ledger.readRaw(this.projectKey, sessionId)) {\n if (!ids.has(entry.entryId)) continue;\n const previous = latest.get(entry.entryId);\n if (!previous || previous.revision < entry.revision) latest.set(entry.entryId, entry);\n }\n this.activeSources = new Set(\n [...latest.values()].map((entry) => this.sourceKey(entry)),\n );\n this.activeSessionId = sessionId;\n this.invalidateFrontier();\n }\n\n private invalidateFrontier(): void {\n this.frontierCache = undefined;\n }\n\n reconcileSelectedSession(): Promise<void> {\n if (this.closed) return Promise.resolve();\n return this.enqueueWrite(() => {\n const getSessionFile = this.context.sessionManager.getSessionFile;\n if (typeof getSessionFile !== \"function\") return;\n const sessionFile = getSessionFile.call(this.context.sessionManager);\n if (!sessionFile) return;\n const recorded = this.context.sessionManager.getRecordedCwd?.();\n const cwd = recorded || this.context.cwd;\n const result = reconcileSession({\n agentDir: this.options.rootDir ?? process.env.PI_CODING_AGENT_DIR ?? `${process.env.HOME ?? \".\"}/.omp/agent`,\n ledger: this.ledger,\n files: [sessionFile],\n liveCwd: cwd,\n projectCwd: cwd,\n apply: true,\n });\n this.lastReconciliation = {\n degraded: result.degraded,\n errors: result.counts.errors,\n raced: result.counts.raced,\n absent: result.counts.absent,\n drops: result.drops,\n reasons: migrationDropReasons(result.drops),\n };\n const sessionId = this.context.sessionManager.getSessionId();\n this.refreshActiveSources(sessionId, this.context.sessionManager.getBranch());\n });\n }\n\n /** Appends only the entries this session has not stored yet; the rest are already addressed. */\n readback(): Promise<void> {\n if (this.closed) return Promise.resolve();\n return this.enqueueWrite(() => {\n if (this.closed) return;\n const entries = this.context.sessionManager.getBranch();\n const sessionId = this.context.sessionManager.getSessionId();\n const recorded = this.context.sessionManager.getRecordedCwd?.();\n if (this.persistedSessionId !== sessionId) {\n this.persisted = new WeakMap();\n this.persistedSessionId = sessionId;\n }\n const active = new Set<string>();\n const pending: Array<{ entry: (typeof entries)[number]; payloadJson: string; contentHash: string }> = [];\n for (const entry of entries) {\n const payloadJson = canonicalLcmPayload(entry);\n const contentHash = hash(payloadJson);\n const known = this.persisted.get(entry);\n if (known?.contentHash === contentHash) active.add(known.key);\n else pending.push({ entry, payloadJson, contentHash });\n }\n if (pending.length > 0) {\n this.ledger.transaction(() => {\n for (const { entry, payloadJson, contentHash } of pending) {\n const message = entry.type === \"message\" ? entry.message as { role?: string; content?: unknown } : undefined;\n const stored = this.ledger.appendRaw({\n projectKey: this.projectKey,\n sessionId,\n entryId: entry.id,\n role: message?.role ?? entry.type,\n content: message ? JSON.stringify(message.content ?? \"\") : payloadJson,\n payloadJson,\n parentEntryId: entry.parentId ?? null,\n ...(recorded || this.context.cwd ? { recordedCwd: recorded || this.context.cwd } : {}),\n });\n const key = this.sourceKey(stored);\n this.persisted.set(entry, { key, contentHash });\n active.add(key);\n }\n });\n }\n this.activeSources = active;\n this.activeSessionId = sessionId;\n this.invalidateFrontier();\n this.dirty = false;\n this.degradedError = undefined;\n });\n }\n\n /** Mid-turn sync: the write path already records its own failure. */\n syncEntries(): void {\n if (this.closed) return;\n void this.readback().catch(() => {});\n }\n\n async syncAndSchedule(): Promise<void> {\n if (this.closed) return;\n const sessionId = this.context.sessionManager.getSessionId();\n if (this.dirty || !this.activeSessionId || this.activeSessionId !== sessionId || this.activeSources.size === 0) {\n await this.readback();\n }\n if ((this.lastReconciliation?.absent ?? 0) > 0 && this.sessionFilePresent()) await this.reconcileSelectedSession();\n this.reclaimExpiredLeases();\n await this.autoRepair();\n if (this.maintenanceTrigger() !== undefined) this.scheduleMaintenance();\n }\n\n /** One repair per beat, budgeted per fault class in the ledger so a restart resumes the budget. */\n async autoRepair(): Promise<LcmRepairOutcome | undefined> {\n if (this.closed) return undefined;\n let ladder: Map<string, { attempts: number; nextAt: number; detail: string; updatedAt: number }>;\n let checks: LcmCheck[];\n try {\n ladder = this.ledger.readRepairLadder();\n if (ladder.size === 0 && this.degradedMessage() === undefined) return undefined;\n checks = lcmChecks(this.diagnostics());\n } catch (error) {\n this.degradedError = error;\n return undefined;\n }\n const now = Date.now();\n const actionable = new Map<string, { check: LcmCheck; repair: LcmRepairId }>();\n for (const check of checks) {\n const repair = check.repair;\n if (!repair || (check.severity !== \"warn\" && check.severity !== \"fail\")) continue;\n actionable.set(check.id, { check, repair });\n }\n for (const [fault, state] of ladder) {\n if (!actionable.has(fault) && now - state.updatedAt >= AUTO_REPAIR_CLEAR_MS) this.ledger.clearRepairLadder(fault);\n }\n const eligible = [...actionable.values()].filter(({ check }) => {\n const state = ladder.get(check.id);\n return !state || (state.attempts < MAX_AUTO_REPAIR_ATTEMPTS && state.nextAt <= now);\n });\n const target = eligible.find(({ check }) => check.severity === \"fail\") ?? eligible[0];\n if (!target) return undefined;\n const outcome = await this.repair(target.repair);\n const attempts = (ladder.get(target.check.id)?.attempts ?? 0) + 1;\n this.ledger.writeRepairLadder(target.check.id, attempts, now + AUTO_REPAIR_DELAY_MS * 2 ** (attempts - 1), outcome.detail);\n return outcome;\n }\n\n /** Reclaims ledgers whose project directory is gone; bounded to one sweep a day. */\n sweepLedgers(): LcmSweepResult {\n if (this.closed) return { removed: [], bytes: 0, skipped: true };\n try {\n return sweepLedgers(this.options.rootDir ?? defaultLedgerRoot(), { keepKey: this.projectKey });\n } catch {\n return { removed: [], bytes: 0, skipped: true };\n }\n }\n\n reclaimExpiredLeases(): number {\n if (this.closed) return 0;\n try {\n return this.maintenance.sweepExpiredLeases().length + this.maintenance.recoverLegacyContentionRetirements().length;\n } catch (error) {\n this.degradedError = error;\n return 0;\n }\n }\n\n maintenanceTrigger(): LcmMaintenanceTrigger | undefined {\n const sessionId = this.activeSessionId;\n if (this.closed || !sessionId || this.activeSources.size === 0) return undefined;\n try {\n if (!this.maintenance.withinBudget(sessionId)) return undefined;\n if (this.maintenanceOccupancyReached()) return \"occupancy\";\n if (this.actionableJobs(sessionId, 1).length > 0) return \"jobs\";\n const { active, covered } = this.coverage();\n return active - covered >= Math.max(1, this.options.maxLeafEntries ?? DEFAULT_LEAF_ENTRIES) ? \"backlog\" : undefined;\n } catch (error) {\n this.degradedError = error;\n return undefined;\n }\n }\n\n /** Fails open: an unreadable occupancy never disables maintenance. */\n maintenanceOccupancyReached(): boolean {\n const ratio = this.options.softThresholdRatio;\n if (typeof ratio !== \"number\" || !Number.isFinite(ratio) || ratio <= 0) return true;\n let usage: { percent: number | null } | undefined;\n try {\n usage = this.context.getContextUsage?.();\n } catch {\n return true;\n }\n const percent = usage?.percent;\n if (typeof percent !== \"number\" || !Number.isFinite(percent)) return true;\n return percent / 100 >= ratio;\n }\n\n maintain(): Promise<void> { return this.syncAndSchedule(); }\n\n scheduleMaintenance(): void {\n if (this.closed) return;\n const run = this.maintenancePending.then(() => this.runMaintenance());\n this.maintenancePending = run.catch((error) => { this.degradedError = error; });\n }\n\n private actionableJobs(sessionId: string, limit: number): Array<{ job: LcmJob; node: LcmNode }> {\n const found: Array<{ job: LcmJob; node: LcmNode }> = [];\n if (limit <= 0) return found;\n for (const job of this.maintenance.claimableJobs(sessionId, CLAIMABLE_JOB_LIMIT)) {\n const node = this.maintenance.getNode(job.nodeId);\n if (!node || node.sessionId !== sessionId) continue;\n if (!node.sources.every((source) => this.activeSources.has(this.sourceKey(source)))) continue;\n found.push({ job, node });\n if (found.length >= limit) break;\n }\n return found;\n }\n\n private async runMaintenance(): Promise<void> {\n const sessionId = this.activeSessionId;\n if (this.closed || !sessionId || this.activeSources.size === 0) return;\n try {\n await this.runMaintenancePasses(sessionId);\n } finally {\n this.invalidateFrontier();\n }\n }\n\n private async runMaintenancePasses(sessionId: string): Promise<void> {\n const wantsModel = this.options.modelSummaries !== false;\n let model: LcmSummarizer;\n try {\n if (!wantsModel) throw new Error(\"model summaries are disabled by configuration\");\n model = new LcmModelAdapter(this.context, this.options.summaryModel, true, {\n ...(this.options.lcmMaxInputChars === undefined ? {} : { maxInputChars: this.options.lcmMaxInputChars }),\n ...(this.options.lcmMaxOutputTokens === undefined ? {} : { maxOutputTokens: this.options.lcmMaxOutputTokens }),\n ...(this.options.lcmMaxOutputChars === undefined ? {} : { maxOutputChars: this.options.lcmMaxOutputChars }),\n });\n } catch (error) {\n this.degradedError = error;\n model = { modelHash: \"unavailable\", generate: async () => { throw error instanceof Error ? error : new Error(String(error)); } };\n }\n const fanIn = Math.max(2, this.options.maxCondenseChildren ?? 4);\n const passes = Math.max(1, this.options.maxMaintenancePasses ?? 4);\n const runDeadline = Date.now() + Math.max(1, this.options.maintenanceRunSeconds ?? 60) * 1_000;\n const raw = this.ledger.readRaw(this.projectKey, sessionId).filter((entry) =>\n this.activeSources.has(this.sourceKey(entry)),\n );\n const inputFor = (node: NonNullable<ReturnType<LcmMaintenance[\"getNode\"]>>): string => {\n if (node.kind === \"condensed\") return node.children.map((id) => this.maintenance.getNode(id)?.text ?? \"\").filter(Boolean).join(\"\\n\\n\");\n return node.sources.map((source) => {\n const entry = this.ledger.readRawEntry(this.projectKey, source.sessionId, source.entryId, source.revision);\n if (!entry || entry.payloadHash !== source.payloadHash) throw new Error(\"stale source\");\n return entry.payloadJson;\n }).join(\"\\n\");\n };\n const runJob = async (job: LcmJob, node: LcmNode): Promise<\"done\" | \"rejected\" | \"capacity\"> => {\n try {\n const input = inputFor(node);\n await this.maintenance.run(job, model, input, this.signal);\n return \"done\";\n } catch (error) {\n if (isLcmCapacityRejection(error)) return \"capacity\";\n if (isLcmRejection(error)) return \"rejected\";\n this.degradedError = error;\n try { this.maintenance.recordFailure(job, error); } catch {}\n return \"done\";\n }\n };\n const dispatch = async (items: ReadonlyArray<{ job: LcmJob; node: LcmNode }>): Promise<void> => {\n let next = 0;\n const worker = async (slot: number): Promise<void> => {\n while (!this.closed && Date.now() < runDeadline && slot < this.maintenance.concurrencyLimit) {\n const item = items[next];\n if (!item) return;\n next += 1;\n if (await runJob(item.job, item.node) === \"capacity\") return;\n }\n };\n await Promise.all(Array.from({ length: Math.min(this.maintenance.concurrencyLimit, items.length) }, (_unused, slot) => worker(slot)));\n };\n this.reclaimExpiredLeases();\n for (let pass = 0; pass < passes && !this.closed && Date.now() < runDeadline; pass += 1) {\n const leafCandidate = this.maintenance.createLeaf(this.maintenance.selectLeaf(raw, this.activeSources));\n const leaf = leafCandidate ? this.maintenance.getNode(leafCandidate.nodeId) : undefined;\n const batch: Array<{ job: LcmJob; node: LcmNode }> = [];\n const queued = new Set<string>();\n if (leaf?.state === \"pending\") {\n const job = this.maintenance.jobForNode(leaf.nodeId);\n if (job && this.maintenance.isClaimable(job)) { batch.push({ job, node: leaf }); queued.add(job.jobId); }\n }\n const pending = this.actionableJobs(sessionId, passes);\n for (const item of pending) if (!queued.has(item.job.jobId)) { queued.add(item.job.jobId); batch.push(item); }\n await dispatch(batch);\n const children = this.maintenance.selectCondensation(sessionId, this.activeSources);\n if (children.length >= fanIn) {\n const node = this.maintenance.createCondensed(children);\n if (node) {\n const job = this.maintenance.jobForNode(node.nodeId);\n if (job && this.maintenance.isClaimable(job)) await runJob(job, node);\n }\n }\n if (!leaf && pending.length === 0 && children.length < fanIn) {\n const upgrades = this.maintenance.selectUpgrades(sessionId, this.activeSources, 1);\n const upgrade = upgrades[0];\n if (!upgrade) break;\n const job = this.maintenance.reopen(upgrade.nodeId);\n await runJob(job, upgrade);\n if (this.maintenance.getNode(upgrade.nodeId)?.modelHash !== \"emergency\") {\n for (const ancestor of this.maintenance.ancestorsOf(upgrade.nodeId)) {\n const node = this.maintenance.getNode(ancestor);\n if (node?.state === \"ready\") this.maintenance.reopen(ancestor, true);\n }\n }\n continue;\n }\n }\n }\n\n compact(input: LcmCompactionInput): LcmCompactionOutput {\n const instructions = decodeCompactionInstructions(input.customInstructions);\n const requestLines = instructions.ok ? instructions.requestLines : [];\n const persistedEntries = new Map<string, RawEntry>();\n this.ledger.transaction(() => {\n for (const entry of input.branchEntries) {\n const message = entry.type === \"message\" ? entry.message as { role?: string; content?: unknown } : undefined;\n const payloadJson = canonicalLcmPayload(entry);\n const stored = this.ledger.appendRaw({\n projectKey: this.projectKey,\n sessionId: input.sessionId,\n entryId: entry.id,\n role: message?.role ?? entry.type,\n content: message ? JSON.stringify(message.content ?? \"\") : payloadJson,\n payloadJson,\n parentEntryId: entry.parentId ?? null,\n });\n persistedEntries.set(`${entry.id}:${stored.payloadHash}`, stored);\n }\n });\n this.invalidateFrontier();\n const firstKeptIndex = input.firstKeptEntryId\n ? input.branchEntries.findIndex((entry) => entry.id === input.firstKeptEntryId)\n : input.branchEntries.length;\n const sourceEntries = input.branchEntries.slice(0, firstKeptIndex < 0 ? input.branchEntries.length : firstKeptIndex);\n const selectedStored = sourceEntries.map((entry) => {\n const payloadHash = hashLcmPayload(JSON.parse(canonicalLcmPayload(entry)));\n const stored = persistedEntries.get(`${entry.id}:${payloadHash}`);\n if (!stored) throw new Error(\"compaction source was not persisted\");\n return stored;\n });\n const activeSources = new Set(selectedStored.map((entry) => this.sourceKey(entry)));\n const frontier = this.maintenance.getFrontier(input.sessionId, activeSources);\n const coveredSources = new Set(frontier.flatMap((node) => node.sources.map((source) => this.sourceKey(source))));\n const summary = renderAddressedFrontier(frontier, requestLines);\n const instructionDetails = instructions.ok && (instructions.requestLines.length > 0 || instructions.policy.preserveCount > 0)\n ? { instructionPolicy: instructions.policy }\n : undefined;\n if (summary && selectedStored.every((entry) => coveredSources.has(this.sourceKey(entry)))) {\n return {\n summary,\n firstKeptEntryId: input.firstKeptEntryId,\n tokensBefore: input.tokensBefore,\n source: \"ready-frontier\",\n ...(instructionDetails ? { details: instructionDetails } : {}),\n };\n }\n if (selectedStored.length === 0) throw new Error(\"LCM emergency fallback has no persisted sources\");\n const payloads = sourceEntries.map((entry) => canonicalLcmPayload(entry)).join(\"\\n\");\n const sources = selectedStored.map((stored) => ({ sessionId: stored.sessionId, entryId: stored.entryId, revision: stored.revision, payloadHash: stored.payloadHash }));\n const fallback = emergencyReduce(payloads, this.options.lcmMaxOutputChars ?? 4_096, sources, requestLines);\n const leaf = this.maintenance.createLeaf(selectedStored);\n if (!leaf) throw new Error(\"LCM emergency fallback node was not created\");\n const persisted = this.maintenance.getNode(leaf.nodeId);\n if (persisted?.state === \"ready\") {\n if (JSON.stringify(persisted.sources) !== JSON.stringify(sources)) throw new Error(\"LCM emergency fallback provenance mismatch\");\n if (!persisted.text) throw new Error(\"LCM emergency fallback text is missing\");\n return {\n summary: persisted.text,\n firstKeptEntryId: input.firstKeptEntryId,\n tokensBefore: input.tokensBefore,\n source: \"emergency\",\n ...(instructionDetails ? { details: instructionDetails } : {}),\n };\n }\n const job = this.maintenance.jobForNode(leaf.nodeId);\n if (!job) throw new Error(\"LCM emergency fallback job was not created\");\n try {\n const completed = this.maintenance.completeEmergency(this.maintenance.claimEmergency(job.jobId), fallback);\n return {\n summary: completed.text ?? fallback,\n firstKeptEntryId: input.firstKeptEntryId,\n tokensBefore: input.tokensBefore,\n source: \"emergency\",\n ...(instructionDetails ? { details: instructionDetails } : {}),\n };\n } catch (error) {\n if (!isLcmRejection(error)) throw error;\n return {\n summary: fallback,\n firstKeptEntryId: input.firstKeptEntryId,\n tokensBefore: input.tokensBefore,\n source: \"emergency\",\n ...(instructionDetails ? { details: instructionDetails } : {}),\n };\n }\n }\n\n report(): LcmReport {\n const day = new Date(Date.now()).toISOString().slice(0, 10);\n const degraded = this.degradedMessage();\n const ledgerState = this.ledger.operationalState;\n return this.ledger.readOnly((db) => {\n const count = (sql: string, ...params: unknown[]): number =>\n Number((db.prepare(sql).get(...params) as { n: number }).n);\n const nodes = db.prepare(\"SELECT json_extract(payload,'$.kind') kind, json_extract(payload,'$.state') state, json_extract(payload,'$.modelHash') model, count(*) n FROM summary_nodes WHERE project_key=? GROUP BY kind, state, model\")\n .all(this.projectKey) as Array<{ kind: string; state: string; model: string; n: number }>;\n const usage = db.prepare(\"SELECT coalesce(sum(calls),0) calls, coalesce(sum(input_tokens),0) input, coalesce(sum(output_tokens),0) output, coalesce(sum(cost),0) cost, coalesce(sum(wall_ms),0) wallMs FROM maintenance_usage WHERE project_key=? AND day=?\")\n .get(this.projectKey, day) as { calls: number; input: number; output: number; cost: number; wallMs: number };\n const budget = this.maintenance.budgetPolicy();\n return {\n projectKey: this.projectKey,\n sessionId: this.activeSessionId,\n state: reconcileLcmState(ledgerState, degraded),\n ledgerState,\n degraded,\n summaryModel: this.options.summaryModel,\n rawEntries: count(\"SELECT count(*) n FROM raw_entries WHERE project_key=?\", this.projectKey),\n sessionEntries: this.activeSessionId === undefined ? 0 : count(\"SELECT count(*) n FROM raw_entries WHERE project_key=? AND session_id=?\", this.projectKey, this.activeSessionId),\n modelNodes: nodes.filter((row) => row.model && row.model !== \"emergency\").reduce((total, row) => total + row.n, 0),\n emergencyNodes: nodes.filter((row) => row.model === \"emergency\").reduce((total, row) => total + row.n, 0),\n pendingNodes: nodes.filter((row) => row.state !== \"ready\").reduce((total, row) => total + row.n, 0),\n pendingJobs: count(\"SELECT count(*) n FROM maintenance_jobs WHERE project_key=? AND status=?\", this.projectKey, \"pending\"),\n upgradableNodes: count(\"SELECT count(*) n FROM summary_nodes WHERE project_key=? AND json_extract(payload,'$.modelHash')=?\", this.projectKey, \"emergency\"),\n usage: { calls: usage.calls, inputTokens: usage.input, outputTokens: usage.output, cost: usage.cost, wallMs: usage.wallMs },\n budget: { calls: budget.calls, sessionCalls: budget.sessionCalls, wallMs: budget.wallMs },\n reconciliation: this.lastReconciliation,\n };\n });\n }\n\n private readonly repairLog: LcmRepairOutcome[] = [];\n\n private branchLength(): number {\n try { return this.context.sessionManager.getBranch().length; } catch { return 0; }\n }\n\n private sessionFile(): string | undefined {\n const getSessionFile = this.context.sessionManager.getSessionFile;\n if (typeof getSessionFile !== \"function\") return undefined;\n return getSessionFile.call(this.context.sessionManager) ?? undefined;\n }\n\n private sessionFilePresent(): boolean {\n const file = this.sessionFile();\n return file !== undefined && fs.existsSync(file);\n }\n\n private countJobs(state: \"pending\" | \"running\", since = 0): number {\n try { return this.maintenance.countJobs(state, since); } catch { return 0; }\n }\n\n diagnostics(report = this.report()): LcmDiagnostics {\n const coverage = this.coverage();\n const sessionFile = this.sessionFile();\n const sessionId = this.activeSessionId;\n let withinBudget = true;\n try { withinBudget = sessionId === undefined || this.maintenance.withinBudget(sessionId); } catch { withinBudget = true; }\n let expiredLeases = 0;\n try { expiredLeases = this.maintenance.expiredLeases(); } catch { expiredLeases = 0; }\n return {\n projectKey: this.projectKey,\n ledgerPath: this.ledger.file,\n ledgerBytes: this.ledger.bytes,\n ledgerState: report.ledgerState,\n runtimeError: this.degradedError === undefined\n ? undefined\n : String(this.degradedError instanceof Error ? this.degradedError.message : this.degradedError),\n sessionId,\n sessionFile,\n sessionFilePresent: this.sessionFilePresent(),\n liveBranchEntries: this.branchLength(),\n ledgerSessionEntries: report.sessionEntries,\n ledgerEntries: report.rawEntries,\n activeSources: coverage.active,\n coveredSources: coverage.covered,\n backlogThreshold: Math.max(1, this.options.maxLeafEntries ?? DEFAULT_LEAF_ENTRIES),\n pendingNodes: report.pendingNodes,\n pendingJobs: this.countJobs(\"pending\"),\n runningJobs: this.countJobs(\"running\"),\n failedJobs: this.recentlyFailedJobs(),\n expiredLeases,\n modelSummaries: this.options.modelSummaries !== false,\n summaryModel: this.options.summaryModel,\n budgetCalls: report.budget.calls,\n usedCalls: report.usage.calls,\n withinBudget,\n reconciliation: this.lastReconciliation\n ? {\n errors: this.lastReconciliation.errors,\n raced: this.lastReconciliation.raced,\n absent: this.lastReconciliation.absent,\n reasons: this.lastReconciliation.reasons,\n }\n : undefined,\n repairs: this.repairLog,\n autoRepairs: this.autoRepairState(),\n };\n }\n\n private autoRepairState(): LcmAutoRepair[] {\n try {\n return [...this.ledger.readRepairLadder()]\n .map(([fault, state]) => ({ fault, attempts: state.attempts, nextAt: state.nextAt, detail: state.detail }))\n .sort((left, right) => left.fault.localeCompare(right.fault));\n } catch {\n return [];\n }\n }\n\n get repairs(): readonly LcmRepairOutcome[] { return this.repairLog; }\n\n private record(id: LcmRepairId, changed: boolean, detail: string): LcmRepairOutcome {\n const outcome: LcmRepairOutcome = { id, changed, detail, at: Date.now() };\n this.repairLog.unshift(outcome);\n if (this.repairLog.length > MAX_REPAIR_LOG) this.repairLog.length = MAX_REPAIR_LOG;\n this.invalidateFrontier();\n return outcome;\n }\n\n /** Every repair is idempotent and reports the delta it caused. */\n async repair(id: LcmRepairId): Promise<LcmRepairOutcome> {\n if (this.closed) return this.record(id, false, \"the runtime is closed\");\n try {\n if (id === \"reconcile\") {\n await this.reconcileSelectedSession();\n const errors = this.lastReconciliation?.errors ?? 0;\n if (errors > 0) return this.record(id, false, `still ${errors} unreadable session file(s)`);\n const absent = this.lastReconciliation?.absent ?? 0;\n return this.record(id, absent === 0, absent > 0 ? \"session file is not on disk yet\" : \"session file re-read into the ledger\");\n }\n if (id === \"readback\") {\n const before = this.report().sessionEntries;\n this.degradedError = undefined;\n this.markDirty();\n await this.readback();\n const after = this.report().sessionEntries;\n return this.record(id, after !== before, `${after - before} entr${after - before === 1 ? \"y\" : \"ies\"} imported \u00B7 ${after} stored`);\n }\n if (id === \"leases\") {\n const swept = this.maintenance.sweepExpiredLeases().length;\n return this.record(id, swept > 0, `${swept} lease(s) released`);\n }\n const retried = this.maintenance.retryFailedJobs().length;\n if (retried > 0) this.scheduleMaintenance();\n return this.record(id, retried > 0, `${retried} job(s) requeued`);\n } catch (error) {\n return this.record(id, false, String(error instanceof Error ? error.message : error));\n }\n }\n\n private frontierCache: { at: number; sessionId: string; nodes: LcmNode[]; covered: Set<string> } | undefined;\n\n /** One frontier walk shared by preview, coverage, and the coverage map. */\n private frontierSnapshot(): { nodes: LcmNode[]; covered: Set<string> } {\n const sessionId = this.activeSessionId ?? \"\";\n const cached = this.frontierCache;\n if (cached && cached.sessionId === sessionId && Date.now() - cached.at < 250) {\n return { nodes: cached.nodes, covered: cached.covered };\n }\n const nodes = sessionId ? this.maintenance.getFrontier(sessionId, this.activeSources) : [];\n const covered = new Set(nodes.flatMap(node => node.sources.map(source => this.sourceKey(source))));\n this.frontierCache = { at: Date.now(), sessionId, nodes, covered };\n return { nodes, covered };\n }\n\n /** Content identity, so a fork keeps the summaries built over the entries it inherited. */\n private sourceKey(source: { entryId: string; payloadHash: string }): string {\n return `${source.entryId}:${source.payloadHash}`;\n }\n\n /** Assembles what a compaction would serve now. Reads only; it never persists a node. */\n preview(): LcmPreview {\n const sessionId = this.activeSessionId;\n if (!sessionId) return { text: \"\", nodes: 0, summaryBytes: 0, sourceBytes: 0, coveredSources: 0, activeSources: 0 };\n const { nodes, covered } = this.frontierSnapshot();\n const text = nodes.map(node => node.text ?? \"\").filter(Boolean).join(\"\\n\\n\");\n return {\n text,\n nodes: nodes.length,\n summaryBytes: Buffer.byteLength(text, \"utf8\"),\n sourceBytes: this.ledger.payloadBytes(this.projectKey, sessionId),\n coveredSources: covered.size,\n activeSources: this.activeSources.size,\n };\n }\n\n /** Ordered coverage of the active branch: each entry says whether a ready node holds it. */\n coverageMap(limit = 2_000): Array<{ key: string; covered: boolean }> {\n const sessionId = this.activeSessionId;\n if (!sessionId) return [];\n const { covered } = this.frontierSnapshot();\n return this.ledger.readRawKeys(this.projectKey, sessionId, limit)\n .map(entry => { const key = this.sourceKey({ entryId: entry.entryId, payloadHash: entry.contentHash }); return { key, covered: covered.has(key) }; });\n }\n\n jobs(limit = 64): LcmJob[] {\n try { return this.maintenance.recentJobs(limit); } catch { return []; }\n }\n\n nodes(limit = 200, offset = 0): LcmNode[] {\n return this.maintenance.listNodes(limit, offset);\n }\n\n node(nodeId: string): { node: LcmNode; revisions: ReturnType<LcmMaintenance[\"revisionsOf\"]>; ancestors: string[] } | undefined {\n const node = this.maintenance.getNode(nodeId);\n if (!node) return undefined;\n return { node, revisions: this.maintenance.revisionsOf(nodeId), ancestors: this.maintenance.ancestorsOf(nodeId) };\n }\n\n source(sessionId: string, entryId: string, revision: number): RawEntry | undefined {\n return this.ledger.readRawEntry(this.projectKey, sessionId, entryId, revision);\n }\n\n coverage(): { active: number; covered: number } {\n if (!this.activeSessionId) return { active: 0, covered: 0 };\n const { covered } = this.frontierSnapshot();\n let hits = 0;\n for (const key of this.activeSources) if (covered.has(key)) hits += 1;\n return { active: this.activeSources.size, covered: hits };\n }\n\n memoryContext() {\n return {\n ledger: {\n projectKey: this.projectKey,\n readRaw: (sessionId?: string) => this.ledger.readRaw(this.projectKey, sessionId),\n readRawPage: (sessionId?: string, offset?: number, limit?: number) => this.ledger.readRawPage(this.projectKey, sessionId, offset, limit),\n readRawEntry: (sessionId: string, entryId: string, revision: number) => this.ledger.readRawEntry(this.projectKey, sessionId, entryId, revision),\n searchRaw: (options: Parameters<LcmLedger[\"searchRaw\"]>[1]) => this.ledger.searchRaw(this.projectKey, options),\n },\n ...(this.activeSessionId === undefined ? {} : { currentSessionId: this.activeSessionId }),\n summaries: {\n listNodes: ({ sessionId, limit }: { sessionId?: string; limit: number }) => this.maintenance.getFrontier(sessionId, sessionId === this.activeSessionId ? this.activeSources : undefined).slice(0, limit).map((node) => ({ ...node, text: node.text ?? \"\", sources: node.sources.map((source) => ({ entryId: source.entryId, revision: source.revision, contentHash: source.payloadHash })) })),\n getNode: (nodeId: string) => {\n const node = this.maintenance.getNode(nodeId);\n return node ? { ...node, text: node.text ?? \"\", sources: node.sources.map((source) => ({ entryId: source.entryId, revision: source.revision, contentHash: source.payloadHash })) } : undefined;\n },\n },\n branchForSession: () => this.activeSessionId === undefined\n ? undefined\n : { activeSourceKeys: [...this.activeSources], ready: this.status === \"healthy\" },\n };\n }\n\n frontier(sessionId?: string) {\n return this.maintenance.getFrontier(sessionId, sessionId === this.activeSessionId ? this.activeSources : undefined);\n }\n\n raw(sessionId?: string): RawEntry[] { return this.ledger.readRaw(this.projectKey, sessionId); }\n\n async shutdown(): Promise<void> {\n if (this.closed) return;\n this.closed = true;\n this.abort.abort();\n await this.writePending.catch(() => undefined);\n await this.maintenancePending.catch(() => undefined);\n this.ledger.close();\n }\n}\n", "import fs from \"node:fs\";\nimport path from \"node:path\";\nimport crypto from \"node:crypto\";\nimport { sqliteDriver, type SqliteDatabase } from \"./sqlite.js\";\nimport { stableProjectKey } from \"./lcm-directory.js\";\nimport { canonicalLcmPayload, canonicalProjectIdentity, createDeleteConfirmationToken, defaultLedgerPath, defaultLedgerRoot, hash, hashLcmPayload, type DeleteConfirmationToken, type ProjectIdentity, type ProjectIdentityInput, type RawEntry, type SessionEntry } from \"./lcm-identity.js\";\n\nexport { canonicalLcmPayload, canonicalProjectIdentity, createDeleteConfirmationToken, defaultLedgerPath, hashLcmPayload };\nexport type { DeleteConfirmationToken, ProjectIdentity, RawEntry, SessionEntry };\nconst LCM_LEDGER_WARNING_BYTES = 8 * 1024 ** 3;\nconst LCM_LEDGER_MAINTENANCE_BYTES = 10 * 1024 ** 3;\nexport interface LedgerOptions { dbPath?: string; rootDir?: string; project?: ProjectIdentityInput; projectKey?: string; now?: () => number; warningBytes?: number; maintenanceBytes?: number }\nexport type OperationalState = \"healthy\" | \"warning\" | \"maintenance\" | \"degraded\";\nexport interface CheckpointMetrics { mode: \"passive\" | \"truncate\"; busy: number; logPages: number; checkpointedPages: number; truncated: boolean }\nexport interface BackupManifest { format: \"lcm-ledger-backup\"; version: number; source: string; destination: string; sourceSha256: string; backupSha256: string; sourceStateSha256: string; rowCounts: Record<string, number>; integrity: \"ok\" | string; createdAt: number }\ntype LcmSearchMode = \"literal\" | \"phrase\" | \"regex\";\nexport interface LcmSearchOptions { sessionId?: string; query?: string; mode: LcmSearchMode; offset: number; limit: number; scanLimit?: number; match?: \"any\" | \"all\" }\nexport interface LcmSearchPage { rows: RawEntry[]; total: number; scanned: number; complete: boolean }\nexport interface DeleteManifest { format: \"lcm-ledger-delete\"; version: number; projectKey: string; deletedAt: number; integrity: string; remaining: number; remainingByTable: Record<string, number>; unattributed: number; unattributedByTable: Record<string, number> }\nexport interface LedgerMigrationReport { version: number; name: string; applied: boolean; reason?: string; counts: Record<string, number> }\nconst LEDGER_SCHEMA_VERSION = 4;\nconst BACKUP_MANIFEST_VERSION = 3;\nconst DELETE_MANIFEST_VERSION = 2;\nconst PROJECT_KEYED_TABLES = [\"projects\", \"project_aliases\", \"sessions\", \"raw_entries\", \"summary_nodes\", \"summary_node_revisions\", \"frontiers\", \"maintenance_jobs\", \"maintenance_usage\", \"repair_ladder\"] as const;\nconst LCM_SEARCH_SCAN_LIMIT = 5_000;\nconst LCM_SCAN_BATCH = 500;\n\nconst SCHEMA = `\nCREATE TABLE IF NOT EXISTS schema_metadata (key TEXT PRIMARY KEY, value TEXT NOT NULL);\nCREATE TABLE IF NOT EXISTS projects (project_key TEXT PRIMARY KEY, identity_json TEXT NOT NULL, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL);\nCREATE TABLE IF NOT EXISTS project_aliases (alias TEXT PRIMARY KEY, project_key TEXT NOT NULL REFERENCES projects(project_key));\nCREATE TABLE IF NOT EXISTS sessions (project_key TEXT NOT NULL, session_id TEXT NOT NULL, created_at INTEGER NOT NULL, PRIMARY KEY(project_key, session_id));\nCREATE TABLE IF NOT EXISTS raw_entries (project_key TEXT NOT NULL, session_id TEXT NOT NULL, entry_id TEXT NOT NULL, revision INTEGER NOT NULL, role TEXT NOT NULL, content TEXT NOT NULL, content_hash TEXT NOT NULL, payload_json TEXT NOT NULL, parent_entry_id TEXT, branch TEXT, created_at INTEGER NOT NULL, PRIMARY KEY(project_key, session_id, entry_id, revision), UNIQUE(project_key, session_id, entry_id, content_hash));\nCREATE TABLE IF NOT EXISTS summary_nodes (node_id TEXT PRIMARY KEY, project_key TEXT NOT NULL, payload TEXT NOT NULL, created_at INTEGER NOT NULL);\nCREATE TABLE IF NOT EXISTS summary_node_revisions (node_id TEXT NOT NULL REFERENCES summary_nodes(node_id), revision INTEGER NOT NULL, project_key TEXT NOT NULL, text TEXT NOT NULL, model_hash TEXT NOT NULL, created_at INTEGER NOT NULL, PRIMARY KEY(node_id, revision));\nCREATE TABLE IF NOT EXISTS summary_edges (parent_id TEXT NOT NULL REFERENCES summary_nodes(node_id), child_id TEXT NOT NULL REFERENCES summary_nodes(node_id), PRIMARY KEY(parent_id, child_id));\nCREATE TABLE IF NOT EXISTS frontiers (project_key TEXT NOT NULL, frontier_id TEXT NOT NULL, node_id TEXT NOT NULL, created_at INTEGER NOT NULL, PRIMARY KEY(project_key, frontier_id, node_id));\nCREATE TABLE IF NOT EXISTS maintenance_jobs (job_id TEXT PRIMARY KEY, project_key TEXT NOT NULL, status TEXT NOT NULL, payload TEXT NOT NULL, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL);\nCREATE TABLE IF NOT EXISTS maintenance_usage (project_key TEXT NOT NULL, day TEXT NOT NULL, session_id TEXT NOT NULL, calls INTEGER NOT NULL, input_tokens INTEGER NOT NULL, output_tokens INTEGER NOT NULL, cost REAL NOT NULL, wall_ms INTEGER NOT NULL, PRIMARY KEY(project_key,day,session_id));\nCREATE TABLE IF NOT EXISTS repair_ladder (project_key TEXT NOT NULL, fault TEXT NOT NULL, attempts INTEGER NOT NULL, next_at INTEGER NOT NULL, updated_at INTEGER NOT NULL, detail TEXT NOT NULL, PRIMARY KEY(project_key, fault));\nCREATE TABLE IF NOT EXISTS orphaned_rows (migration_version INTEGER NOT NULL, table_name TEXT NOT NULL, row_json TEXT NOT NULL, detected_at INTEGER NOT NULL);\nCREATE INDEX IF NOT EXISTS raw_entries_lookup ON raw_entries(project_key, session_id, entry_id, revision);\nDROP INDEX IF EXISTS raw_entries_recent;\nCREATE INDEX IF NOT EXISTS raw_entries_session_order ON raw_entries(project_key, session_id, created_at, revision);\nCREATE INDEX IF NOT EXISTS summary_nodes_order ON summary_nodes(project_key, created_at, node_id);\nCREATE INDEX IF NOT EXISTS maintenance_jobs_status ON maintenance_jobs(project_key, status);\nCREATE INDEX IF NOT EXISTS summary_edges_child ON summary_edges(child_id, parent_id);\n`;\n\nconst fileHash = (file: string) => crypto.createHash(\"sha256\").update(fs.readFileSync(file)).digest(\"hex\");\nconst snapshotHash = (db: SqliteDatabase): string => {\n const digest = crypto.createHash(\"sha256\");\n for (const [table, order] of [[\"schema_metadata\", \"key\"], [\"projects\", \"project_key\"], [\"project_aliases\", \"alias\"], [\"sessions\", \"project_key,session_id\"], [\"raw_entries\", \"project_key,session_id,entry_id,revision\"], [\"summary_nodes\", \"node_id\"], [\"summary_edges\", \"parent_id,child_id\"], [\"frontiers\", \"project_key,frontier_id,node_id\"], [\"maintenance_jobs\", \"job_id\"], [\"maintenance_usage\", \"project_key,day,session_id\"], [\"repair_ladder\", \"project_key,fault\"], [\"orphaned_rows\", \"migration_version,table_name,row_json\"]] as const) {\n digest.update(`${table}\\0`);\n for (const row of db.prepare(`SELECT * FROM ${table} ORDER BY ${order}`).all()) digest.update(`${JSON.stringify(row)}\\0`);\n }\n return digest.digest(\"hex\");\n};\n\nconst toRawEntry = (row: Record<string, unknown>): RawEntry => ({ projectKey: row.project_key as string, sessionId: row.session_id as string, entryId: row.entry_id as string, revision: Number(row.revision), role: row.role as string, content: row.content as string, contentHash: row.content_hash as string, payloadHash: row.content_hash as string, payloadJson: row.payload_json as string, parentEntryId: row.parent_entry_id as string | null, branch: row.branch as string | null, createdAt: row.created_at as number });\nconst toRawEntries = (rows: unknown[]): RawEntry[] => (rows as Array<Record<string, unknown>>).map(toRawEntry);\n\nconst probeFts5 = (db: SqliteDatabase): boolean => {\n try { db.exec(\"CREATE VIRTUAL TABLE temp.lcm_fts5_probe USING fts5(probe); DROP TABLE temp.lcm_fts5_probe;\"); return true; }\n catch { try { db.exec(\"DROP TABLE IF EXISTS temp.lcm_fts5_probe\"); } catch {} return false; }\n};\n\nconst foldToken = (value: string): string => value.normalize(\"NFD\").replace(/\\p{M}+/gu, \"\").toLowerCase();\nconst tokenize = (value: string): string[] => value.split(/[^\\p{L}\\p{N}]+/u).map(foldToken).filter(token => token.length > 0);\nconst searchPhrases = (query: string, mode: LcmSearchMode): string[][] =>\n (mode === \"phrase\" ? [query] : query.split(/\\s+/)).map(tokenize).filter(phrase => phrase.length > 0);\nconst ftsExpression = (phrases: string[][], match: \"any\" | \"all\"): string =>\n phrases.map(phrase => `\"${phrase.join(\" \")}\"`).join(match === \"all\" ? \" AND \" : \" OR \");\nconst containsPhrase = (tokens: string[], phrase: string[]): boolean => {\n for (let start = 0; start + phrase.length <= tokens.length; start++) {\n let hit = true;\n for (let offset = 0; offset < phrase.length; offset++) if (tokens[start + offset] !== phrase[offset]) { hit = false; break; }\n if (hit) return true;\n }\n return false;\n};\nconst phrasePredicate = (phrases: string[][], match: \"any\" | \"all\"): (content: string) => boolean =>\n match === \"all\"\n ? content => { const tokens = tokenize(content); return phrases.every(phrase => containsPhrase(tokens, phrase)); }\n : content => { const tokens = tokenize(content); return phrases.some(phrase => containsPhrase(tokens, phrase)); };\n\nclass LedgerDegradedError extends Error { constructor(message: string, public readonly cause?: unknown) { super(message); this.name = \"LedgerDegradedError\"; } }\n\nexport class LcmLedger {\n readonly db: SqliteDatabase;\n readonly project: ProjectIdentity;\n private degraded = false;\n private readonly dbPath: string;\n private readonly now: () => number;\n private readonly warningBytes: number;\n private readonly maintenanceBytes: number;\n private writeChain: Promise<void> = Promise.resolve();\n private transactionDepth = 0;\n private closed = false;\n private fts = false;\n readonly migrations: LedgerMigrationReport[] = [];\n constructor(options: LedgerOptions = {}) {\n this.now = options.now ?? Date.now;\n this.warningBytes = options.warningBytes ?? LCM_LEDGER_WARNING_BYTES;\n this.maintenanceBytes = options.maintenanceBytes ?? LCM_LEDGER_MAINTENANCE_BYTES;\n if (!Number.isSafeInteger(this.warningBytes) || !Number.isSafeInteger(this.maintenanceBytes) || this.warningBytes < 0 || this.maintenanceBytes < this.warningBytes) {\n throw new Error(\"invalid ledger size thresholds\");\n }\n const identity = canonicalProjectIdentity(options.project ?? { liveCwd: process.cwd() });\n const adopted = options.projectKey\n ?? (options.dbPath ? identity.key : stableProjectKey(options.rootDir ?? defaultLedgerRoot(), identity, this.now()));\n this.project = adopted === identity.key ? identity : { ...identity, key: adopted };\n const dbPath = options.dbPath ?? defaultLedgerPath(options.rootDir, this.project.key);\n fs.mkdirSync(path.dirname(dbPath), { recursive: true });\n this.dbPath = dbPath;\n this.db = new (sqliteDriver())(dbPath);\n try {\n this.db.exec(\"PRAGMA journal_mode=WAL; PRAGMA synchronous=FULL; PRAGMA busy_timeout=5000; PRAGMA wal_autocheckpoint=1000;\");\n this.db.exec(\"BEGIN IMMEDIATE;\" + SCHEMA + \"COMMIT;\");\n const columns = this.db.prepare(\"PRAGMA table_info(raw_entries)\").all() as Array<{ name: string }>;\n if (!columns.some(column => column.name === \"payload_json\")) {\n if (Number((this.db.prepare(\"SELECT count(*) n FROM raw_entries\").get() as { n: number }).n)) throw new Error(\"raw payloads missing; reimport authoritative session entries\");\n this.db.exec(\"ALTER TABLE raw_entries ADD COLUMN payload_json TEXT NOT NULL DEFAULT ''\");\n }\n this.fts = probeFts5(this.db);\n this.migrateSchema();\n this.db.exec(\"PRAGMA foreign_keys=ON\");\n const result = this.db.prepare(\"PRAGMA integrity_check\").get() as { integrity_check?: string };\n if (result.integrity_check !== \"ok\") throw new Error(String(result.integrity_check));\n this.registerProject(this.project);\n } catch (error) { this.degraded = true; throw new LedgerDegradedError(\"ledger startup failed\", error); }\n }\n readRepairLadder(projectKey = this.project.key): Map<string, { attempts: number; nextAt: number; detail: string; updatedAt: number }> {\n return this.readOnly(db => new Map((db.prepare(\"SELECT fault,attempts,next_at,detail,updated_at FROM repair_ladder WHERE project_key=?\").all(projectKey) as Array<{ fault: string; attempts: number; next_at: number; detail: string; updated_at: number }>).map(row => [row.fault, { attempts: Number(row.attempts), nextAt: Number(row.next_at), detail: row.detail, updatedAt: Number(row.updated_at) }])));\n }\n writeRepairLadder(fault: string, attempts: number, nextAt: number, detail: string): void {\n this.transaction(db => db.prepare(\"INSERT INTO repair_ladder(project_key,fault,attempts,next_at,updated_at,detail) VALUES(?,?,?,?,?,?) ON CONFLICT(project_key,fault) DO UPDATE SET attempts=excluded.attempts,next_at=excluded.next_at,updated_at=excluded.updated_at,detail=excluded.detail\").run(this.project.key, fault, attempts, nextAt, this.now(), detail));\n }\n clearRepairLadder(fault: string): void {\n this.transaction(db => db.prepare(\"DELETE FROM repair_ladder WHERE project_key=? AND fault=?\").run(this.project.key, fault));\n }\n get isDegraded() { return this.degraded; }\n get file(): string { return this.dbPath; }\n get bytes(): number { try { return fs.statSync(this.dbPath).size; } catch { return 0; } }\n get operationalState(): OperationalState {\n if (this.degraded) return \"degraded\";\n try { const size = fs.statSync(this.dbPath).size; if (size >= this.maintenanceBytes) return \"maintenance\"; if (size >= this.warningBytes) return \"warning\"; } catch {}\n return \"healthy\";\n }\n markDegraded(error?: unknown) { this.degraded = true; return new LedgerDegradedError(\"ledger is degraded\", error); }\n private registerProject(identity: ProjectIdentity) {\n const now = this.now();\n this.db.prepare(\"INSERT INTO projects(project_key,identity_json,created_at,updated_at) VALUES(?,?,?,?) ON CONFLICT(project_key) DO UPDATE SET identity_json=excluded.identity_json,updated_at=excluded.updated_at\").run(identity.key, JSON.stringify(identity), now, now);\n for (const alias of identity.aliases) {\n const existing = this.db.prepare(\"SELECT project_key FROM project_aliases WHERE alias=?\").get(alias) as { project_key?: string } | undefined;\n if (existing && existing.project_key !== identity.key) throw new LedgerDegradedError(`ambiguous project alias: ${alias}`);\n this.db.prepare(\"INSERT OR IGNORE INTO project_aliases(alias,project_key) VALUES(?,?)\").run(alias, identity.key);\n }\n }\n get ftsAvailable() { return this.fts; }\n private schemaVersion(): number {\n const row = this.db.prepare(\"SELECT value FROM schema_metadata WHERE key='version'\").get() as { value?: string } | undefined;\n const version = Number(row?.value ?? 0);\n return Number.isSafeInteger(version) && version > 0 ? version : 0;\n }\n private hasObject(type: string, name: string): boolean {\n return this.db.prepare(\"SELECT 1 FROM sqlite_master WHERE type=? AND name=?\").get(type, name) !== undefined;\n }\n private indexOutOfStep(): boolean {\n if (this.fts !== this.hasObject(\"table\", \"raw_entries_fts\")) return true;\n if (!this.fts) return false;\n if (!this.hasObject(\"trigger\", \"raw_entries_fts_insert\")) return true;\n return Number((this.db.prepare(\"SELECT count(*) n FROM raw_entries_fts\").get() as { n: number }).n) !== Number((this.db.prepare(\"SELECT count(*) n FROM raw_entries\").get() as { n: number }).n);\n }\n private migrateSchema(): void {\n const version = this.schemaVersion();\n if (version < 2 || this.indexOutOfStep()) this.migrations.push(this.migrateFullTextIndex());\n if (version < 3 || (this.db.prepare(\"PRAGMA foreign_key_list(summary_edges)\").all().length === 0)) this.migrations.push(this.migrateDerivedForeignKeys());\n if (version !== LEDGER_SCHEMA_VERSION) this.db.prepare(\"INSERT INTO schema_metadata(key,value) VALUES('version',?) ON CONFLICT(key) DO UPDATE SET value=excluded.value\").run(String(LEDGER_SCHEMA_VERSION));\n }\n private migrateFullTextIndex(): LedgerMigrationReport {\n if (!this.fts) {\n this.db.exec(\"DROP TRIGGER IF EXISTS raw_entries_fts_insert\");\n return { version: 2, name: \"raw-entries-fts\", applied: false, reason: \"sqlite driver has no fts5 module\", counts: { indexed: 0 } };\n }\n let indexed = 0;\n this.transaction(db => {\n db.exec(\"CREATE VIRTUAL TABLE IF NOT EXISTS raw_entries_fts USING fts5(content, project_key UNINDEXED, session_id UNINDEXED, entry_id UNINDEXED, revision UNINDEXED)\");\n db.exec(\"CREATE TRIGGER IF NOT EXISTS raw_entries_fts_insert AFTER INSERT ON raw_entries BEGIN INSERT INTO raw_entries_fts(content,project_key,session_id,entry_id,revision) VALUES(new.content,new.project_key,new.session_id,new.entry_id,new.revision); END\");\n indexed = Number((db.prepare(\"SELECT count(*) n FROM raw_entries\").get() as { n: number }).n);\n if (Number((db.prepare(\"SELECT count(*) n FROM raw_entries_fts\").get() as { n: number }).n) === indexed) return;\n db.exec(\"DELETE FROM raw_entries_fts\");\n db.exec(\"INSERT INTO raw_entries_fts(content,project_key,session_id,entry_id,revision) SELECT content,project_key,session_id,entry_id,revision FROM raw_entries\");\n });\n return { version: 2, name: \"raw-entries-fts\", applied: true, counts: { indexed } };\n }\n private migrateDerivedForeignKeys(): LedgerMigrationReport {\n const counts: Record<string, number> = { summary_edges: 0, summary_node_revisions: 0 };\n this.transaction(db => {\n const detectedAt = this.now();\n const known = \"(SELECT node_id FROM summary_nodes)\";\n const quarantine = (table: string, orphaned: string): void => {\n const rows = db.prepare(`SELECT * FROM ${table} WHERE ${orphaned}`).all() as Array<Record<string, unknown>>;\n for (const row of rows) db.prepare(\"INSERT INTO orphaned_rows(migration_version,table_name,row_json,detected_at) VALUES(?,?,?,?)\").run(LEDGER_SCHEMA_VERSION, table, JSON.stringify(row), detectedAt);\n counts[table] = rows.length;\n };\n quarantine(\"summary_edges\", `parent_id NOT IN ${known} OR child_id NOT IN ${known}`);\n db.exec(`CREATE TABLE summary_edges_next (parent_id TEXT NOT NULL REFERENCES summary_nodes(node_id), child_id TEXT NOT NULL REFERENCES summary_nodes(node_id), PRIMARY KEY(parent_id, child_id));\nINSERT INTO summary_edges_next(parent_id,child_id) SELECT parent_id,child_id FROM summary_edges WHERE parent_id IN ${known} AND child_id IN ${known};\nDROP TABLE summary_edges;\nALTER TABLE summary_edges_next RENAME TO summary_edges;`);\n quarantine(\"summary_node_revisions\", `node_id NOT IN ${known}`);\n db.exec(`CREATE TABLE summary_node_revisions_next (node_id TEXT NOT NULL REFERENCES summary_nodes(node_id), revision INTEGER NOT NULL, project_key TEXT NOT NULL, text TEXT NOT NULL, model_hash TEXT NOT NULL, created_at INTEGER NOT NULL, PRIMARY KEY(node_id, revision));\nINSERT INTO summary_node_revisions_next(node_id,revision,project_key,text,model_hash,created_at) SELECT node_id,revision,project_key,text,model_hash,created_at FROM summary_node_revisions WHERE node_id IN ${known};\nDROP TABLE summary_node_revisions;\nALTER TABLE summary_node_revisions_next RENAME TO summary_node_revisions;`);\n });\n return { version: 3, name: \"derived-foreign-keys\", applied: true, counts };\n }\n private guard() { if (this.degraded) throw new LedgerDegradedError(\"ledger is degraded\"); }\n private assertProjectKey(projectKey: string) { if (projectKey !== this.project.key) throw new Error(\"project key does not match ledger project\"); }\n async serialize<T>(operation: () => T): Promise<T> { const previous = this.writeChain; let release!: () => void; this.writeChain = new Promise<void>(resolve => { release = resolve }); await previous; try { this.guard(); return operation(); } finally { release(); } }\n appendRaw(entry: SessionEntry): RawEntry {\n this.guard();\n if (entry.projectKey !== this.project.key) throw new Error(\"entry project does not match ledger project\");\n if (entry.entryId.trim().length === 0) throw new Error(\"entry ID is required\");\n if (typeof entry.payloadJson !== \"string\" || !entry.payloadJson.trim()) throw new Error(\"full payload JSON is required\");\n let payload: Record<string, unknown>;\n try { payload = JSON.parse(entry.payloadJson) as Record<string, unknown>; } catch { throw new Error(\"invalid payload JSON\"); }\n if (!payload || typeof payload !== \"object\" || typeof payload.type !== \"string\" || typeof payload.id !== \"string\" || payload.id !== entry.entryId) throw new Error(\"payload must be a full SessionEntry\");\n const payloadJson = canonicalLcmPayload(payload);\n const contentHash = hashLcmPayload(payload);\n const ownsTransaction = this.transactionDepth === 0;\n if (ownsTransaction) this.db.exec(\"BEGIN IMMEDIATE\");\n try {\n const existing = this.db.prepare(\"SELECT revision,created_at FROM raw_entries WHERE project_key=? AND session_id=? AND entry_id=? AND content_hash=?\").get(entry.projectKey, entry.sessionId, entry.entryId, contentHash) as { revision: number; created_at: number } | undefined;\n if (existing) { if (ownsTransaction) this.db.exec(\"COMMIT\"); return { ...entry, payloadJson, payloadHash: contentHash, revision: existing.revision, contentHash, createdAt: existing.created_at }; }\n const latest = this.db.prepare(\"SELECT COALESCE(MAX(revision),0) revision FROM raw_entries WHERE project_key=? AND session_id=? AND entry_id=?\").get(entry.projectKey, entry.sessionId, entry.entryId) as { revision: number };\n const revision = latest.revision + 1; const createdAt = entry.createdAt ?? this.now();\n this.db.prepare(\"INSERT OR IGNORE INTO sessions(project_key,session_id,created_at) VALUES(?,?,?)\").run(entry.projectKey, entry.sessionId, createdAt);\n this.db.prepare(\"INSERT INTO raw_entries(project_key,session_id,entry_id,revision,role,content,content_hash,payload_json,parent_entry_id,branch,created_at) VALUES(?,?,?,?,?,?,?,?,?,?,?)\").run(entry.projectKey,entry.sessionId,entry.entryId,revision,entry.role,entry.content,contentHash,payloadJson,entry.parentEntryId ?? null,entry.branch ?? null,createdAt);\n if (ownsTransaction) this.db.exec(\"COMMIT\");\n return { ...entry, payloadJson, payloadHash: contentHash, revision, contentHash, createdAt };\n } catch (error) {\n if (ownsTransaction) this.db.exec(\"ROLLBACK\");\n const code = (error as NodeJS.ErrnoException).code; if (code === \"ENOSPC\" || code === \"SQLITE_FULL\" || String(error).includes(\"database or disk is full\")) this.degraded = true; throw new LedgerDegradedError(\"ledger write failed\", error);\n }\n }\n readRaw(projectKey = this.project.key, sessionId?: string): RawEntry[] { this.guard(); this.assertProjectKey(projectKey); const rows = sessionId ? this.db.prepare(\"SELECT * FROM raw_entries WHERE project_key=? AND session_id=? ORDER BY created_at,revision,rowid\").all(projectKey,sessionId) : this.db.prepare(\"SELECT * FROM raw_entries WHERE project_key=? ORDER BY created_at,session_id,entry_id,revision\").all(projectKey); return toRawEntries(rows); }\n readRawPage(projectKey = this.project.key, sessionId?: string, offset = 0, limit = 100): RawEntry[] { if (!Number.isSafeInteger(offset) || offset < 0 || !Number.isSafeInteger(limit) || limit < 1) throw new Error(\"invalid raw page\"); this.guard(); this.assertProjectKey(projectKey); const rows = sessionId ? this.db.prepare(\"SELECT * FROM raw_entries WHERE project_key=? AND session_id=? ORDER BY created_at,revision,rowid LIMIT ? OFFSET ?\").all(projectKey,sessionId,limit,offset) : this.db.prepare(\"SELECT * FROM raw_entries WHERE project_key=? ORDER BY created_at,session_id,entry_id,revision LIMIT ? OFFSET ?\").all(projectKey,limit,offset); return toRawEntries(rows); }\n readRawEntry(projectKey: string, sessionId: string, entryId: string, revision: number): RawEntry | undefined { this.guard(); this.assertProjectKey(projectKey); const row = this.db.prepare(\"SELECT * FROM raw_entries WHERE project_key=? AND session_id=? AND entry_id=? AND revision=?\").get(projectKey,sessionId,entryId,revision) as Record<string, unknown> | undefined; return row ? toRawEntry(row) : undefined; }\n searchRaw(projectKey: string | undefined, options: LcmSearchOptions): LcmSearchPage {\n this.guard();\n const key = projectKey ?? this.project.key;\n this.assertProjectKey(key);\n const { offset, limit, sessionId } = options;\n if (!Number.isSafeInteger(offset) || offset < 0 || !Number.isSafeInteger(limit) || limit < 1) throw new Error(\"invalid raw page\");\n const scanLimit = options.scanLimit ?? LCM_SEARCH_SCAN_LIMIT;\n if (!Number.isSafeInteger(scanLimit) || scanLimit < 1) throw new Error(\"invalid scan limit\");\n const query = options.query?.trim() ?? \"\";\n if (query.length === 0) return this.recentPage(key, sessionId, offset, limit);\n if (options.mode === \"regex\") {\n let pattern: RegExp;\n try { pattern = new RegExp(query, \"iu\"); } catch { return { rows: [], total: 0, scanned: 0, complete: false }; }\n return this.scanPage(key, sessionId, content => pattern.test(content), offset, limit, scanLimit, false);\n }\n const match = options.match ?? \"any\";\n const phrases = searchPhrases(query, options.mode);\n if (phrases.length === 0) return { rows: [], total: 0, scanned: 0, complete: true };\n if (this.fts) { try { return this.indexPage(key, sessionId, ftsExpression(phrases, match), offset, limit); } catch {} }\n return this.scanPage(key, sessionId, phrasePredicate(phrases, match), offset, limit, scanLimit, true);\n }\n private recentPage(key: string, sessionId: string | undefined, offset: number, limit: number): LcmSearchPage {\n const counted = (sessionId\n ? this.db.prepare(\"SELECT count(*) n FROM raw_entries WHERE project_key=? AND session_id=?\").get(key, sessionId)\n : this.db.prepare(\"SELECT count(*) n FROM raw_entries WHERE project_key=?\").get(key)) as { n: number };\n const total = Number(counted.n);\n const rows = sessionId\n ? this.db.prepare(\"SELECT * FROM raw_entries WHERE project_key=? AND session_id=? ORDER BY created_at DESC, revision DESC, rowid DESC LIMIT ? OFFSET ?\").all(key, sessionId, limit, offset)\n : this.db.prepare(\"SELECT * FROM raw_entries WHERE project_key=? ORDER BY created_at DESC, revision DESC, rowid DESC LIMIT ? OFFSET ?\").all(key, limit, offset);\n return { rows: toRawEntries(rows), total, scanned: total, complete: true };\n }\n private indexPage(key: string, sessionId: string | undefined, expression: string, offset: number, limit: number): LcmSearchPage {\n const source = \"FROM raw_entries_fts JOIN raw_entries r ON r.project_key=raw_entries_fts.project_key AND r.session_id=raw_entries_fts.session_id AND r.entry_id=raw_entries_fts.entry_id AND r.revision=CAST(raw_entries_fts.revision AS INTEGER) WHERE raw_entries_fts MATCH ? AND raw_entries_fts.project_key=?\" + (sessionId ? \" AND raw_entries_fts.session_id=?\" : \"\");\n const filters = sessionId ? [expression, key, sessionId] : [expression, key];\n const total = Number((this.db.prepare(`SELECT count(*) n ${source}`).get(...filters) as { n: number }).n);\n const rows = this.db.prepare(`SELECT r.* ${source} ORDER BY r.created_at DESC, r.revision DESC, r.rowid DESC LIMIT ? OFFSET ?`).all(...filters, limit, offset);\n return { rows: toRawEntries(rows), total, scanned: total, complete: true };\n }\n private scanPage(key: string, sessionId: string | undefined, matches: (content: string) => boolean, offset: number, limit: number, scanLimit: number, degraded: boolean): LcmSearchPage {\n const statement = sessionId\n ? this.db.prepare(\"SELECT session_id,entry_id,revision,content FROM raw_entries WHERE project_key=? AND session_id=? ORDER BY created_at DESC, revision DESC, rowid DESC LIMIT ? OFFSET ?\")\n : this.db.prepare(\"SELECT session_id,entry_id,revision,content FROM raw_entries WHERE project_key=? ORDER BY created_at DESC, revision DESC, rowid DESC LIMIT ? OFFSET ?\");\n const found: Array<{ sessionId: string; entryId: string; revision: number }> = [];\n let scanned = 0;\n let exhausted = false;\n while (scanned < scanLimit) {\n const size = Math.min(LCM_SCAN_BATCH, scanLimit - scanned);\n const batch = (sessionId ? statement.all(key, sessionId, size, scanned) : statement.all(key, size, scanned)) as Array<Record<string, unknown>>;\n scanned += batch.length;\n for (const row of batch) if (matches(row.content as string)) found.push({ sessionId: row.session_id as string, entryId: row.entry_id as string, revision: Number(row.revision) });\n if (batch.length < size) { exhausted = true; break; }\n }\n const rows: RawEntry[] = [];\n for (const identity of found.slice(offset, offset + limit)) {\n const entry = this.readRawEntry(key, identity.sessionId, identity.entryId, identity.revision);\n if (entry) rows.push(entry);\n }\n return { rows, total: found.length, scanned, complete: degraded ? false : exhausted };\n }\n /** Identity columns only, so a coverage scan never loads payloads. */\n readRawKeys(projectKey = this.project.key, sessionId?: string, limit = 100_000): Array<{ sessionId: string; entryId: string; revision: number; contentHash: string }> {\n this.guard(); this.assertProjectKey(projectKey);\n const rows = sessionId\n ? this.db.prepare(\"SELECT session_id, entry_id, revision, content_hash FROM raw_entries WHERE project_key=? AND session_id=? ORDER BY created_at,revision,rowid LIMIT ?\").all(projectKey, sessionId, limit)\n : this.db.prepare(\"SELECT session_id, entry_id, revision, content_hash FROM raw_entries WHERE project_key=? ORDER BY created_at,session_id,entry_id,revision LIMIT ?\").all(projectKey, limit);\n return (rows as Array<Record<string, unknown>>).map(row => ({ sessionId: row.session_id as string, entryId: row.entry_id as string, revision: Number(row.revision), contentHash: row.content_hash as string }));\n }\n /** Total stored payload bytes for one session, as a single aggregate. */\n payloadBytes(projectKey = this.project.key, sessionId?: string): number {\n this.guard(); this.assertProjectKey(projectKey);\n const row = sessionId\n ? this.db.prepare(\"SELECT coalesce(sum(length(payload_json)),0) n FROM raw_entries WHERE project_key=? AND session_id=?\").get(projectKey, sessionId)\n : this.db.prepare(\"SELECT coalesce(sum(length(payload_json)),0) n FROM raw_entries WHERE project_key=?\").get(projectKey);\n return Number((row as { n: number }).n);\n }\n readOnly<T>(fn: (db: SqliteDatabase) => T): T { this.guard(); return fn(this.db); }\n transaction<T>(fn: (db: SqliteDatabase) => T): T { this.guard(); if (this.transactionDepth > 0) return fn(this.db); this.db.exec(\"BEGIN IMMEDIATE\"); this.transactionDepth = 1; try { const result = fn(this.db); this.db.exec(\"COMMIT\"); return result; } catch (error) { this.db.exec(\"ROLLBACK\"); throw error; } finally { this.transactionDepth = 0; } }\n checkpoint(mode: \"passive\" | \"truncate\" = \"passive\"): CheckpointMetrics {\n const row = this.db.prepare(`PRAGMA wal_checkpoint(${mode.toUpperCase()})`).get() as { busy?: number; log?: number; checkpointed?: number };\n const busy = row.busy ?? 0;\n const logPages = row.log ?? 0;\n return { mode, busy, logPages, checkpointedPages: row.checkpointed ?? 0, truncated: mode === \"truncate\" && busy === 0 && logPages === 0 };\n }\n backup(destination: string): BackupManifest {\n this.guard();\n return this.serializeSync(() => {\n const target = path.resolve(destination);\n fs.mkdirSync(path.dirname(target), { recursive: true });\n if (fs.existsSync(target)) throw new Error(\"backup destination exists\");\n this.db.exec(`VACUUM INTO '${target.replace(/'/g, \"''\")}'`);\n fs.chmodSync(target, 0o600);\n const copy = new (sqliteDriver())(target);\n let integrity = \"unknown\";\n let backupStateSha256 = \"\";\n const rowCounts: Record<string, number> = {};\n try {\n integrity = (copy.prepare(\"PRAGMA integrity_check\").get() as { integrity_check?: string }).integrity_check ?? \"unknown\";\n for (const table of [\"projects\", \"sessions\", \"raw_entries\", \"summary_nodes\", \"summary_node_revisions\", \"summary_edges\", \"frontiers\", \"maintenance_jobs\", \"maintenance_usage\", \"repair_ladder\", \"orphaned_rows\"]) {\n rowCounts[table] = Number((copy.prepare(`SELECT count(*) n FROM ${table}`).get() as { n: number }).n);\n }\n backupStateSha256 = snapshotHash(copy);\n } finally {\n copy.close();\n }\n const manifest: BackupManifest = { format: \"lcm-ledger-backup\", version: BACKUP_MANIFEST_VERSION, source: this.dbPath, destination: target, sourceSha256: fileHash(this.dbPath), backupSha256: fileHash(target), sourceStateSha256: backupStateSha256, rowCounts, integrity, createdAt: this.now() };\n fs.writeFileSync(`${target}.manifest.json`, JSON.stringify(manifest), { mode: 0o600 });\n fs.chmodSync(`${target}.manifest.json`, 0o600);\n return manifest;\n });\n }\n exportBackup(destination: string): BackupManifest { return this.backup(destination); }\n private orphanOwner(db: SqliteDatabase, rowJson: string): string | undefined {\n let row: Record<string, unknown>;\n try { row = JSON.parse(rowJson) as Record<string, unknown>; } catch { return undefined; }\n if (typeof row.project_key === \"string\") return row.project_key;\n for (const column of [\"node_id\", \"parent_id\", \"child_id\"]) {\n const nodeId = row[column];\n if (typeof nodeId !== \"string\") continue;\n const owner = db.prepare(\"SELECT project_key FROM summary_nodes WHERE node_id=?\").get(nodeId) as { project_key?: string } | undefined;\n if (owner?.project_key !== undefined) return owner.project_key;\n }\n return undefined;\n }\n private projectFootprint(): { remaining: Record<string, number>; unattributed: Record<string, number> } {\n const key = this.project.key;\n const count = (sql: string, ...params: unknown[]): number => Number((this.db.prepare(sql).get(...params) as { n: number }).n);\n const remaining: Record<string, number> = {};\n for (const table of PROJECT_KEYED_TABLES) remaining[table] = count(`SELECT count(*) n FROM ${table} WHERE project_key=?`, key);\n remaining.summary_edges = count(\"SELECT count(*) n FROM summary_edges WHERE parent_id IN (SELECT node_id FROM summary_nodes WHERE project_key=?) OR child_id IN (SELECT node_id FROM summary_nodes WHERE project_key=?)\", key, key);\n if (this.fts) remaining.raw_entries_fts = count(\"SELECT count(*) n FROM raw_entries_fts WHERE project_key=?\", key);\n const unattributed: Record<string, number> = {};\n remaining.orphaned_rows = 0;\n for (const row of this.db.prepare(\"SELECT row_json FROM orphaned_rows\").all() as Array<{ row_json: string }>) {\n const owner = this.orphanOwner(this.db, row.row_json);\n if (owner === key) remaining.orphaned_rows++;\n else if (owner === undefined) unattributed.orphaned_rows = (unattributed.orphaned_rows ?? 0) + 1;\n }\n const dangling = count(\"SELECT count(*) n FROM summary_edges WHERE parent_id NOT IN (SELECT node_id FROM summary_nodes) OR child_id NOT IN (SELECT node_id FROM summary_nodes)\");\n if (dangling > 0) unattributed.summary_edges = dangling;\n return { remaining, unattributed };\n }\n deleteProject(token: DeleteConfirmationToken, backupManifest: BackupManifest): void {\n this.guard();\n if (token.__brand !== \"DeleteConfirmationToken\" || token.projectKey !== this.project.key || token.value !== hash(`delete:${this.project.key}`)) throw new Error(\"invalid delete confirmation token\");\n if (backupManifest.version !== BACKUP_MANIFEST_VERSION) throw new Error(`backup manifest version ${backupManifest.version} predates this ledger (expected ${BACKUP_MANIFEST_VERSION}); take a fresh backup`);\n const backupDb = fs.existsSync(backupManifest.destination) ? new (sqliteDriver())(backupManifest.destination) : undefined;\n let backupStateSha256: string | undefined;\n try {\n if (backupDb) backupStateSha256 = snapshotHash(backupDb);\n } finally {\n backupDb?.close();\n }\n if (backupManifest.integrity !== \"ok\" || backupManifest.source !== this.dbPath || !backupManifest.backupSha256 || backupManifest.backupSha256 !== fileHash(backupManifest.destination) || !backupManifest.sourceStateSha256 || backupManifest.sourceStateSha256 !== backupStateSha256 || backupManifest.sourceSha256 !== fileHash(this.dbPath) || backupManifest.sourceStateSha256 !== snapshotHash(this.db)) throw new Error(\"backup verification failed\");\n this.transaction(db => {\n const purge = db.prepare(\"DELETE FROM orphaned_rows WHERE rowid=?\");\n for (const row of db.prepare(\"SELECT rowid AS id, row_json FROM orphaned_rows\").all() as Array<{ id: number; row_json: string }>) {\n if (this.orphanOwner(db, row.row_json) === this.project.key) purge.run(row.id);\n }\n db.prepare(\"DELETE FROM summary_edges WHERE parent_id IN (SELECT node_id FROM summary_nodes WHERE project_key=?) OR child_id IN (SELECT node_id FROM summary_nodes WHERE project_key=?)\").run(this.project.key, this.project.key);\n for (const table of [\"raw_entries\", \"sessions\", \"frontiers\", \"summary_node_revisions\", \"summary_nodes\", \"maintenance_jobs\", \"maintenance_usage\", \"repair_ladder\"]) db.prepare(`DELETE FROM ${table} WHERE project_key=?`).run(this.project.key);\n if (this.fts) db.prepare(\"DELETE FROM raw_entries_fts WHERE project_key=?\").run(this.project.key);\n db.prepare(\"DELETE FROM project_aliases WHERE project_key=?\").run(this.project.key);\n db.prepare(\"DELETE FROM projects WHERE project_key=?\").run(this.project.key);\n });\n const integrity = (this.db.prepare(\"PRAGMA integrity_check\").get() as { integrity_check?: string }).integrity_check;\n if (integrity !== \"ok\") throw new Error(`post-delete integrity failed: ${integrity}`);\n const footprint = this.projectFootprint();\n const total = (counts: Record<string, number>): number => Object.values(counts).reduce((sum, value) => sum + value, 0);\n const audit: DeleteManifest = { format: \"lcm-ledger-delete\", version: DELETE_MANIFEST_VERSION, projectKey: this.project.key, deletedAt: this.now(), integrity, remaining: total(footprint.remaining), remainingByTable: footprint.remaining, unattributed: total(footprint.unattributed), unattributedByTable: footprint.unattributed };\n fs.writeFileSync(`${backupManifest.destination}.delete-manifest.json`, JSON.stringify(audit), { mode: 0o600 });\n }\n private serializeSync<T>(operation: () => T): T { this.guard(); return operation(); }\n close() { if (this.closed) return; this.db.close(); this.closed = true; }\n}\n", "import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { writeJsonAtomic } from \"../core/atomic-write.js\";\nimport { defaultLedgerPath, type ProjectIdentity } from \"./lcm-identity.js\";\n\nconst DIRECTORY_FILE = \"projects.json\";\nconst DIRECTORY_VERSION = 1;\nconst SWEEP_INTERVAL_MS = 24 * 60 * 60 * 1_000;\nconst RETENTION_MS = 30 * 24 * 60 * 60 * 1_000;\n\ninterface LcmDirectoryRecord {\n key: string;\n path: string;\n updatedAt: number;\n}\n\ninterface LcmDirectoryFile {\n version: number;\n sweptAt: number;\n projects: LcmDirectoryRecord[];\n}\n\nexport interface LcmSweepResult {\n removed: string[];\n bytes: number;\n skipped: boolean;\n}\n\nconst empty = (): LcmDirectoryFile => ({ version: DIRECTORY_VERSION, sweptAt: 0, projects: [] });\n\nconst directoryFile = (rootDir: string): string => path.join(rootDir, DIRECTORY_FILE);\n\nconst read = (rootDir: string): LcmDirectoryFile => {\n try {\n const parsed = JSON.parse(fs.readFileSync(directoryFile(rootDir), \"utf8\")) as Partial<LcmDirectoryFile>;\n if (parsed.version !== DIRECTORY_VERSION || !Array.isArray(parsed.projects)) return empty();\n return {\n version: DIRECTORY_VERSION,\n sweptAt: typeof parsed.sweptAt === \"number\" ? parsed.sweptAt : 0,\n projects: parsed.projects.filter(\n (record): record is LcmDirectoryRecord =>\n typeof record?.key === \"string\" && typeof record.path === \"string\" && typeof record.updatedAt === \"number\",\n ),\n };\n } catch {\n return empty();\n }\n};\n\n/** Merges against the file on disk so a concurrent instance never loses its record. */\nconst write = (rootDir: string, file: LcmDirectoryFile, owned: readonly string[]): void => {\n try {\n fs.mkdirSync(rootDir, { recursive: true });\n const current = read(rootDir);\n const merged = new Map(current.projects.map((record) => [record.path, record] as const));\n for (const path of owned) merged.delete(path);\n for (const record of file.projects) merged.set(record.path, record);\n writeJsonAtomic(directoryFile(rootDir), {\n version: DIRECTORY_VERSION,\n sweptAt: Math.max(file.sweptAt, current.sweptAt),\n projects: [...merged.values()],\n });\n } catch {}\n};\n\nconst ledgerFiles = (key: string, rootDir: string): string[] => {\n const base = defaultLedgerPath(rootDir, key);\n return [base, `${base}-wal`, `${base}-shm`];\n};\n\n/** Remembers the key a canonical path was first filed under, so history follows the path across inode changes. */\nexport const stableProjectKey = (rootDir: string, identity: ProjectIdentity, now = Date.now()): string => {\n const canonicalPath = identity.canonicalPath;\n if (!canonicalPath) return identity.key;\n const file = read(rootDir);\n const record = file.projects.find((candidate) => candidate.path === canonicalPath);\n const adopted = record && record.key !== identity.key && fs.existsSync(defaultLedgerPath(rootDir, record.key))\n ? record.key\n : identity.key;\n write(rootDir, { ...file, projects: [{ key: adopted, path: canonicalPath, updatedAt: now }] }, [canonicalPath]);\n return adopted;\n};\n\n/** Removes ledgers whose project directory is gone and that nothing wrote for the retention window. */\nexport const sweepLedgers = (\n rootDir: string,\n options: { keepKey: string; now?: number; retentionMs?: number; force?: boolean },\n): LcmSweepResult => {\n const now = options.now ?? Date.now();\n const retentionMs = options.retentionMs ?? RETENTION_MS;\n const file = read(rootDir);\n if (!options.force && now - file.sweptAt < SWEEP_INTERVAL_MS) return { removed: [], bytes: 0, skipped: true };\n const removed: string[] = [];\n let bytes = 0;\n const kept: LcmDirectoryRecord[] = [];\n for (const record of file.projects) {\n const ledger = defaultLedgerPath(rootDir, record.key);\n let stats: fs.Stats | undefined;\n try {\n stats = fs.statSync(ledger);\n } catch {\n continue;\n }\n const abandoned =\n record.key !== options.keepKey &&\n !fs.existsSync(record.path) &&\n now - Math.max(stats.mtimeMs, record.updatedAt) >= retentionMs;\n if (!abandoned) {\n kept.push(record);\n continue;\n }\n try {\n for (const target of ledgerFiles(record.key, rootDir)) fs.rmSync(target, { force: true });\n } catch {\n kept.push(record);\n continue;\n }\n bytes += stats.size;\n removed.push(record.path);\n }\n write(rootDir, { ...file, sweptAt: now, projects: kept }, file.projects.map((record) => record.path));\n return { removed, bytes, skipped: false };\n};\n", "import crypto from \"node:crypto\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { sqliteDriver, type SqliteDatabase } from \"./sqlite.js\";\nimport { sessionsDirRoot, sessionDirNamesForCwd } from \"../memory/discovery.js\";\nimport { canonicalLcmPayload, canonicalProjectIdentity, defaultLedgerPath, hashLcmPayload, LcmLedger } from \"./lcm-ledger.js\";\n\nexport interface MigrationOptions {\n agentDir: string;\n ledgerRoot?: string;\n ledger?: LcmLedger;\n files?: string[];\n candidateDirs?: string[];\n projectCwd?: string;\n liveCwd?: string;\n since?: string;\n until?: string;\n onDemand?: boolean;\n now?: number;\n apply?: boolean;\n allowIncompleteDiscovery?: boolean;\n maxFiles?: number;\n maxDiscoveryEntries?: number;\n maxFileBytes?: number;\n maxLineBytes?: number;\n maxTotalBytes?: number;\n onProgress?: (progress: MigrationProgress) => void;\n}\ninterface MigrationProgress {\n projectKey: string;\n sessionPath: string;\n sourceHash: string;\n lineOrdinal: number;\n entryId: string;\n contentHash: string;\n}\ninterface MigrationCounts {\n eligible: number;\n imported: number;\n skippedDuplicate: number;\n skippedOutOfWindow: number;\n malformed: number;\n oversized: number;\n absent: number;\n incompleteDiscovery: number;\n raced: number;\n errors: number;\n}\nexport interface MigrationDrops {\n oversizedFiles: number;\n oversizedFileBytes: number;\n oversizedLines: number;\n oversizedLineBytes: number;\n skippedFiles: number;\n entries: number;\n}\nconst plural = (count: number, noun: string): string => `${count} ${noun}${count === 1 ? \"\" : \"s\"}`;\nconst megabytes = (bytes: number): string => `${(bytes / 1024 ** 2).toFixed(1)} MB`;\n/** One sentence per non-empty drop category; empty when nothing was dropped. */\nexport const migrationDropReasons = (drops: MigrationDrops): string[] => {\n const reasons: string[] = [];\n if (drops.oversizedFiles > 0) reasons.push(`${plural(drops.oversizedFiles, \"session file\")} skipped as oversized (${megabytes(drops.oversizedFileBytes)})`);\n if (drops.oversizedLines > 0) reasons.push(`${plural(drops.oversizedLines, \"line\")} skipped as oversized (${megabytes(drops.oversizedLineBytes)})`);\n if (drops.skippedFiles > 0) reasons.push(`${plural(drops.skippedFiles, \"session file\")} skipped after the total scan budget`);\n return reasons;\n};\nexport interface MigrationResult {\n mode: \"apply\" | \"dry-run\";\n since: string;\n until: string;\n counts: MigrationCounts;\n drops: MigrationDrops;\n degraded: boolean;\n filesScanned: number;\n bytesScanned: number;\n generations: Array<{ sessionPath: string; sourceHash: string }>;\n exitCode: number;\n}\nconst hash = (data: string | Buffer): string => crypto.createHash(\"sha256\").update(data).digest(\"hex\");\nconst record = (value: unknown): Record<string, unknown> | undefined =>\n value !== null && typeof value === \"object\" && !Array.isArray(value) ? value as Record<string, unknown> : undefined;\nconst nonblank = (value: unknown): value is string => typeof value === \"string\" && value.trim().length > 0;\n/** Session JSONL is append-only, so a longer file is the live session growing. */\nexport const sourceStillValid = (before: number, after: number): boolean => after >= before;\nconst SOURCE_READ_ATTEMPTS = 3;\nclass SourceChangedError extends Error {}\ntype SourceRead =\n | { kind: \"data\"; raced: number; data: Buffer }\n | { kind: \"absent\"; raced: number }\n | { kind: \"not-file\"; raced: number }\n | { kind: \"oversized\"; raced: number; size: number }\n | { kind: \"over-budget\"; raced: number }\n | { kind: \"raced\"; raced: number }\n | { kind: \"error\"; raced: number };\nconst readSource = (file: string, maxFileBytes: number, remainingBytes: number): SourceRead => {\n let raced = 0;\n for (let attempt = 0; attempt < SOURCE_READ_ATTEMPTS; attempt += 1) {\n let fd: number | undefined;\n try {\n fd = fs.openSync(file, \"r\");\n const before = fs.fstatSync(fd);\n if (!before.isFile()) return { kind: \"not-file\", raced };\n if (before.size > maxFileBytes) return { kind: \"oversized\", raced, size: before.size };\n if (before.size > remainingBytes) return { kind: \"over-budget\", raced };\n const data = Buffer.allocUnsafe(before.size);\n let offset = 0;\n while (offset < data.length) {\n const size = fs.readSync(fd, data, offset, data.length - offset, offset);\n if (size === 0) throw new SourceChangedError(\"source shortened during read\");\n offset += size;\n }\n if (!sourceStillValid(before.size, fs.fstatSync(fd).size)) throw new SourceChangedError(\"source shrank during read\");\n return { kind: \"data\", raced, data };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return { kind: \"absent\", raced };\n if (!(error instanceof SourceChangedError)) return { kind: \"error\", raced };\n raced += 1;\n } finally { if (fd !== undefined) fs.closeSync(fd); }\n }\n return { kind: \"raced\", raced };\n};\nconst utc = (value: string): number => {\n if (!/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{1,3})?(?:Z|\\+00:00)$/.test(value)) throw new Error(\"timestamps must be explicit UTC ISO-8601 values\");\n const at = Date.parse(value);\n const normalized = value.replace(\"+00:00\", \"Z\").replace(/Z$/, \"\");\n if (!Number.isFinite(at) || new Date(at).toISOString().slice(0, 19) !== normalized.slice(0, 19)) throw new Error(\"invalid UTC timestamp\");\n return at;\n};\nexport function migrationWindow(options: Pick<MigrationOptions, \"since\" | \"until\" | \"now\">): { since: number; until: number } {\n const now = options.now ?? Date.now();\n const since = options.since === undefined ? now - 72 * 60 * 60 * 1000 : utc(options.since);\n const until = options.until === undefined ? now : utc(options.until);\n if (!Number.isFinite(since) || !Number.isFinite(until) || since > until) throw new Error(\"invalid migration window\");\n return { since, until };\n}\nconst positive = (value: number | undefined, fallback: number): number => {\n const result = value ?? fallback;\n if (!Number.isSafeInteger(result) || result < 1) throw new Error(\"scan limits must be positive safe integers\");\n return result;\n};\nexport function discoverMigrationSessions(options: MigrationOptions): { files: string[]; incomplete: number } {\n const maxFiles = positive(options.maxFiles, 10_000);\n const maxEntries = positive(options.maxDiscoveryEntries, 100_000);\n const files = new Set<string>();\n let incomplete = 0;\n let entries = 0;\n const add = (file: string): void => {\n if (files.size >= maxFiles && !files.has(path.resolve(file))) { incomplete++; return; }\n files.add(path.resolve(file));\n };\n if (options.files) {\n for (const file of options.files.slice(0, maxFiles)) add(file);\n if (options.files.length > maxFiles) incomplete++;\n return { files: [...files].sort(), incomplete };\n }\n const list = (dir: string, visit: (entry: fs.Dirent) => void): void => {\n let handle: fs.Dir | undefined;\n try {\n handle = fs.opendirSync(dir);\n let entry: fs.Dirent | null;\n while ((entry = handle.readSync()) !== null) {\n if (++entries > maxEntries) { incomplete++; break; }\n visit(entry);\n }\n } catch { incomplete++; } finally { handle?.closeSync(); }\n };\n const scan = (dir: string): void => list(dir, entry => {\n if (entry.isFile() && entry.name.endsWith(\".jsonl\")) add(path.join(dir, entry.name));\n else if (entry.isSymbolicLink() && entry.name.endsWith(\".jsonl\")) incomplete++;\n });\n if (options.candidateDirs) {\n for (const dir of options.candidateDirs) { if (entries >= maxEntries) { incomplete++; break; } scan(dir); }\n } else if (options.projectCwd) {\n const names = sessionDirNamesForCwd(options.projectCwd);\n let found = false;\n for (const name of [names.canonical, ...names.legacy]) {\n const dir = path.join(sessionsDirRoot(options.agentDir), name);\n try { if (fs.statSync(dir).isDirectory()) { found = true; scan(dir); } }\n catch (error) { if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") incomplete++; }\n }\n if (!found) incomplete++;\n } else {\n const root = sessionsDirRoot(options.agentDir);\n list(root, entry => {\n if (entry.isDirectory()) scan(path.join(root, entry.name));\n else if (entry.isFile() && entry.name.endsWith(\".jsonl\")) add(path.join(root, entry.name));\n else if (entry.isSymbolicLink()) incomplete++;\n });\n }\n return { files: [...files].sort(), incomplete };\n}\nconst CHECKPOINT_SCHEMA = \"CREATE TABLE IF NOT EXISTS migration_checkpoints (project_key TEXT NOT NULL, session_path TEXT NOT NULL, source_hash TEXT NOT NULL, line_ordinal INTEGER NOT NULL, entry_id TEXT NOT NULL, content_hash TEXT NOT NULL, PRIMARY KEY(project_key,session_path,source_hash,line_ordinal,entry_id,content_hash))\";\nexport function reconcileSession(options: Omit<MigrationOptions, \"files\"> & { files: [string] }): MigrationResult {\n return migrateSessions({ ...options, onDemand: true });\n}\n\nexport function migrateSessions(options: MigrationOptions): MigrationResult {\n const window = migrationWindow(options);\n const maxFileBytes = positive(options.maxFileBytes, 64 * 1024 ** 2);\n const maxLineBytes = positive(options.maxLineBytes, 8 * 1024 ** 2);\n const maxTotalBytes = positive(options.maxTotalBytes, 1024 ** 3);\n const discovery = discoverMigrationSessions(options);\n const result: MigrationResult = {\n mode: options.apply ? \"apply\" : \"dry-run\", since: new Date(window.since).toISOString(), until: new Date(window.until).toISOString(),\n counts: { eligible: 0, imported: 0, skippedDuplicate: 0, skippedOutOfWindow: 0, malformed: 0, oversized: 0, absent: 0, incompleteDiscovery: discovery.incomplete, raced: 0, errors: 0 },\n drops: { oversizedFiles: 0, oversizedFileBytes: 0, oversizedLines: 0, oversizedLineBytes: 0, skippedFiles: 0, entries: 0 },\n degraded: false,\n filesScanned: 0, bytesScanned: 0, generations: [], exitCode: 0,\n };\n const counts = result.counts;\n const drops = result.drops;\n const drySeen = new Set<string>();\n files: for (const [position, file] of discovery.files.entries()) {\n const read = readSource(file, maxFileBytes, maxTotalBytes - result.bytesScanned);\n counts.raced += read.raced;\n if (read.kind !== \"data\") {\n switch (read.kind) {\n case \"absent\": counts.absent++; counts.incompleteDiscovery++; break;\n case \"not-file\": counts.incompleteDiscovery++; break;\n case \"oversized\": counts.oversized++; drops.oversizedFiles++; drops.oversizedFileBytes += read.size; break;\n case \"over-budget\": counts.incompleteDiscovery++; drops.skippedFiles += discovery.files.length - position; break files;\n case \"raced\": counts.incompleteDiscovery++; break;\n default: counts.errors++; counts.incompleteDiscovery++;\n }\n continue;\n }\n const data = read.data;\n result.filesScanned++;\n result.bytesScanned += data.length;\n const sourceHash = hash(data);\n result.generations.push({ sessionPath: file, sourceHash });\n let header: Record<string, unknown> | undefined;\n let ledger: LcmLedger | undefined;\n let database: SqliteDatabase | undefined;\n let sessionId = \"\";\n let projectKey = \"\";\n let cwd: string | undefined;\n let ordinal = 0;\n try {\n for (let start = 0; start < data.length;) {\n ordinal++;\n const newline = data.indexOf(10, start);\n const end = newline < 0 ? data.length : newline;\n const bytes = data.subarray(start, end);\n start = newline < 0 ? data.length : end + 1;\n if (bytes.length > maxLineBytes) { counts.oversized++; drops.oversizedLines++; drops.oversizedLineBytes += bytes.length; drops.entries++; continue; }\n const content = bytes.toString(\"utf8\").replace(/\\r$/, \"\");\n if (!content.trim()) continue;\n let row: Record<string, unknown> | undefined;\n try { row = record(JSON.parse(content)); } catch { counts.malformed++; continue; }\n if (!row) { counts.malformed++; continue; }\n if (row.type === \"message_end\") continue;\n if (!header) {\n if (row.type !== \"session\") { if (record(row.message)) counts.malformed++; continue; }\n if (!nonblank(row.id)) { counts.malformed++; break; }\n header = row;\n sessionId = row.id;\n cwd = nonblank(row.cwd) ? row.cwd : options.liveCwd;\n if (!cwd) { counts.malformed++; break; }\n const projectInput = options.liveCwd ? { recordedCwd: cwd, liveCwd: options.liveCwd } : { recordedCwd: cwd };\n projectKey = canonicalProjectIdentity(projectInput).key;\n if (options.ledger && options.ledger.project.key !== projectKey) { counts.errors++; break; }\n if (options.apply) {\n if (options.ledger) ledger = options.ledger;\n else if (options.ledgerRoot) ledger = new LcmLedger({ rootDir: options.ledgerRoot, project: { recordedCwd: cwd } });\n else ledger = new LcmLedger({ project: { recordedCwd: cwd } });\n database = ledger.db;\n database.exec(CHECKPOINT_SCHEMA);\n } else if (options.ledger) database = options.ledger.db;\n else {\n const dbPath = defaultLedgerPath(options.ledgerRoot, projectKey);\n if (fs.existsSync(dbPath)) database = new (sqliteDriver())(dbPath, { readOnly: true });\n }\n continue;\n }\n if (row.type === \"session\" || !nonblank(row.type) || !nonblank(row.id) || (row.parentId !== null && row.parentId !== undefined && typeof row.parentId !== \"string\")) { counts.malformed++; continue; }\n const message = record(row.message);\n if (row.type === \"message\" && (!message || !nonblank(message.role))) { counts.malformed++; continue; }\n let at: number;\n try { at = typeof row.timestamp === \"string\" ? utc(row.timestamp) : NaN; } catch { at = NaN; }\n if (!Number.isFinite(at)) { counts.malformed++; continue; }\n if (!options.onDemand && (at < window.since || at > window.until)) { counts.skippedOutOfWindow++; continue; }\n counts.eligible++;\n const payloadJson = canonicalLcmPayload(row);\n const contentHash = hashLcmPayload(row);\n const identity = JSON.stringify([projectKey, sessionId, row.id, contentHash]);\n const progress: MigrationProgress = { projectKey, sessionPath: file, sourceHash, lineOrdinal: ordinal, entryId: row.id, contentHash };\n const duplicate = drySeen.has(identity) || database?.prepare(\"SELECT 1 FROM raw_entries WHERE project_key=? AND session_id=? AND entry_id=? AND content_hash=?\").get(projectKey, sessionId, row.id, contentHash) !== undefined;\n if (duplicate) counts.skippedDuplicate++;\n else if (ledger) {\n ledger.appendRaw({\n projectKey, sessionId, entryId: row.id, role: message && typeof message.role === \"string\" ? message.role : row.type,\n content, payloadJson, parentEntryId: typeof row.parentId === \"string\" ? row.parentId : null,\n branch: typeof row.branch === \"string\" ? row.branch : typeof row.branchId === \"string\" ? row.branchId : null,\n ...(cwd ? { recordedCwd: cwd } : {}), createdAt: at\n });\n counts.imported++;\n }\n else if (!duplicate) counts.imported++;\n drySeen.add(identity);\n if (ledger) database!.prepare(\"INSERT OR IGNORE INTO migration_checkpoints(project_key,session_path,source_hash,line_ordinal,entry_id,content_hash) VALUES(?,?,?,?,?,?)\")\n .run(projectKey, file, sourceHash, ordinal, row.id, contentHash);\n options.onProgress?.(progress);\n }\n if (!header) counts.malformed++;\n } catch (error) {\n counts.errors++;\n if (options.onProgress) throw error;\n } finally {\n if (ledger && ledger !== options.ledger) ledger.close();\n else if (!ledger && database && database !== options.ledger?.db) database.close();\n }\n }\n result.degraded = drops.entries > 0 || drops.oversizedFiles > 0 || drops.skippedFiles > 0;\n result.exitCode = counts.errors || counts.malformed || counts.oversized || (counts.incompleteDiscovery && !options.allowIncompleteDiscovery) ? 1 : 0;\n return result;\n}\n", "import crypto from \"node:crypto\";\nimport { hashLcmPayload, type RawEntry } from \"../storage/lcm-identity.js\";\nimport type { LcmLedger } from \"../storage/lcm-ledger.js\";\nimport type { SqliteDatabase } from \"../storage/sqlite.js\";\nimport { utf8Bytes } from \"./bounds.js\";\nimport { buildLcmPrompt, emergencyReduce, type LcmModelResult, type LcmPromptMode, type LcmSummarizer } from \"./lcm-model.js\";\n\ntype LcmNodeState = \"pending\" | \"ready\" | \"running\" | \"failed\";\ntype LcmJobState = \"pending\" | \"running\" | \"completed\" | \"failed\";\nexport interface LcmSourceRef { sessionId: string; entryId: string; revision: number; payloadHash: string; }\ntype RawSourceRef = LcmSourceRef;\nexport interface LcmNode { nodeId: string; projectKey: string; sessionId: string; kind: \"leaf\" | \"condensed\"; sources: LcmSourceRef[]; children: string[]; depth: number; sourceHash: string; policyHash: string; modelHash: string; state: LcmNodeState; text?: string; createdAt: number; }\nexport interface LcmJob { jobId: string; projectKey: string; nodeId: string; priority: number; eligibleAt: number; state: LcmJobState; ownerId?: string; leaseToken?: string; leaseUntil?: number; attempts: number; nextRetryAt: number; error?: string; legacyRecovery?: true; createdAt: number; updatedAt: number; }\nexport interface LcmBudget { calls: number; inputTokens: number; outputTokens: number; cost: number; wallMs: number; }\nexport interface LcmBudgetPolicy extends LcmBudget { sessionCalls: number; }\nconst DEFAULT_LCM_BUDGET: LcmBudgetPolicy = { calls: Number.POSITIVE_INFINITY, inputTokens: Number.POSITIVE_INFINITY, outputTokens: Number.POSITIVE_INFINITY, cost: Number.POSITIVE_INFINITY, wallMs: Number.POSITIVE_INFINITY, sessionCalls: Number.POSITIVE_INFINITY };\nexport interface LcmMaintenanceOptions { now?: () => number; ownerId?: string; policyHash?: string; maxLeafEntries?: number; maxCondenseChildren?: number; maxInputChars?: number; maxOutputChars?: number; modelTimeoutMs?: number; budget?: Partial<LcmBudgetPolicy>; maxConcurrentJobs?: number | (() => number); }\nexport const DEFAULT_LEAF_ENTRIES = 32;\nexport const DEFAULT_MAINTENANCE_CONCURRENCY = 3;\nexport const LEASE_MS = 30_000;\nexport const LEASE_SWEEP_GRACE_MS = 60_000;\nexport type LcmRejectionReason = \"job lease held\" | \"project lease held\" | \"job not eligible\" | \"budget exhausted\" | \"lease fenced\";\nexport class LcmRejection extends Error {\n readonly reason: LcmRejectionReason;\n constructor(reason: LcmRejectionReason) { super(reason); this.name = \"LcmRejection\"; this.reason = reason; }\n}\nexport const isLcmRejection = (error: unknown): error is LcmRejection => error instanceof LcmRejection;\nexport const isLcmCapacityRejection = (error: unknown): boolean => isLcmRejection(error) && (error.reason === \"project lease held\" || error.reason === \"budget exhausted\");\nconst LEGACY_CONTENTION_RETIREMENTS: ReadonlySet<string> = new Set([\"job lease held\", \"project lease held\", \"LcmRejection: job lease held\", \"LcmRejection: project lease held\"]);\nconst hash = (v: unknown) => hashLcmPayload(v);\nconst parse = <T>(v: unknown): T => JSON.parse(String(v));\nconst rawHash = (e: RawEntry) => e.payloadHash;\nconst token = () => crypto.randomUUID();\nconst LCM_MODEL_LEVELS: ReadonlyArray<{ mode: LcmPromptMode; share: number }> = [{ mode: \"detail\", share: 1 }, { mode: \"bullets\", share: 0.5 }];\nconst CLAIMABLE_JOBS_SQL = `SELECT j.payload FROM maintenance_jobs j\nJOIN summary_nodes n ON n.node_id=json_extract(j.payload,'$.nodeId') AND n.project_key=j.project_key\nWHERE j.project_key=?\nAND (j.status='pending' OR (j.status='running' AND CAST(coalesce(json_extract(j.payload,'$.leaseUntil'),0) AS INTEGER)<=?))\nAND CAST(json_extract(j.payload,'$.eligibleAt') AS INTEGER)<=?\nAND CAST(json_extract(j.payload,'$.nextRetryAt') AS INTEGER)<=?\nAND (? IS NULL OR json_extract(n.payload,'$.sessionId')=?)\nORDER BY CAST(json_extract(j.payload,'$.priority') AS INTEGER) DESC, j.created_at, j.job_id\nLIMIT ?`;\nconst LIVE_LEASES_SQL = `SELECT coalesce(json_extract(n.payload,'$.sessionId'),'') sessionId\nFROM maintenance_jobs j\nLEFT JOIN summary_nodes n ON n.node_id=json_extract(j.payload,'$.nodeId') AND n.project_key=j.project_key\nWHERE j.project_key=? AND j.status='running' AND j.job_id<>? AND CAST(coalesce(json_extract(j.payload,'$.leaseUntil'),0) AS INTEGER)>?`;\n\nexport class LcmMaintenance {\n readonly projectKey: string;\n private readonly now: () => number;\n private readonly ownerId: string;\n private readonly policyHash: string;\n private readonly maxLeaf: number;\n private readonly maxChildren: number;\n private readonly maxInputChars: number;\n private readonly maxOutputChars: number;\n private readonly budget: LcmBudgetPolicy;\n private readonly modelTimeoutMs: number;\n private readonly maxConcurrentJobs: number | (() => number);\n constructor(private readonly ledger: LcmLedger, options: LcmMaintenanceOptions = {}) { this.maxConcurrentJobs = options.maxConcurrentJobs ?? DEFAULT_MAINTENANCE_CONCURRENCY; this.projectKey = ledger.project.key; this.now = options.now ?? Date.now; this.ownerId = options.ownerId ?? crypto.randomUUID(); this.policyHash = options.policyHash ?? hash(\"lcm-policy-v1\"); this.maxLeaf = options.maxLeafEntries ?? DEFAULT_LEAF_ENTRIES; this.maxChildren = options.maxCondenseChildren ?? 4; this.maxInputChars = options.maxInputChars ?? 200_000; this.maxOutputChars = options.maxOutputChars ?? 4_096; this.modelTimeoutMs = options.modelTimeoutMs ?? 120_000; this.budget = { ...DEFAULT_LCM_BUDGET, ...options.budget }; }\n budgetPolicy(): LcmBudgetPolicy { return { ...this.budget }; }\n get concurrencyLimit(): number { const raw = typeof this.maxConcurrentJobs === \"function\" ? this.maxConcurrentJobs() : this.maxConcurrentJobs; return Number.isFinite(raw) ? Math.max(1, Math.floor(raw)) : DEFAULT_MAINTENANCE_CONCURRENCY; }\n private liveLeases(db: SqliteDatabase, at: number, excludeJobId?: string): Array<{ sessionId: string }> { return db.prepare(LIVE_LEASES_SQL).all(this.projectKey, excludeJobId ?? \"\", at - LEASE_SWEEP_GRACE_MS) as Array<{ sessionId: string }>; }\n private admits(db: SqliteDatabase, at: number, sessionId: string, leases: ReadonlyArray<{ sessionId: string }>): boolean {\n const day = this.day(at);\n const project = this.usage(db, day);\n const session = this.usage(db, day, sessionId);\n let sessionReserved = 0;\n for (const lease of leases) if (lease.sessionId === sessionId) sessionReserved += 1;\n const reserved = leases.length + 1;\n const fits = (used: number, cap: number): boolean => used < cap && used + (project.calls > 0 ? (used / project.calls) * reserved : 0) <= cap;\n return project.calls + leases.length < this.budget.calls\n && fits(project.inputTokens, this.budget.inputTokens)\n && fits(project.outputTokens, this.budget.outputTokens)\n && fits(project.cost, this.budget.cost)\n && fits(project.wallMs, this.budget.wallMs)\n && session.calls + sessionReserved < this.budget.sessionCalls;\n }\n private recordRevision(db: SqliteDatabase, node: LcmNode): void {\n if (!node.text) return;\n const row = db.prepare(\"SELECT coalesce(max(revision),0) n FROM summary_node_revisions WHERE node_id=?\").get(node.nodeId) as { n: number };\n db.prepare(\"INSERT OR IGNORE INTO summary_node_revisions(node_id,revision,project_key,text,model_hash,created_at) VALUES(?,?,?,?,?,?)\")\n .run(node.nodeId, Number(row.n) + 1, this.projectKey, node.text, node.modelHash, this.now());\n }\n revisionsOf(nodeId: string): Array<{ revision: number; text: string; modelHash: string; createdAt: number }> {\n return this.ledger.readOnly(db => (db.prepare(\"SELECT revision, text, model_hash, created_at FROM summary_node_revisions WHERE node_id=? AND project_key=? ORDER BY revision\").all(nodeId, this.projectKey) as Array<{ revision: number; text: string; model_hash: string; created_at: number }>)\n .map(row => ({ revision: Number(row.revision), text: row.text, modelHash: row.model_hash, createdAt: Number(row.created_at) })));\n }\n selectUpgrades(sessionId?: string, activeSources?: ReadonlySet<string>, limit = 1): LcmNode[] {\n return this.listNodes(100000)\n .filter(node => node.state === \"ready\" && node.modelHash === \"emergency\" && node.policyHash === this.policyHash\n && (!sessionId || node.sessionId === sessionId)\n && (!activeSources || node.sources.every(source => activeSources.has(this.sourceKey(source)))))\n .sort((left, right) => left.depth - right.depth || left.nodeId.localeCompare(right.nodeId))\n .slice(0, limit);\n }\n ancestorsOf(nodeId: string): string[] {\n return this.ledger.readOnly(db => {\n const seen = new Set<string>();\n const stack = [nodeId];\n const order: string[] = [];\n while (stack.length > 0) {\n const current = stack.pop()!;\n const parents = db.prepare(\"SELECT e.parent_id FROM summary_edges e JOIN summary_nodes parent ON parent.node_id=e.parent_id WHERE e.child_id=? AND parent.project_key=?\").all(current, this.projectKey) as Array<{ parent_id: string }>;\n for (const { parent_id: parent } of parents) {\n if (seen.has(parent)) continue;\n seen.add(parent);\n order.push(parent);\n stack.push(parent);\n }\n }\n return order;\n });\n }\n reopen(nodeId: string, force = false): LcmJob {\n return this.ledger.transaction(db => {\n const row = db.prepare(\"SELECT payload FROM summary_nodes WHERE node_id=? AND project_key=?\").get(nodeId, this.projectKey) as { payload?: string } | undefined;\n if (!row?.payload) throw new Error(\"node not found\");\n const node = parse<LcmNode>(row.payload);\n if (node.projectKey !== this.projectKey) throw new Error(\"node project does not match ledger project\");\n if (!force && node.modelHash !== \"emergency\") throw new Error(\"node already carries a model summary\");\n const t = this.now();\n const job: LcmJob = { ...this.job(node), jobId: `job:upgrade:${token()}:${node.nodeId}`, createdAt: t, updatedAt: t };\n db.prepare(\"INSERT INTO maintenance_jobs(job_id,project_key,status,payload,created_at,updated_at) VALUES(?,?,?,?,?,?)\")\n .run(job.jobId, this.projectKey, job.state, JSON.stringify(job), job.createdAt, job.updatedAt);\n return job;\n });\n }\n listNodes(limit = 100, offset = 0): LcmNode[] { return this.ledger.readOnly(db => (db.prepare(\"SELECT payload FROM summary_nodes WHERE project_key=? ORDER BY created_at,node_id LIMIT ? OFFSET ?\").all(this.projectKey, limit, offset) as Array<{payload:string}>).map(r => { const node = parse<LcmNode>(r.payload); if (node.projectKey !== this.projectKey) throw new Error(\"node project does not match ledger project\"); return node; })); }\n getNode(nodeId: string): LcmNode | undefined { return this.ledger.readOnly(db => { const row = db.prepare(\"SELECT payload FROM summary_nodes WHERE node_id=? AND project_key=?\").get(nodeId, this.projectKey) as {payload?:string}|undefined; if (!row?.payload) return undefined; const node = parse<LcmNode>(row.payload); if (node.projectKey !== this.projectKey) throw new Error(\"node project does not match ledger project\"); return node; }); }\n /** Scoped by the live source set when given; drops a condensed child and a contained node. */\n getFrontier(sessionId?: string, activeSources?: ReadonlySet<string>): LcmNode[] { const nodes=this.listNodes(100000).filter(n => n.state === \"ready\" && n.policyHash === this.policyHash && (!sessionId || activeSources !== undefined || n.sessionId === sessionId) && (!activeSources || n.sources.every(s => activeSources.has(this.sourceKey(s))))); const condensed=new Set(nodes.flatMap(n=>n.children)); const standing=nodes.filter(n=>!condensed.has(n.nodeId)); const ranked=[...standing].sort((a,b)=>b.sources.length-a.sources.length||a.nodeId.localeCompare(b.nodeId)); const kept: LcmNode[]=[]; const shadowed=new Set<string>(); for (const node of ranked) { const keys=node.sources.map(s=>this.sourceKey(s)); if (kept.some(other=>{ const held=new Set(other.sources.map(s=>this.sourceKey(s))); return keys.every(key=>held.has(key)); })) { shadowed.add(node.nodeId); continue; } kept.push(node); } return standing.filter(n=>!shadowed.has(n.nodeId)); }\n recentJobs(limit = 200): LcmJob[] { return this.ledger.readOnly(db => (db.prepare(\"SELECT payload FROM maintenance_jobs WHERE project_key=? ORDER BY CASE status WHEN 'failed' THEN 0 WHEN 'running' THEN 1 WHEN 'pending' THEN 2 ELSE 3 END, updated_at DESC LIMIT ?\").all(this.projectKey, limit) as Array<{payload:string}>).map(r => { const job = parse<LcmJob>(r.payload); if (job.projectKey !== this.projectKey) throw new Error(\"job project does not match ledger project\"); return job; })); }\n listJobs(limit = 100): LcmJob[] { return this.ledger.readOnly(db => (db.prepare(\"SELECT payload FROM maintenance_jobs WHERE project_key=? ORDER BY created_at,job_id LIMIT ?\").all(this.projectKey, limit) as Array<{payload:string}>).map(r => { const job = parse<LcmJob>(r.payload); if (job.projectKey !== this.projectKey) throw new Error(\"job project does not match ledger project\"); return job; })); }\n jobForNode(nodeId: string): LcmJob | undefined { return this.ledger.readOnly(db => { const row = db.prepare(\"SELECT payload FROM maintenance_jobs WHERE job_id=? AND project_key=?\").get(`job:${nodeId}`, this.projectKey) as {payload?:string}|undefined; if (!row?.payload) return undefined; const job = parse<LcmJob>(row.payload); if (job.projectKey !== this.projectKey) throw new Error(\"job project does not match ledger project\"); return job; }); }\n claimableJobs(sessionId?: string, limit = 64): LcmJob[] { const t = this.now(); const scope = sessionId ?? null; return this.ledger.readOnly(db => (db.prepare(CLAIMABLE_JOBS_SQL).all(this.projectKey, t - LEASE_SWEEP_GRACE_MS, t, t, scope, scope, limit) as Array<{payload:string}>).map(r => { const job = parse<LcmJob>(r.payload); if (job.projectKey !== this.projectKey) throw new Error(\"job project does not match ledger project\"); return job; })); }\n countJobs(state: LcmJobState, updatedSince = 0): number { return this.ledger.readOnly(db => Number((db.prepare(\"SELECT count(*) n FROM maintenance_jobs WHERE project_key=? AND status=? AND updated_at>=?\").get(this.projectKey, state, updatedSince) as {n:number}).n)); }\n isClaimable(job: LcmJob): boolean { const t = this.now(); return (job.state === \"pending\" || (job.state === \"running\" && (job.leaseUntil ?? 0) + LEASE_SWEEP_GRACE_MS <= t)) && job.eligibleAt <= t && job.nextRetryAt <= t; }\n sweepExpiredLeases(): LcmJob[] { return this.ledger.transaction(db => { const t = this.now() - LEASE_SWEEP_GRACE_MS; const rows = db.prepare(\"SELECT payload FROM maintenance_jobs WHERE project_key=? AND status=?\").all(this.projectKey, \"running\") as Array<{payload:string}>; const swept: LcmJob[] = []; for (const row of rows) { const old = parse<LcmJob>(row.payload); if (old.projectKey !== this.projectKey) throw new Error(\"job project does not match ledger project\"); if ((old.leaseUntil ?? 0) > t) continue; const now = this.now(); const { ownerId: _ownerId, leaseToken: _leaseToken, leaseUntil: _leaseUntil, ...base } = old; const job: LcmJob = { ...base, state: \"pending\", error: \"lease expired\", eligibleAt: now, nextRetryAt: now, updatedAt: now }; db.prepare(\"UPDATE maintenance_jobs SET status=?,payload=?,updated_at=? WHERE job_id=? AND project_key=?\").run(job.state, JSON.stringify(job), job.updatedAt, job.jobId, this.projectKey); swept.push(job); } return swept; }); }\n expiredLeases(): number { const t = this.now() - LEASE_SWEEP_GRACE_MS; return this.ledger.readOnly(db => Number((db.prepare(\"SELECT count(*) n FROM maintenance_jobs WHERE project_key=? AND status=? AND coalesce(json_extract(payload,'$.leaseUntil'),0)<=?\").get(this.projectKey, \"running\", t) as {n:number}).n)); }\n retryFailedJobs(): LcmJob[] { return this.ledger.transaction(db => { const rows = db.prepare(\"SELECT payload FROM maintenance_jobs WHERE project_key=? AND status=?\").all(this.projectKey, \"failed\") as Array<{payload:string}>; const retried: LcmJob[] = []; for (const row of rows) { const old = parse<LcmJob>(row.payload); if (old.projectKey !== this.projectKey) throw new Error(\"job project does not match ledger project\"); const t = this.now(); const { error: _error, ownerId: _ownerId, leaseToken: _leaseToken, leaseUntil: _leaseUntil, ...base } = old; const job: LcmJob = { ...base, state: \"pending\", attempts: 0, eligibleAt: t, nextRetryAt: t, updatedAt: t }; db.prepare(\"UPDATE maintenance_jobs SET status=?,payload=?,updated_at=? WHERE job_id=? AND project_key=?\").run(job.state, JSON.stringify(job), job.updatedAt, job.jobId, this.projectKey); retried.push(job); } return retried; }); }\n recoverLegacyContentionRetirements(): LcmJob[] { return this.ledger.transaction(db => { const rows = db.prepare(\"SELECT payload FROM maintenance_jobs WHERE project_key=? AND status=?\").all(this.projectKey, \"failed\") as Array<{payload:string}>; const recovered: LcmJob[] = []; for (const row of rows) { const old = parse<LcmJob>(row.payload); if (old.projectKey !== this.projectKey) throw new Error(\"job project does not match ledger project\"); if (old.legacyRecovery || !LEGACY_CONTENTION_RETIREMENTS.has(old.error ?? \"\")) continue; const t = this.now(); const { error: _error, ...base } = old; const job: LcmJob = { ...base, state: \"pending\", attempts: 0, legacyRecovery: true, eligibleAt: t, nextRetryAt: t, updatedAt: t }; db.prepare(\"UPDATE maintenance_jobs SET status=?,payload=?,updated_at=? WHERE job_id=? AND project_key=?\").run(job.state, JSON.stringify(job), job.updatedAt, job.jobId, this.projectKey); recovered.push(job); } return recovered; }); }\n recordFailure(job: LcmJob, error: unknown): LcmJob | undefined { return this.ledger.transaction(db => { const row = db.prepare(\"SELECT payload FROM maintenance_jobs WHERE job_id=? AND project_key=?\").get(job.jobId, this.projectKey) as {payload?:string}|undefined; if (!row?.payload) return undefined; const old = parse<LcmJob>(row.payload); if (old.projectKey !== this.projectKey) throw new Error(\"job project does not match ledger project\"); const t = this.now(); if (old.state === \"completed\" || old.attempts !== job.attempts) return old; if (old.state === \"running\" && (old.leaseUntil ?? 0) > t && old.leaseToken !== job.leaseToken) return old; const attempts = old.attempts + 1; const delay = Math.min(900_000, 30_000 * 2 ** (attempts - 1)); const { ownerId: _ownerId, leaseToken: _leaseToken, leaseUntil: _leaseUntil, ...base } = old; const next: LcmJob = { ...base, attempts, error: String(error), state: attempts >= 3 ? \"failed\" : \"pending\", eligibleAt: t + delay, nextRetryAt: t + delay, updatedAt: t }; db.prepare(\"UPDATE maintenance_jobs SET status=?,payload=?,updated_at=? WHERE job_id=? AND project_key=?\").run(next.state, JSON.stringify(next), next.updatedAt, next.jobId, this.projectKey); return next; }); }\n selectLeaf(entries = this.ledger.readRaw(this.projectKey), activeSources?: ReadonlySet<string>): RawEntry[] { const first = entries[0]; if (!first) return []; const nodes = this.listNodes(100000).filter(n => n.state !== \"failed\" && n.policyHash === this.policyHash && (n.sessionId === first.sessionId || (activeSources !== undefined && n.state === \"ready\")) && (!activeSources || n.sources.every(s => activeSources.has(this.sourceKey(s))))); const covered = new Set(nodes.flatMap(n => n.sources.map(s => this.sourceKey(s)))); const candidates = entries.filter(e => e.sessionId === first.sessionId && !covered.has(this.sourceKey(e))); const picked: RawEntry[] = []; let chars = 0; for (const entry of candidates) { if (picked.length >= this.maxLeaf) break; const size = entry.payloadJson.length; if (picked.length > 0 && chars + size > this.maxInputChars) break; picked.push(entry); chars += size; } return picked; }\n selectCondensation(sessionId?: string, activeSources?: ReadonlySet<string>): LcmNode[] { const nodes = this.listNodes(100000).filter(n => n.state === \"ready\" && n.policyHash === this.policyHash && (!sessionId || n.sessionId === sessionId) && (!activeSources || n.sources.every(s => activeSources.has(this.sourceKey(s))))); const eligible = new Set(nodes.map(n => n.nodeId)); const edges = this.ledger.readOnly(db => db.prepare(\"SELECT e.parent_id,e.child_id FROM summary_edges e JOIN summary_nodes parent ON parent.node_id=e.parent_id AND parent.project_key=? JOIN summary_nodes child ON child.node_id=e.child_id AND child.project_key=parent.project_key WHERE parent.project_key=?\").all(this.projectKey, this.projectKey) as Array<{parent_id:string;child_id:string}>); const consumed = new Set(edges.filter(e => eligible.has(e.parent_id)).map(e => e.child_id)); const candidates = nodes.filter(n => !consumed.has(n.nodeId)); const first = candidates[0]; if (!first) return []; const depth = Math.min(...candidates.map(n => n.depth)); const sameDepth = candidates.filter(n => n.depth === depth); if (depth > 0 && sameDepth.length < 2) return []; return candidates.filter(n => n.projectKey === first.projectKey && n.sessionId === first.sessionId && n.depth === depth).sort((a,b) => a.nodeId.localeCompare(b.nodeId)).slice(0, this.maxChildren); }\n createLeaf(entries: RawEntry[]): LcmNode | undefined { if (!entries.length) return undefined; const source = entries.map((e, index) => { if (e.projectKey !== this.projectKey) throw new Error(\"entry project does not match ledger project\"); const payload = parse<{type?: unknown; id?: unknown}>(e.payloadJson); if (typeof payload.type !== \"string\" || !payload.type || payload.id !== e.entryId) throw new Error(\"invalid raw payload\"); if (hash(payload) !== rawHash(e)) throw new Error(\"payload hash mismatch\"); return { sessionId:e.sessionId, entryId:e.entryId, revision:e.revision, payloadHash:rawHash(e) }; }); this.validateSources(source); const node: LcmNode = { nodeId:`leaf:${hash({ projectKey:this.projectKey, source, policyHash:this.policyHash })}`, projectKey:this.projectKey, sessionId:entries[0]!.sessionId, kind:\"leaf\", sources:source, children:[], depth:0, sourceHash:hash(source.map(s=>s.payloadHash)), policyHash:this.policyHash, modelHash:\"\", state:\"pending\", createdAt:this.now() }; this.publish(node); return node; }\n createCondensed(children: LcmNode[]): LcmNode | undefined { if (!children.length) return undefined; if (children.some(c => c.state !== \"ready\")) throw new Error(\"condensation requires ready children\"); if (new Set(children.map(c=>c.sessionId)).size !== 1 || new Set(children.map(c=>c.depth)).size !== 1) throw new Error(\"mixed session or depth\"); const storedChildren = children.map((child) => this.getNode(child.nodeId)); if (storedChildren.some((child) => !child || child.projectKey !== this.projectKey)) throw new Error(\"child project does not match ledger project\"); if (storedChildren.some((child, index) => JSON.stringify(child) !== JSON.stringify(children[index]))) throw new Error(\"child payload changed\"); const source = [...new Map(storedChildren.flatMap(c => c!.sources).map((value) => [this.sourceKey(value), value])).values()]; this.validateSources(source); const node: LcmNode = { nodeId:`condensed:${hash({ projectKey:this.projectKey, children:storedChildren.map(c=>c!.nodeId), policyHash:this.policyHash })}`, projectKey:this.projectKey, sessionId:children[0]!.sessionId, kind:\"condensed\", sources:source, children:children.map(c=>c.nodeId), depth:Math.max(...children.map(c=>c.depth))+1, sourceHash:hash(children.map(c=>c.sourceHash)), policyHash:this.policyHash, modelHash:\"\", state:\"pending\", createdAt:this.now() }; this.publish(node); return node; }\n private validateSources(source: LcmSourceRef[]) { const seen = new Set<string>(); for (const s of source) { if (seen.has(this.sourceKey(s))) throw new Error(\"duplicate source identity\"); seen.add(this.sourceKey(s)); } if (new Set(source.map(s => s.sessionId)).size !== 1) throw new Error(\"cross-session ranges\"); }\n private sourceKey(source: Pick<LcmSourceRef, \"entryId\" | \"payloadHash\">) { return `${source.entryId}:${source.payloadHash}`; }\n private publish(node: LcmNode) { this.ledger.transaction(db => { if (node.children.includes(node.nodeId)) throw new Error(\"cycle\"); for (const child of node.children) if (!db.prepare(\"SELECT 1 FROM summary_nodes WHERE node_id=? AND project_key=?\").get(child,this.projectKey)) throw new Error(\"missing child\"); db.prepare(\"INSERT OR IGNORE INTO summary_nodes(node_id,project_key,payload,created_at) VALUES(?,?,?,?)\").run(node.nodeId,this.projectKey,JSON.stringify(node),node.createdAt); for (const child of node.children) db.prepare(\"INSERT OR IGNORE INTO summary_edges(parent_id,child_id) VALUES(?,?)\").run(node.nodeId,child); const job = this.job(node); db.prepare(\"INSERT OR IGNORE INTO maintenance_jobs(job_id,project_key,status,payload,created_at,updated_at) VALUES(?,?,?,?,?,?)\").run(job.jobId,this.projectKey,job.state,JSON.stringify(job),job.createdAt,job.updatedAt); }); }\n private job(node:LcmNode): LcmJob { const t=this.now(); return {jobId:`job:${node.nodeId}`,projectKey:this.projectKey,nodeId:node.nodeId,priority:node.kind === \"condensed\" ? 20 : 10,eligibleAt:t,state:\"pending\",attempts:0,nextRetryAt:t,createdAt:t,updatedAt:t}; }\n claim(jobId: string, ownerId = this.ownerId): LcmJob { return this.ledger.transaction(db => { const row = db.prepare(\"SELECT payload FROM maintenance_jobs WHERE job_id=? AND project_key=?\").get(jobId,this.projectKey) as {payload?:string}|undefined; if (!row?.payload) throw new Error(\"job not found\"); const old=parse<LcmJob>(row.payload); if (old.projectKey !== this.projectKey) throw new Error(\"job project does not match ledger project\"); const t=this.now(); const expired = old.state === \"running\" && (old.leaseUntil ?? 0) + LEASE_SWEEP_GRACE_MS <= t; if (old.state === \"running\" && !expired) throw new LcmRejection(\"job lease held\"); if ((old.state !== \"pending\" && !expired) || old.eligibleAt > t || old.nextRetryAt > t) throw new LcmRejection(\"job not eligible\"); const leases = this.liveLeases(db, t, old.jobId); if (leases.length >= this.concurrencyLimit) throw new LcmRejection(\"project lease held\"); const nodeRow = db.prepare(\"SELECT payload FROM summary_nodes WHERE node_id=? AND project_key=?\").get(old.nodeId,this.projectKey) as {payload?:string}|undefined; const sessionId = nodeRow?.payload ? parse<LcmNode>(nodeRow.payload).sessionId : \"\"; if (!this.admits(db, t, sessionId, leases)) throw new LcmRejection(\"budget exhausted\"); const out={...old,state:\"running\" as const,ownerId,leaseToken:token(),leaseUntil:t+LEASE_MS,updatedAt:t}; db.prepare(\"UPDATE maintenance_jobs SET status=?,payload=?,updated_at=? WHERE job_id=? AND project_key=?\").run(out.state,JSON.stringify(out),t,jobId,this.projectKey); return out; }); }\n claimEmergency(jobId: string, ownerId = this.ownerId): LcmJob { return this.ledger.transaction(db => { const row = db.prepare(\"SELECT payload FROM maintenance_jobs WHERE job_id=? AND project_key=?\").get(jobId,this.projectKey) as {payload?:string}|undefined; if (!row?.payload) throw new Error(\"job not found\"); const old = parse<LcmJob>(row.payload); if (old.projectKey !== this.projectKey) throw new Error(\"job project does not match ledger project\"); const t = this.now(); const expired = old.state === \"running\" && (old.leaseUntil ?? 0) <= t; if (old.state === \"running\" && !expired) throw new LcmRejection(\"job lease held\"); if (old.state === \"completed\") throw new Error(\"job already completed\"); const out = { ...old, state: \"running\" as const, ownerId, leaseToken: token(), leaseUntil: t + LEASE_MS, updatedAt: t }; db.prepare(\"UPDATE maintenance_jobs SET status=?,payload=?,updated_at=? WHERE job_id=? AND project_key=?\").run(out.state,JSON.stringify(out),t,jobId,this.projectKey); return out; }); }\n renew(job:LcmJob): LcmJob { return this.fenced(job, old => ({...old,leaseUntil:this.now()+LEASE_MS,updatedAt:this.now()})); }\n private validateText(text: unknown): asserts text is string { if (typeof text !== \"string\" || text.length === 0) throw new Error(\"invalid summary text\"); let length = 0; for (const _ of text) { length += 1; if (length > this.maxOutputChars) throw new Error(\"summary exceeds output bound\"); } }\n private validateShrink(text: string, inputBytes: number): void { if (!Number.isSafeInteger(inputBytes) || inputBytes < 0) throw new Error(\"invalid input bound\"); if (utf8Bytes(text) >= inputBytes) throw new Error(\"summary does not shrink its input\"); }\n withinBudget(sessionId: string, excludeJobId?: string): boolean { return this.ledger.readOnly(db => { const at = this.now(); return this.admits(db, at, sessionId, this.liveLeases(db, at, excludeJobId)); }); }\n private accountRejected(sessionId: string, result: LcmModelResult): void { if (![result.inputTokens,result.outputTokens,result.cost,result.wallMs].every((value) => Number.isFinite(value) && value >= 0)) return; try { this.ledger.transaction(db => this.account(db, sessionId, result)); } catch {} }\n complete(job:LcmJob, result:LcmModelResult, inputBytes: number): LcmNode { this.validateText(result.text); this.validateShrink(result.text, inputBytes); return this.ledger.transaction(db => { const current=this.readJob(db,job.jobId); this.assertLease(current,job); if (current.nodeId !== job.nodeId) throw new Error(\"job node mismatch\"); const row=db.prepare(\"SELECT payload FROM summary_nodes WHERE node_id=? AND project_key=?\").get(job.nodeId,this.projectKey) as {payload?:string}|undefined; if (!row?.payload) throw new Error(\"node not found\"); const node=parse<LcmNode>(row.payload); if (node.projectKey !== this.projectKey || node.nodeId !== current.nodeId) throw new Error(\"node project does not match ledger project\"); for (const source of node.sources) { const raw=db.prepare(\"SELECT payload_json,session_id FROM raw_entries WHERE project_key=? AND session_id=? AND entry_id=? AND revision=?\").get(this.projectKey,source.sessionId,source.entryId,source.revision) as {payload_json?:string;session_id?:string}|undefined; if (!raw?.payload_json || hash(parse(raw.payload_json)) !== source.payloadHash || raw.session_id !== source.sessionId) throw new Error(\"stale source\"); } if (![result.inputTokens,result.outputTokens,result.cost,result.wallMs].every((value) => Number.isFinite(value) && value >= 0)) throw new Error(\"invalid model usage\"); const projectUsage = this.usage(db, this.day(this.now())); const sessionUsage = this.usage(db, this.day(this.now()), node.sessionId); if (projectUsage.calls + 1 > this.budget.calls || projectUsage.inputTokens + result.inputTokens > this.budget.inputTokens || projectUsage.outputTokens + result.outputTokens > this.budget.outputTokens || projectUsage.cost + result.cost > this.budget.cost || projectUsage.wallMs + result.wallMs > this.budget.wallMs || sessionUsage.calls + 1 > this.budget.sessionCalls) throw new Error(\"budget exhausted\"); this.recordRevision(db, node); const out={...node,state:\"ready\" as const,text:result.text,modelHash:result.modelHash}; this.account(db,node.sessionId,result); db.prepare(\"UPDATE summary_nodes SET payload=? WHERE node_id=? AND project_key=?\").run(JSON.stringify(out),node.nodeId,this.projectKey); const { ownerId: _ownerId, leaseToken: _leaseToken, leaseUntil: _leaseUntil, ...base } = current; const done={...base,state:\"completed\" as const,updatedAt:this.now()}; db.prepare(\"UPDATE maintenance_jobs SET status=?,payload=?,updated_at=? WHERE job_id=? AND project_key=?\").run(done.state,JSON.stringify(done),done.updatedAt,done.jobId,this.projectKey); return out; }); }\n completeEmergency(job:LcmJob, text:string): LcmNode { this.validateText(text); return this.ledger.transaction(db => { const current=this.readJob(db,job.jobId); this.assertLease(current,job); if (current.nodeId !== job.nodeId) throw new Error(\"job node mismatch\"); const row=db.prepare(\"SELECT payload FROM summary_nodes WHERE node_id=? AND project_key=?\").get(job.nodeId,this.projectKey) as {payload?:string}|undefined; if (!row?.payload) throw new Error(\"node not found\"); const node=parse<LcmNode>(row.payload); if (node.projectKey !== this.projectKey || node.nodeId !== current.nodeId) throw new Error(\"node project does not match ledger project\"); for (const source of node.sources) { const raw=db.prepare(\"SELECT payload_json,session_id FROM raw_entries WHERE project_key=? AND session_id=? AND entry_id=? AND revision=?\").get(this.projectKey,source.sessionId,source.entryId,source.revision) as {payload_json?:string;session_id?:string}|undefined; if (!raw?.payload_json || hash(parse(raw.payload_json)) !== source.payloadHash || raw.session_id !== source.sessionId) throw new Error(\"stale source\"); } this.recordRevision(db, node); const out={...node,state:\"ready\" as const,text,modelHash:\"emergency\"}; db.prepare(\"UPDATE summary_nodes SET payload=? WHERE node_id=? AND project_key=?\").run(JSON.stringify(out),node.nodeId,this.projectKey); const { ownerId: _ownerId, leaseToken: _leaseToken, leaseUntil: _leaseUntil, ...base } = current; const done={...base,state:\"completed\" as const,updatedAt:this.now()}; db.prepare(\"UPDATE maintenance_jobs SET status=?,payload=?,updated_at=? WHERE job_id=? AND project_key=?\").run(done.state,JSON.stringify(done),done.updatedAt,done.jobId,this.projectKey); return out; }); }\n fail(job:LcmJob,error:string): LcmJob { return this.fenced(job, old => { const attempts=old.attempts+1; const delay=Math.min(900_000,30_000*2**(attempts-1)); const { ownerId: _ownerId, leaseToken: _leaseToken, leaseUntil: _leaseUntil, ...base } = old; return {...base,attempts,error,state:attempts>=3?\"failed\":\"pending\",eligibleAt:this.now()+delay,nextRetryAt:this.now()+delay,updatedAt:this.now()}; }); }\n async run(job:LcmJob, model:LcmSummarizer, input:string, signal=new AbortController().signal): Promise<LcmNode> {\n let sources: LcmSourceRef[] = [];\n let claimed: LcmJob | undefined;\n const controller = new AbortController();\n let renew: ReturnType<typeof setInterval> | undefined;\n const timer = setTimeout(() => controller.abort(), this.modelTimeoutMs);\n const abort = () => controller.abort();\n signal.addEventListener(\"abort\", abort, { once: true });\n const inputBytes = utf8Bytes(input);\n try {\n claimed = this.claim(job.jobId, job.ownerId ?? this.ownerId);\n const node = this.getNode(claimed.nodeId);\n sources = node?.sources ?? [];\n const kind = node?.kind ?? \"leaf\";\n const sessionId = node?.sessionId ?? \"\";\n renew = setInterval(() => { try { if (claimed) claimed = this.renew(claimed); } catch {} }, 10_000);\n let lastError: unknown = new Error(\"LCM summarization did not converge\");\n for (const [index, level] of LCM_MODEL_LEVELS.entries()) {\n if (controller.signal.aborted) break;\n if (index > 0 && !this.withinBudget(sessionId, job.jobId)) break;\n const target = Math.max(1, Math.min(Math.floor(this.maxOutputChars * level.share), inputBytes - 1));\n let result: LcmModelResult;\n try {\n result = await Promise.race([\n model.generate({ prompt: buildLcmPrompt(kind, input, this.maxInputChars, level.mode, target), sessionId, signal: controller.signal }),\n new Promise<never>((_, reject) => controller.signal.addEventListener(\"abort\", () => reject(new Error(\"LCM timeout\")), { once: true })),\n ]);\n } catch (error) { lastError = error; continue; }\n if (utf8Bytes(result.text) >= inputBytes) { this.accountRejected(sessionId, result); lastError = new Error(\"summary does not shrink its input\"); continue; }\n return this.complete(claimed, result, inputBytes);\n }\n throw lastError;\n } catch (error) {\n if (!claimed) throw error;\n const fallback = emergencyReduce(input, this.maxOutputChars, sources);\n try { return this.completeEmergency(claimed, fallback); }\n catch (fenced) {\n if (isLcmRejection(fenced) && fenced.reason === \"lease fenced\") throw fenced;\n try { this.fail(claimed, String(error)); } catch {}\n throw error;\n }\n } finally { clearTimeout(timer); if (renew) clearInterval(renew); signal.removeEventListener(\"abort\", abort); }\n }\n private day(ms:number): string { return new Date(ms).toISOString().slice(0,10); }\n private usage(db:any, day:string, sessionId?:string): LcmBudget { const q = sessionId === undefined ? \"SELECT COALESCE(SUM(calls),0) calls,COALESCE(SUM(input_tokens),0) inputTokens,COALESCE(SUM(output_tokens),0) outputTokens,COALESCE(SUM(cost),0) cost,COALESCE(SUM(wall_ms),0) wallMs FROM maintenance_usage WHERE project_key=? AND day=?\" : \"SELECT COALESCE(SUM(calls),0) calls,COALESCE(SUM(input_tokens),0) inputTokens,COALESCE(SUM(output_tokens),0) outputTokens,COALESCE(SUM(cost),0) cost,COALESCE(SUM(wall_ms),0) wallMs FROM maintenance_usage WHERE project_key=? AND day=? AND session_id=?\"; const r=(sessionId === undefined ? db.prepare(q).get(this.projectKey,day) : db.prepare(q).get(this.projectKey,day,sessionId)) as LcmBudget; return r; }\n private account(db:any, sessionId:string, result:LcmModelResult) { const d=this.day(this.now()); db.prepare(\"INSERT INTO maintenance_usage(project_key,day,session_id,calls,input_tokens,output_tokens,cost,wall_ms) VALUES(?,?,?,?,?,?,?,?) ON CONFLICT(project_key,day,session_id) DO UPDATE SET calls=calls+excluded.calls,input_tokens=input_tokens+excluded.input_tokens,output_tokens=output_tokens+excluded.output_tokens,cost=cost+excluded.cost,wall_ms=wall_ms+excluded.wall_ms\").run(this.projectKey,d,sessionId,1,result.inputTokens,result.outputTokens,result.cost,result.wallMs); }\n private readJob(db: any,id:string):LcmJob { const row=db.prepare(\"SELECT payload FROM maintenance_jobs WHERE job_id=? AND project_key=?\").get(id,this.projectKey) as {payload:string}|undefined; if(!row) throw new Error(\"job not found\"); const job=parse<LcmJob>(row.payload); if(job.projectKey!==this.projectKey) throw new Error(\"job project does not match ledger project\"); return job; }\n private assertLease(current:LcmJob, expected:LcmJob) { if(current.ownerId!==expected.ownerId || current.leaseToken!==expected.leaseToken || current.state!==\"running\" || (current.leaseUntil??0)<this.now()) throw new LcmRejection(\"lease fenced\"); }\n private fenced(job:LcmJob, update:(old:LcmJob)=>LcmJob):LcmJob { return this.ledger.transaction(db => { const old=this.readJob(db,job.jobId); this.assertLease(old,job); const out=update(old); db.prepare(\"UPDATE maintenance_jobs SET status=?,payload=?,updated_at=? WHERE job_id=? AND project_key=?\").run(out.state,JSON.stringify(out),out.updatedAt,out.jobId,this.projectKey); return out; }); }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import fs from \"node:fs\";\nimport type { ExtensionContext } from \"@oh-my-pi/pi-coding-agent\";\nimport { canonicalLcmPayload, canonicalProjectIdentity, hashLcmPayload, LcmLedger, type RawEntry } from \"../storage/lcm-ledger.js\";\nimport { defaultLedgerRoot, hash } from \"../storage/lcm-identity.js\";\n\nimport { sweepLedgers, type LcmSweepResult } from \"../storage/lcm-directory.js\";\nimport { migrationDropReasons, reconcileSession, type MigrationDrops } from \"../storage/lcm-migration.js\";\nimport { clipUtf8, MAX_SUMMARY_BYTES, utf8Bytes } from \"./bounds.js\";\nimport { lcmSummaryAddress, renderLcmChildAddresses, renderLcmSourceAddresses } from \"./lcm-addresses.js\";\nimport { emergencyReduce, LcmModelAdapter, type LcmSummarizer } from \"./lcm-model.js\";\nimport { LCM_RECOVERY_POINTER } from \"./render.js\";\nimport { reconcileLcmState } from \"./lcm-status.js\";\nimport { lcmChecks, type LcmAutoRepair, type LcmCheck, type LcmDiagnostics, type LcmRepairId, type LcmRepairOutcome } from \"./lcm-doctor.js\";\nimport { DEFAULT_LEAF_ENTRIES, DEFAULT_MAINTENANCE_CONCURRENCY, isLcmCapacityRejection, isLcmRejection, LcmMaintenance, type LcmBudgetPolicy, type LcmJob, type LcmNode } from \"./lcm-maintenance.js\";\nimport type { LcmCompactionInput, LcmCompactionOutput } from \"./hook.js\";\nimport { decodeCompactionInstructions } from \"./instructions.js\";\n\ntype LcmMaintenanceTrigger = \"occupancy\" | \"jobs\" | \"backlog\";\n\nexport interface LcmPreview {\n text: string;\n nodes: number;\n summaryBytes: number;\n sourceBytes: number;\n coveredSources: number;\n activeSources: number;\n}\n\nexport interface LcmReconciliation {\n degraded: boolean;\n errors: number;\n raced: number;\n absent: number;\n drops: MigrationDrops;\n reasons: string[];\n}\n\nexport interface LcmReport {\n projectKey: string;\n sessionId: string | undefined;\n state: string;\n ledgerState: string;\n degraded: string | undefined;\n summaryModel: string | undefined;\n rawEntries: number;\n sessionEntries: number;\n modelNodes: number;\n emergencyNodes: number;\n pendingNodes: number;\n pendingJobs: number;\n upgradableNodes: number;\n usage: { calls: number; inputTokens: number; outputTokens: number; cost: number; wallMs: number };\n budget: { calls: number; sessionCalls: number; wallMs: number };\n reconciliation: LcmReconciliation | undefined;\n}\n\nexport interface LcmRuntimeOptions {\n rootDir?: string;\n summaryModel?: string;\n maxLeafEntries?: number;\n maxCondenseChildren?: number;\n lcmMaxInputChars?: number;\n lcmMaxOutputTokens?: number;\n lcmMaxOutputChars?: number;\n maxMaintenancePasses?: number;\n maintenanceConcurrency?: number;\n modelSummaries?: boolean;\n modelTimeoutSeconds?: number;\n maxDailyModelCalls?: number;\n maxSessionModelCalls?: number;\n maxDailyModelSeconds?: number;\n maintenanceRunSeconds?: number;\n softThresholdRatio?: number;\n}\n\nconst SHUTDOWN_GRACE_MS = 500;\nconst MAX_AUTO_REPAIR_ATTEMPTS = 5;\nconst AUTO_REPAIR_DELAY_MS = 30_000;\nconst AUTO_REPAIR_CLEAR_MS = 1_800_000;\nconst MAX_REPAIR_LOG = 8;\nconst CLAIMABLE_JOB_LIMIT = 256;\nconst FAILED_JOB_WINDOW_MS = 24 * 60 * 60 * 1_000;\nconst NODE_ADDRESS_LABEL = \"address: \";\nconst BLOCK_SEPARATOR = \"\\n\\n\";\nconst WITHHELD_EXPAND_LABEL = \"; expand: \";\n\nconst withheldHeadline = (count: number): string =>\n `\u2026 withheld ${count} frontier node${count === 1 ? \"\" : \"s\"} that did not fit`;\n\nconst withheldNotice = (nodeIds: readonly string[], budget: number): string => {\n const headline = withheldHeadline(nodeIds.length);\n const addresses = nodeIds.map(lcmSummaryAddress);\n const line = (kept: readonly string[], omitted: number): string =>\n `${headline}${WITHHELD_EXPAND_LABEL}${kept.join(\", \")}${omitted > 0 ? `, +${omitted} more` : \"\"}`;\n const kept: string[] = [];\n for (const address of addresses) {\n if (utf8Bytes(line([...kept, address], addresses.length - kept.length - 1)) > budget) break;\n kept.push(address);\n }\n return kept.length === 0 ? headline : line(kept, addresses.length - kept.length);\n};\n\nconst clipOversized = (\n blocks: ReadonlyArray<{ node: LcmNode; head: string }>,\n headBytes: readonly number[],\n footer: string,\n separator: number,\n requestBlock = \"\",\n): string => {\n let widest = 0;\n for (let index = 1; index < blocks.length; index += 1) if (headBytes[index]! > headBytes[widest]!) widest = index;\n const { node } = blocks[widest]!;\n const addressLine = `\\n${NODE_ADDRESS_LABEL}${lcmSummaryAddress(node.nodeId)}`;\n const withheld = blocks.filter((_, index) => index !== widest).map((block) => block.node.nodeId);\n const requestBytes = requestBlock ? utf8Bytes(requestBlock) + separator : 0;\n const available = MAX_SUMMARY_BYTES - utf8Bytes(footer) - utf8Bytes(addressLine) - requestBytes;\n const notice = withheld.length === 0\n ? \"\"\n : withheldNotice(withheld, Math.max(utf8Bytes(withheldHeadline(withheld.length)), Math.floor(available / 2)));\n const text = clipUtf8(node.text ?? \"\", available - (notice ? separator + utf8Bytes(notice) : 0));\n const head = text ? `${text}${addressLine}` : addressLine.slice(1);\n const parts = [...(requestBlock ? [requestBlock] : []), head, ...(notice ? [notice] : [])];\n return `${parts.join(BLOCK_SEPARATOR)}${footer}`;\n};\n\nexport const renderAddressedFrontier = (\n frontier: readonly LcmNode[],\n requestLines: readonly string[] = [],\n): string => {\n const blocks = frontier\n .filter((node) => Boolean(node.text))\n .map((node) => ({ node, head: `${node.text ?? \"\"}\\n${NODE_ADDRESS_LABEL}${lcmSummaryAddress(node.nodeId)}` }));\n if (blocks.length === 0) return \"\";\n const requestBlock = requestLines.length > 0 ? `[Compaction Request]\\n${requestLines.join(\"\\n\")}` : \"\";\n const footer = `\\n\\n${LCM_RECOVERY_POINTER}`;\n const separator = utf8Bytes(BLOCK_SEPARATOR);\n const footerBytes = utf8Bytes(footer);\n const requestBytes = requestBlock ? utf8Bytes(requestBlock) + separator : 0;\n const headBytes = blocks.map((block) => utf8Bytes(block.head));\n const floorFor = (kept: number): number =>\n kept === blocks.length ? 0 : separator + utf8Bytes(withheldHeadline(blocks.length - kept));\n\n const kept: number[] = [];\n const withheld: number[] = [];\n let body = requestBytes;\n for (let index = 0; index < blocks.length; index += 1) {\n const grown = body + headBytes[index]! + (kept.length > 0 || requestBlock ? separator : 0);\n if (grown + footerBytes + floorFor(kept.length + 1) > MAX_SUMMARY_BYTES) { withheld.push(index); continue; }\n kept.push(index);\n body = grown;\n }\n if (kept.length === 0) return clipOversized(blocks, headBytes, footer, separator, requestBlock);\n\n const room = MAX_SUMMARY_BYTES - body - footerBytes - (withheld.length === 0 ? 0 : separator);\n const notice = withheld.length === 0\n ? \"\"\n : withheldNotice(withheld.map((index) => blocks[index]!.node.nodeId), Math.max(utf8Bytes(withheldHeadline(withheld.length)), Math.floor(room / 2)));\n const perNode = Math.max(0, Math.floor((room - utf8Bytes(notice)) / kept.length) - 1);\n const rendered = kept.map((index) => {\n const { node, head } = blocks[index]!;\n const addresses = node.sources.length > 0\n ? renderLcmSourceAddresses(node.sources, perNode)\n : renderLcmChildAddresses(node.children, perNode);\n return addresses && utf8Bytes(addresses) <= perNode ? `${head}\\n${addresses}` : head;\n });\n const parts = [...(requestBlock ? [requestBlock] : []), ...rendered, ...(notice ? [notice] : [])];\n return `${parts.join(BLOCK_SEPARATOR)}${footer}`;\n};\n\nexport class LcmRuntime {\n readonly ledger: LcmLedger;\n readonly maintenance: LcmMaintenance;\n private readonly context: ExtensionContext;\n private readonly resolveOptions: () => LcmRuntimeOptions;\n private readonly abort = new AbortController();\n private writePending: Promise<void> = Promise.resolve();\n private maintenancePending: Promise<void> = Promise.resolve();\n private closed = false;\n private dirty = false;\n private degradedError: unknown;\n private activeSources = new Set<string>();\n private activeSessionId: string | undefined;\n private persisted = new WeakMap<object, { key: string; contentHash: string }>();\n private persistedSessionId: string | undefined;\n private lastReconciliation: LcmReconciliation | undefined;\n\n constructor(context: ExtensionContext, options: LcmRuntimeOptions | (() => LcmRuntimeOptions) = {}) {\n this.context = context;\n this.resolveOptions = typeof options === \"function\" ? options : () => options;\n const initial = this.resolveOptions();\n const recorded = context.sessionManager.getRecordedCwd?.();\n const liveCwd = recorded || context.cwd;\n const project = canonicalProjectIdentity({ liveCwd });\n const ledgerOptions = initial.rootDir === undefined\n ? { project: { liveCwd: project.canonicalPath ?? liveCwd } }\n : { rootDir: initial.rootDir, project: { liveCwd: project.canonicalPath ?? liveCwd } };\n this.ledger = new LcmLedger(ledgerOptions);\n this.maintenance = new LcmMaintenance(this.ledger, {\n ...initial,\n ...(initial.lcmMaxInputChars === undefined ? {} : { maxInputChars: initial.lcmMaxInputChars }),\n ...(initial.lcmMaxOutputChars === undefined ? {} : { maxOutputChars: initial.lcmMaxOutputChars }),\n ...(initial.modelTimeoutSeconds === undefined ? {} : { modelTimeoutMs: initial.modelTimeoutSeconds * 1_000 }),\n maxConcurrentJobs: () => this.resolveOptions().maintenanceConcurrency ?? DEFAULT_MAINTENANCE_CONCURRENCY,\n budget: {\n ...(initial.maxDailyModelCalls ? { calls: initial.maxDailyModelCalls } : {}),\n ...(initial.maxSessionModelCalls ? { sessionCalls: initial.maxSessionModelCalls } : {}),\n ...(initial.maxDailyModelSeconds ? { wallMs: initial.maxDailyModelSeconds * 1_000 } : {}),\n },\n });\n }\n\n private get options(): LcmRuntimeOptions { return this.resolveOptions(); }\n\n get projectKey(): string { return this.ledger.project.key; }\n get signal(): AbortSignal { return this.abort.signal; }\n get status(): \"healthy\" | \"degraded\" { return this.degradedMessage() === undefined ? \"healthy\" : \"degraded\"; }\n get error(): unknown { return this.degradedError; }\n get reconciliation(): LcmReconciliation | undefined { return this.lastReconciliation; }\n\n private degradedMessage(): string | undefined {\n const faults: string[] = [];\n if (this.degradedError !== undefined) faults.push(String(this.degradedError instanceof Error ? this.degradedError.message : this.degradedError));\n const errors = this.lastReconciliation?.errors ?? 0;\n if (errors > 0) faults.push(`LCM session reconciliation reported ${errors} error(s)`);\n const reasons = this.lastReconciliation?.reasons ?? [];\n if (reasons.length > 0) faults.push(`LCM session reconciliation dropped ${reasons.join(\"; \")}`);\n const failed = this.recentlyFailedJobs();\n if (failed > 0) faults.push(`LCM maintenance left ${failed} job${failed === 1 ? \"\" : \"s\"} failed`);\n return faults.length === 0 ? undefined : faults.join(\" \u00B7 \");\n }\n\n private recentlyFailedJobs(): number {\n try { return this.maintenance.countJobs(\"failed\", Date.now() - FAILED_JOB_WINDOW_MS); } catch { return 0; }\n }\n markDirty(): void { this.dirty = true; }\n\n private enqueueWrite(operation: () => void | Promise<void>): Promise<void> {\n const run = this.writePending.then(operation);\n this.writePending = run.catch((error) => { this.degradedError = error; });\n return run;\n }\n\n private refreshActiveSources(sessionId: string, entries: readonly { id: string }[]): void {\n const ids = new Set(entries.map((entry) => entry.id));\n const latest = new Map<string, RawEntry>();\n for (const entry of this.ledger.readRaw(this.projectKey, sessionId)) {\n if (!ids.has(entry.entryId)) continue;\n const previous = latest.get(entry.entryId);\n if (!previous || previous.revision < entry.revision) latest.set(entry.entryId, entry);\n }\n this.activeSources = new Set(\n [...latest.values()].map((entry) => this.sourceKey(entry)),\n );\n this.activeSessionId = sessionId;\n this.invalidateFrontier();\n }\n\n private invalidateFrontier(): void {\n this.frontierCache = undefined;\n }\n\n reconcileSelectedSession(): Promise<void> {\n if (this.closed) return Promise.resolve();\n return this.enqueueWrite(() => {\n const getSessionFile = this.context.sessionManager.getSessionFile;\n if (typeof getSessionFile !== \"function\") return;\n const sessionFile = getSessionFile.call(this.context.sessionManager);\n if (!sessionFile) return;\n const recorded = this.context.sessionManager.getRecordedCwd?.();\n const cwd = recorded || this.context.cwd;\n const result = reconcileSession({\n agentDir: this.options.rootDir ?? process.env.PI_CODING_AGENT_DIR ?? `${process.env.HOME ?? \".\"}/.omp/agent`,\n ledger: this.ledger,\n files: [sessionFile],\n liveCwd: cwd,\n projectCwd: cwd,\n apply: true,\n });\n this.lastReconciliation = {\n degraded: result.degraded,\n errors: result.counts.errors,\n raced: result.counts.raced,\n absent: result.counts.absent,\n drops: result.drops,\n reasons: migrationDropReasons(result.drops),\n };\n const sessionId = this.context.sessionManager.getSessionId();\n this.refreshActiveSources(sessionId, this.context.sessionManager.getBranch());\n });\n }\n\n /** Appends only the entries this session has not stored yet; the rest are already addressed. */\n readback(): Promise<void> {\n if (this.closed) return Promise.resolve();\n return this.enqueueWrite(() => {\n if (this.closed) return;\n const entries = this.context.sessionManager.getBranch();\n const sessionId = this.context.sessionManager.getSessionId();\n const recorded = this.context.sessionManager.getRecordedCwd?.();\n if (this.persistedSessionId !== sessionId) {\n this.persisted = new WeakMap();\n this.persistedSessionId = sessionId;\n }\n const active = new Set<string>();\n const pending: Array<{ entry: (typeof entries)[number]; payloadJson: string; contentHash: string }> = [];\n for (const entry of entries) {\n const payloadJson = canonicalLcmPayload(entry);\n const contentHash = hash(payloadJson);\n const known = this.persisted.get(entry);\n if (known?.contentHash === contentHash) active.add(known.key);\n else pending.push({ entry, payloadJson, contentHash });\n }\n if (pending.length > 0) {\n this.ledger.transaction(() => {\n for (const { entry, payloadJson, contentHash } of pending) {\n const message = entry.type === \"message\" ? entry.message as { role?: string; content?: unknown } : undefined;\n const stored = this.ledger.appendRaw({\n projectKey: this.projectKey,\n sessionId,\n entryId: entry.id,\n role: message?.role ?? entry.type,\n content: message ? JSON.stringify(message.content ?? \"\") : payloadJson,\n payloadJson,\n parentEntryId: entry.parentId ?? null,\n ...(recorded || this.context.cwd ? { recordedCwd: recorded || this.context.cwd } : {}),\n });\n const key = this.sourceKey(stored);\n this.persisted.set(entry, { key, contentHash });\n active.add(key);\n }\n });\n }\n this.activeSources = active;\n this.activeSessionId = sessionId;\n this.invalidateFrontier();\n this.dirty = false;\n this.degradedError = undefined;\n });\n }\n\n /** Mid-turn sync: the write path already records its own failure. */\n syncEntries(): void {\n if (this.closed) return;\n void this.readback().catch(() => {});\n }\n\n async syncAndSchedule(): Promise<void> {\n if (this.closed) return;\n const sessionId = this.context.sessionManager.getSessionId();\n if (this.dirty || !this.activeSessionId || this.activeSessionId !== sessionId || this.activeSources.size === 0) {\n await this.readback();\n }\n if ((this.lastReconciliation?.absent ?? 0) > 0 && this.sessionFilePresent()) await this.reconcileSelectedSession();\n this.reclaimExpiredLeases();\n await this.autoRepair();\n if (this.maintenanceTrigger() !== undefined) this.scheduleMaintenance();\n }\n\n /** One repair per beat, budgeted per fault class in the ledger so a restart resumes the budget. */\n async autoRepair(): Promise<LcmRepairOutcome | undefined> {\n if (this.closed) return undefined;\n let ladder: Map<string, { attempts: number; nextAt: number; detail: string; updatedAt: number }>;\n let checks: LcmCheck[];\n try {\n ladder = this.ledger.readRepairLadder();\n if (ladder.size === 0 && this.degradedMessage() === undefined) return undefined;\n checks = lcmChecks(this.diagnostics());\n } catch (error) {\n this.degradedError = error;\n return undefined;\n }\n const now = Date.now();\n const actionable = new Map<string, { check: LcmCheck; repair: LcmRepairId }>();\n for (const check of checks) {\n const repair = check.repair;\n if (!repair || (check.severity !== \"warn\" && check.severity !== \"fail\")) continue;\n actionable.set(check.id, { check, repair });\n }\n for (const [fault, state] of ladder) {\n if (!actionable.has(fault) && now - state.updatedAt >= AUTO_REPAIR_CLEAR_MS) this.ledger.clearRepairLadder(fault);\n }\n const eligible = [...actionable.values()].filter(({ check }) => {\n const state = ladder.get(check.id);\n return !state || (state.attempts < MAX_AUTO_REPAIR_ATTEMPTS && state.nextAt <= now);\n });\n const target = eligible.find(({ check }) => check.severity === \"fail\") ?? eligible[0];\n if (!target) return undefined;\n const outcome = await this.repair(target.repair);\n const attempts = (ladder.get(target.check.id)?.attempts ?? 0) + 1;\n this.ledger.writeRepairLadder(target.check.id, attempts, now + AUTO_REPAIR_DELAY_MS * 2 ** (attempts - 1), outcome.detail);\n return outcome;\n }\n\n /** Reclaims ledgers whose project directory is gone; bounded to one sweep a day. */\n sweepLedgers(): LcmSweepResult {\n if (this.closed) return { removed: [], bytes: 0, skipped: true };\n try {\n return sweepLedgers(this.options.rootDir ?? defaultLedgerRoot(), { keepKey: this.projectKey });\n } catch {\n return { removed: [], bytes: 0, skipped: true };\n }\n }\n\n reclaimExpiredLeases(): number {\n if (this.closed) return 0;\n try {\n return this.maintenance.sweepExpiredLeases().length + this.maintenance.recoverLegacyContentionRetirements().length;\n } catch (error) {\n this.degradedError = error;\n return 0;\n }\n }\n\n maintenanceTrigger(): LcmMaintenanceTrigger | undefined {\n const sessionId = this.activeSessionId;\n if (this.closed || !sessionId || this.activeSources.size === 0) return undefined;\n try {\n if (!this.maintenance.withinBudget(sessionId)) return undefined;\n if (this.maintenanceOccupancyReached()) return \"occupancy\";\n if (this.actionableJobs(sessionId, 1).length > 0) return \"jobs\";\n const { active, covered } = this.coverage();\n return active - covered >= Math.max(1, this.options.maxLeafEntries ?? DEFAULT_LEAF_ENTRIES) ? \"backlog\" : undefined;\n } catch (error) {\n this.degradedError = error;\n return undefined;\n }\n }\n\n /** Fails open: an unreadable occupancy never disables maintenance. */\n maintenanceOccupancyReached(): boolean {\n const ratio = this.options.softThresholdRatio;\n if (typeof ratio !== \"number\" || !Number.isFinite(ratio) || ratio <= 0) return true;\n let usage: { percent: number | null } | undefined;\n try {\n usage = this.context.getContextUsage?.();\n } catch {\n return true;\n }\n const percent = usage?.percent;\n if (typeof percent !== \"number\" || !Number.isFinite(percent)) return true;\n return percent / 100 >= ratio;\n }\n\n maintain(): Promise<void> { return this.syncAndSchedule(); }\n\n scheduleMaintenance(): void {\n if (this.closed) return;\n const run = this.maintenancePending.then(() => this.runMaintenance());\n this.maintenancePending = run.catch((error) => { this.degradedError = error; });\n }\n\n private actionableJobs(sessionId: string, limit: number): Array<{ job: LcmJob; node: LcmNode }> {\n const found: Array<{ job: LcmJob; node: LcmNode }> = [];\n if (limit <= 0) return found;\n for (const job of this.maintenance.claimableJobs(sessionId, CLAIMABLE_JOB_LIMIT)) {\n const node = this.maintenance.getNode(job.nodeId);\n if (!node || node.sessionId !== sessionId) continue;\n if (!node.sources.every((source) => this.activeSources.has(this.sourceKey(source)))) continue;\n found.push({ job, node });\n if (found.length >= limit) break;\n }\n return found;\n }\n\n private async runMaintenance(): Promise<void> {\n const sessionId = this.activeSessionId;\n if (this.closed || !sessionId || this.activeSources.size === 0) return;\n try {\n await this.runMaintenancePasses(sessionId);\n } finally {\n this.invalidateFrontier();\n }\n }\n\n private async runMaintenancePasses(sessionId: string): Promise<void> {\n const wantsModel = this.options.modelSummaries !== false;\n let model: LcmSummarizer;\n try {\n if (!wantsModel) throw new Error(\"model summaries are disabled by configuration\");\n model = new LcmModelAdapter(this.context, this.options.summaryModel, true, {\n ...(this.options.lcmMaxInputChars === undefined ? {} : { maxInputChars: this.options.lcmMaxInputChars }),\n ...(this.options.lcmMaxOutputTokens === undefined ? {} : { maxOutputTokens: this.options.lcmMaxOutputTokens }),\n ...(this.options.lcmMaxOutputChars === undefined ? {} : { maxOutputChars: this.options.lcmMaxOutputChars }),\n });\n } catch (error) {\n this.degradedError = error;\n model = { modelHash: \"unavailable\", generate: async () => { throw error instanceof Error ? error : new Error(String(error)); } };\n }\n const fanIn = Math.max(2, this.options.maxCondenseChildren ?? 4);\n const passes = Math.max(1, this.options.maxMaintenancePasses ?? 4);\n const runDeadline = Date.now() + Math.max(1, this.options.maintenanceRunSeconds ?? 60) * 1_000;\n const raw = this.ledger.readRaw(this.projectKey, sessionId).filter((entry) =>\n this.activeSources.has(this.sourceKey(entry)),\n );\n const inputFor = (node: NonNullable<ReturnType<LcmMaintenance[\"getNode\"]>>): string => {\n if (node.kind === \"condensed\") return node.children.map((id) => this.maintenance.getNode(id)?.text ?? \"\").filter(Boolean).join(\"\\n\\n\");\n return node.sources.map((source) => {\n const entry = this.ledger.readRawEntry(this.projectKey, source.sessionId, source.entryId, source.revision);\n if (!entry || entry.payloadHash !== source.payloadHash) throw new Error(\"stale source\");\n return entry.payloadJson;\n }).join(\"\\n\");\n };\n const runJob = async (job: LcmJob, node: LcmNode): Promise<\"done\" | \"rejected\" | \"capacity\"> => {\n try {\n const input = inputFor(node);\n await this.maintenance.run(job, model, input, this.signal);\n return \"done\";\n } catch (error) {\n if (isLcmCapacityRejection(error)) return \"capacity\";\n if (isLcmRejection(error)) return \"rejected\";\n this.degradedError = error;\n try { this.maintenance.recordFailure(job, error); } catch {}\n return \"done\";\n }\n };\n const dispatch = async (items: ReadonlyArray<{ job: LcmJob; node: LcmNode }>): Promise<void> => {\n let next = 0;\n const worker = async (slot: number): Promise<void> => {\n while (!this.closed && Date.now() < runDeadline && slot < this.maintenance.concurrencyLimit) {\n const item = items[next];\n if (!item) return;\n next += 1;\n if (await runJob(item.job, item.node) === \"capacity\") return;\n }\n };\n await Promise.all(Array.from({ length: Math.min(this.maintenance.concurrencyLimit, items.length) }, (_unused, slot) => worker(slot)));\n };\n this.reclaimExpiredLeases();\n for (let pass = 0; pass < passes && !this.closed && Date.now() < runDeadline; pass += 1) {\n const leafCandidate = this.maintenance.createLeaf(this.maintenance.selectLeaf(raw, this.activeSources));\n const leaf = leafCandidate ? this.maintenance.getNode(leafCandidate.nodeId) : undefined;\n const batch: Array<{ job: LcmJob; node: LcmNode }> = [];\n const queued = new Set<string>();\n if (leaf?.state === \"pending\") {\n const job = this.maintenance.jobForNode(leaf.nodeId);\n if (job && this.maintenance.isClaimable(job)) { batch.push({ job, node: leaf }); queued.add(job.jobId); }\n }\n const pending = this.actionableJobs(sessionId, passes);\n for (const item of pending) if (!queued.has(item.job.jobId)) { queued.add(item.job.jobId); batch.push(item); }\n await dispatch(batch);\n const children = this.maintenance.selectCondensation(sessionId, this.activeSources);\n if (children.length >= fanIn) {\n const node = this.maintenance.createCondensed(children);\n if (node) {\n const job = this.maintenance.jobForNode(node.nodeId);\n if (job && this.maintenance.isClaimable(job)) await runJob(job, node);\n }\n }\n if (!leaf && pending.length === 0 && children.length < fanIn) {\n const upgrades = this.maintenance.selectUpgrades(sessionId, this.activeSources, 1);\n const upgrade = upgrades[0];\n if (!upgrade) break;\n const job = this.maintenance.reopen(upgrade.nodeId);\n await runJob(job, upgrade);\n if (this.maintenance.getNode(upgrade.nodeId)?.modelHash !== \"emergency\") {\n for (const ancestor of this.maintenance.ancestorsOf(upgrade.nodeId)) {\n const node = this.maintenance.getNode(ancestor);\n if (node?.state === \"ready\") this.maintenance.reopen(ancestor, true);\n }\n }\n continue;\n }\n }\n }\n\n compact(input: LcmCompactionInput): LcmCompactionOutput {\n const instructions = decodeCompactionInstructions(input.customInstructions);\n const requestLines = instructions.ok ? instructions.requestLines : [];\n const persistedEntries = new Map<string, RawEntry>();\n this.ledger.transaction(() => {\n for (const entry of input.branchEntries) {\n const message = entry.type === \"message\" ? entry.message as { role?: string; content?: unknown } : undefined;\n const payloadJson = canonicalLcmPayload(entry);\n const stored = this.ledger.appendRaw({\n projectKey: this.projectKey,\n sessionId: input.sessionId,\n entryId: entry.id,\n role: message?.role ?? entry.type,\n content: message ? JSON.stringify(message.content ?? \"\") : payloadJson,\n payloadJson,\n parentEntryId: entry.parentId ?? null,\n });\n persistedEntries.set(`${entry.id}:${stored.payloadHash}`, stored);\n }\n });\n this.invalidateFrontier();\n const firstKeptIndex = input.firstKeptEntryId\n ? input.branchEntries.findIndex((entry) => entry.id === input.firstKeptEntryId)\n : input.branchEntries.length;\n const sourceEntries = input.branchEntries.slice(0, firstKeptIndex < 0 ? input.branchEntries.length : firstKeptIndex);\n const selectedStored = sourceEntries.map((entry) => {\n const payloadHash = hashLcmPayload(JSON.parse(canonicalLcmPayload(entry)));\n const stored = persistedEntries.get(`${entry.id}:${payloadHash}`);\n if (!stored) throw new Error(\"compaction source was not persisted\");\n return stored;\n });\n const activeSources = new Set(selectedStored.map((entry) => this.sourceKey(entry)));\n const frontier = this.maintenance.getFrontier(input.sessionId, activeSources);\n const coveredSources = new Set(frontier.flatMap((node) => node.sources.map((source) => this.sourceKey(source))));\n const summary = renderAddressedFrontier(frontier, requestLines);\n const instructionDetails = instructions.ok && (instructions.requestLines.length > 0 || instructions.policy.preserveCount > 0)\n ? { instructionPolicy: instructions.policy }\n : undefined;\n if (summary && selectedStored.every((entry) => coveredSources.has(this.sourceKey(entry)))) {\n return {\n summary,\n firstKeptEntryId: input.firstKeptEntryId,\n tokensBefore: input.tokensBefore,\n source: \"ready-frontier\",\n ...(instructionDetails ? { details: instructionDetails } : {}),\n };\n }\n if (selectedStored.length === 0) throw new Error(\"LCM emergency fallback has no persisted sources\");\n const payloads = sourceEntries.map((entry) => canonicalLcmPayload(entry)).join(\"\\n\");\n const sources = selectedStored.map((stored) => ({ sessionId: stored.sessionId, entryId: stored.entryId, revision: stored.revision, payloadHash: stored.payloadHash }));\n const fallback = emergencyReduce(payloads, this.options.lcmMaxOutputChars ?? 4_096, sources, requestLines);\n const leaf = this.maintenance.createLeaf(selectedStored);\n if (!leaf) throw new Error(\"LCM emergency fallback node was not created\");\n const persisted = this.maintenance.getNode(leaf.nodeId);\n if (persisted?.state === \"ready\") {\n if (JSON.stringify(persisted.sources) !== JSON.stringify(sources)) throw new Error(\"LCM emergency fallback provenance mismatch\");\n if (!persisted.text) throw new Error(\"LCM emergency fallback text is missing\");\n return {\n summary: persisted.text,\n firstKeptEntryId: input.firstKeptEntryId,\n tokensBefore: input.tokensBefore,\n source: \"emergency\",\n ...(instructionDetails ? { details: instructionDetails } : {}),\n };\n }\n const job = this.maintenance.jobForNode(leaf.nodeId);\n if (!job) throw new Error(\"LCM emergency fallback job was not created\");\n try {\n const completed = this.maintenance.completeEmergency(this.maintenance.claimEmergency(job.jobId), fallback);\n return {\n summary: completed.text ?? fallback,\n firstKeptEntryId: input.firstKeptEntryId,\n tokensBefore: input.tokensBefore,\n source: \"emergency\",\n ...(instructionDetails ? { details: instructionDetails } : {}),\n };\n } catch (error) {\n if (!isLcmRejection(error)) throw error;\n return {\n summary: fallback,\n firstKeptEntryId: input.firstKeptEntryId,\n tokensBefore: input.tokensBefore,\n source: \"emergency\",\n ...(instructionDetails ? { details: instructionDetails } : {}),\n };\n }\n }\n\n report(): LcmReport {\n const day = new Date(Date.now()).toISOString().slice(0, 10);\n const degraded = this.degradedMessage();\n const ledgerState = this.ledger.operationalState;\n return this.ledger.readOnly((db) => {\n const count = (sql: string, ...params: unknown[]): number =>\n Number((db.prepare(sql).get(...params) as { n: number }).n);\n const nodes = db.prepare(\"SELECT json_extract(payload,'$.kind') kind, json_extract(payload,'$.state') state, json_extract(payload,'$.modelHash') model, count(*) n FROM summary_nodes WHERE project_key=? GROUP BY kind, state, model\")\n .all(this.projectKey) as Array<{ kind: string; state: string; model: string; n: number }>;\n const usage = db.prepare(\"SELECT coalesce(sum(calls),0) calls, coalesce(sum(input_tokens),0) input, coalesce(sum(output_tokens),0) output, coalesce(sum(cost),0) cost, coalesce(sum(wall_ms),0) wallMs FROM maintenance_usage WHERE project_key=? AND day=?\")\n .get(this.projectKey, day) as { calls: number; input: number; output: number; cost: number; wallMs: number };\n const budget = this.maintenance.budgetPolicy();\n return {\n projectKey: this.projectKey,\n sessionId: this.activeSessionId,\n state: reconcileLcmState(ledgerState, degraded),\n ledgerState,\n degraded,\n summaryModel: this.options.summaryModel,\n rawEntries: count(\"SELECT count(*) n FROM raw_entries WHERE project_key=?\", this.projectKey),\n sessionEntries: this.activeSessionId === undefined ? 0 : count(\"SELECT count(*) n FROM raw_entries WHERE project_key=? AND session_id=?\", this.projectKey, this.activeSessionId),\n modelNodes: nodes.filter((row) => row.model && row.model !== \"emergency\").reduce((total, row) => total + row.n, 0),\n emergencyNodes: nodes.filter((row) => row.model === \"emergency\").reduce((total, row) => total + row.n, 0),\n pendingNodes: nodes.filter((row) => row.state !== \"ready\").reduce((total, row) => total + row.n, 0),\n pendingJobs: count(\"SELECT count(*) n FROM maintenance_jobs WHERE project_key=? AND status=?\", this.projectKey, \"pending\"),\n upgradableNodes: count(\"SELECT count(*) n FROM summary_nodes WHERE project_key=? AND json_extract(payload,'$.modelHash')=?\", this.projectKey, \"emergency\"),\n usage: { calls: usage.calls, inputTokens: usage.input, outputTokens: usage.output, cost: usage.cost, wallMs: usage.wallMs },\n budget: { calls: budget.calls, sessionCalls: budget.sessionCalls, wallMs: budget.wallMs },\n reconciliation: this.lastReconciliation,\n };\n });\n }\n\n private readonly repairLog: LcmRepairOutcome[] = [];\n\n private branchLength(): number {\n try { return this.context.sessionManager.getBranch().length; } catch { return 0; }\n }\n\n private sessionFile(): string | undefined {\n const getSessionFile = this.context.sessionManager.getSessionFile;\n if (typeof getSessionFile !== \"function\") return undefined;\n return getSessionFile.call(this.context.sessionManager) ?? undefined;\n }\n\n private sessionFilePresent(): boolean {\n const file = this.sessionFile();\n return file !== undefined && fs.existsSync(file);\n }\n\n private countJobs(state: \"pending\" | \"running\", since = 0): number {\n try { return this.maintenance.countJobs(state, since); } catch { return 0; }\n }\n\n diagnostics(report = this.report()): LcmDiagnostics {\n const coverage = this.coverage();\n const sessionFile = this.sessionFile();\n const sessionId = this.activeSessionId;\n let withinBudget = true;\n try { withinBudget = sessionId === undefined || this.maintenance.withinBudget(sessionId); } catch { withinBudget = true; }\n let expiredLeases = 0;\n try { expiredLeases = this.maintenance.expiredLeases(); } catch { expiredLeases = 0; }\n return {\n projectKey: this.projectKey,\n ledgerPath: this.ledger.file,\n ledgerBytes: this.ledger.bytes,\n ledgerState: report.ledgerState,\n runtimeError: this.degradedError === undefined\n ? undefined\n : String(this.degradedError instanceof Error ? this.degradedError.message : this.degradedError),\n sessionId,\n sessionFile,\n sessionFilePresent: this.sessionFilePresent(),\n liveBranchEntries: this.branchLength(),\n ledgerSessionEntries: report.sessionEntries,\n ledgerEntries: report.rawEntries,\n activeSources: coverage.active,\n coveredSources: coverage.covered,\n backlogThreshold: Math.max(1, this.options.maxLeafEntries ?? DEFAULT_LEAF_ENTRIES),\n pendingNodes: report.pendingNodes,\n pendingJobs: this.countJobs(\"pending\"),\n runningJobs: this.countJobs(\"running\"),\n failedJobs: this.recentlyFailedJobs(),\n expiredLeases,\n modelSummaries: this.options.modelSummaries !== false,\n summaryModel: this.options.summaryModel,\n budgetCalls: report.budget.calls,\n usedCalls: report.usage.calls,\n withinBudget,\n reconciliation: this.lastReconciliation\n ? {\n errors: this.lastReconciliation.errors,\n raced: this.lastReconciliation.raced,\n absent: this.lastReconciliation.absent,\n reasons: this.lastReconciliation.reasons,\n }\n : undefined,\n repairs: this.repairLog,\n autoRepairs: this.autoRepairState(),\n };\n }\n\n private autoRepairState(): LcmAutoRepair[] {\n try {\n return [...this.ledger.readRepairLadder()]\n .map(([fault, state]) => ({ fault, attempts: state.attempts, nextAt: state.nextAt, detail: state.detail }))\n .sort((left, right) => left.fault.localeCompare(right.fault));\n } catch {\n return [];\n }\n }\n\n get repairs(): readonly LcmRepairOutcome[] { return this.repairLog; }\n\n private record(id: LcmRepairId, changed: boolean, detail: string): LcmRepairOutcome {\n const outcome: LcmRepairOutcome = { id, changed, detail, at: Date.now() };\n this.repairLog.unshift(outcome);\n if (this.repairLog.length > MAX_REPAIR_LOG) this.repairLog.length = MAX_REPAIR_LOG;\n this.invalidateFrontier();\n return outcome;\n }\n\n /** Every repair is idempotent and reports the delta it caused. */\n async repair(id: LcmRepairId): Promise<LcmRepairOutcome> {\n if (this.closed) return this.record(id, false, \"the runtime is closed\");\n try {\n if (id === \"reconcile\") {\n await this.reconcileSelectedSession();\n const errors = this.lastReconciliation?.errors ?? 0;\n if (errors > 0) return this.record(id, false, `still ${errors} unreadable session file(s)`);\n const absent = this.lastReconciliation?.absent ?? 0;\n return this.record(id, absent === 0, absent > 0 ? \"session file is not on disk yet\" : \"session file re-read into the ledger\");\n }\n if (id === \"readback\") {\n const before = this.report().sessionEntries;\n this.degradedError = undefined;\n this.markDirty();\n await this.readback();\n const after = this.report().sessionEntries;\n return this.record(id, after !== before, `${after - before} entr${after - before === 1 ? \"y\" : \"ies\"} imported \u00B7 ${after} stored`);\n }\n if (id === \"leases\") {\n const swept = this.maintenance.sweepExpiredLeases().length;\n return this.record(id, swept > 0, `${swept} lease(s) released`);\n }\n const retried = this.maintenance.retryFailedJobs().length;\n if (retried > 0) this.scheduleMaintenance();\n return this.record(id, retried > 0, `${retried} job(s) requeued`);\n } catch (error) {\n return this.record(id, false, String(error instanceof Error ? error.message : error));\n }\n }\n\n private frontierCache: { at: number; sessionId: string; nodes: LcmNode[]; covered: Set<string> } | undefined;\n\n /** One frontier walk shared by preview, coverage, and the coverage map. */\n private frontierSnapshot(): { nodes: LcmNode[]; covered: Set<string> } {\n const sessionId = this.activeSessionId ?? \"\";\n const cached = this.frontierCache;\n if (cached && cached.sessionId === sessionId && Date.now() - cached.at < 250) {\n return { nodes: cached.nodes, covered: cached.covered };\n }\n const nodes = sessionId ? this.maintenance.getFrontier(sessionId, this.activeSources) : [];\n const covered = new Set(nodes.flatMap(node => node.sources.map(source => this.sourceKey(source))));\n this.frontierCache = { at: Date.now(), sessionId, nodes, covered };\n return { nodes, covered };\n }\n\n /** Content identity, so a fork keeps the summaries built over the entries it inherited. */\n private sourceKey(source: { entryId: string; payloadHash: string }): string {\n return `${source.entryId}:${source.payloadHash}`;\n }\n\n /** Assembles what a compaction would serve now. Reads only; it never persists a node. */\n preview(): LcmPreview {\n const sessionId = this.activeSessionId;\n if (!sessionId) return { text: \"\", nodes: 0, summaryBytes: 0, sourceBytes: 0, coveredSources: 0, activeSources: 0 };\n const { nodes, covered } = this.frontierSnapshot();\n const text = nodes.map(node => node.text ?? \"\").filter(Boolean).join(\"\\n\\n\");\n return {\n text,\n nodes: nodes.length,\n summaryBytes: Buffer.byteLength(text, \"utf8\"),\n sourceBytes: this.ledger.payloadBytes(this.projectKey, sessionId),\n coveredSources: covered.size,\n activeSources: this.activeSources.size,\n };\n }\n\n /** Ordered coverage of the active branch: each entry says whether a ready node holds it. */\n coverageMap(limit = 2_000): Array<{ key: string; covered: boolean }> {\n const sessionId = this.activeSessionId;\n if (!sessionId) return [];\n const { covered } = this.frontierSnapshot();\n return this.ledger.readRawKeys(this.projectKey, sessionId, limit)\n .map(entry => { const key = this.sourceKey({ entryId: entry.entryId, payloadHash: entry.contentHash }); return { key, covered: covered.has(key) }; });\n }\n\n jobs(limit = 64): LcmJob[] {\n try { return this.maintenance.recentJobs(limit); } catch { return []; }\n }\n\n nodes(limit = 200, offset = 0): LcmNode[] {\n return this.maintenance.listNodes(limit, offset);\n }\n\n node(nodeId: string): { node: LcmNode; revisions: ReturnType<LcmMaintenance[\"revisionsOf\"]>; ancestors: string[] } | undefined {\n const node = this.maintenance.getNode(nodeId);\n if (!node) return undefined;\n return { node, revisions: this.maintenance.revisionsOf(nodeId), ancestors: this.maintenance.ancestorsOf(nodeId) };\n }\n\n source(sessionId: string, entryId: string, revision: number): RawEntry | undefined {\n return this.ledger.readRawEntry(this.projectKey, sessionId, entryId, revision);\n }\n\n coverage(): { active: number; covered: number } {\n if (!this.activeSessionId) return { active: 0, covered: 0 };\n const { covered } = this.frontierSnapshot();\n let hits = 0;\n for (const key of this.activeSources) if (covered.has(key)) hits += 1;\n return { active: this.activeSources.size, covered: hits };\n }\n\n memoryContext() {\n return {\n ledger: {\n projectKey: this.projectKey,\n readRaw: (sessionId?: string) => this.ledger.readRaw(this.projectKey, sessionId),\n readRawPage: (sessionId?: string, offset?: number, limit?: number) => this.ledger.readRawPage(this.projectKey, sessionId, offset, limit),\n readRawEntry: (sessionId: string, entryId: string, revision: number) => this.ledger.readRawEntry(this.projectKey, sessionId, entryId, revision),\n searchRaw: (options: Parameters<LcmLedger[\"searchRaw\"]>[1]) => this.ledger.searchRaw(this.projectKey, options),\n },\n ...(this.activeSessionId === undefined ? {} : { currentSessionId: this.activeSessionId }),\n summaries: {\n listNodes: ({ sessionId, limit }: { sessionId?: string; limit: number }) => this.maintenance.getFrontier(sessionId, sessionId === this.activeSessionId ? this.activeSources : undefined).slice(0, limit).map((node) => ({ ...node, text: node.text ?? \"\", sources: node.sources.map((source) => ({ entryId: source.entryId, revision: source.revision, contentHash: source.payloadHash })) })),\n getNode: (nodeId: string) => {\n const node = this.maintenance.getNode(nodeId);\n return node ? { ...node, text: node.text ?? \"\", sources: node.sources.map((source) => ({ entryId: source.entryId, revision: source.revision, contentHash: source.payloadHash })) } : undefined;\n },\n },\n branchForSession: () => this.activeSessionId === undefined\n ? undefined\n : { activeSourceKeys: [...this.activeSources], ready: this.status === \"healthy\" },\n };\n }\n\n frontier(sessionId?: string) {\n return this.maintenance.getFrontier(sessionId, sessionId === this.activeSessionId ? this.activeSources : undefined);\n }\n\n raw(sessionId?: string): RawEntry[] { return this.ledger.readRaw(this.projectKey, sessionId); }\n\n /** Waits for writes, then gives aborted maintenance a bounded grace before detaching the ledger close. */\n async shutdown(): Promise<void> {\n if (this.closed) return;\n this.closed = true;\n this.abort.abort();\n await this.writePending.catch(() => undefined);\n const pending = this.maintenancePending.catch(() => undefined);\n const grace = new Promise<false>((resolve) => {\n const timer = setTimeout(() => resolve(false), SHUTDOWN_GRACE_MS);\n timer.unref?.();\n });\n if (await Promise.race([pending.then(() => true), grace])) {\n this.ledger.close();\n return;\n }\n void pending.then(() => {\n try { this.ledger.close(); } catch {}\n });\n }\n}\n", "import fs from \"node:fs\";\nimport path from \"node:path\";\nimport crypto from \"node:crypto\";\nimport { sqliteDriver, type SqliteDatabase } from \"./sqlite.js\";\nimport { stableProjectKey } from \"./lcm-directory.js\";\nimport { canonicalLcmPayload, canonicalProjectIdentity, createDeleteConfirmationToken, defaultLedgerPath, defaultLedgerRoot, hash, hashLcmPayload, type DeleteConfirmationToken, type ProjectIdentity, type ProjectIdentityInput, type RawEntry, type SessionEntry } from \"./lcm-identity.js\";\n\nexport { canonicalLcmPayload, canonicalProjectIdentity, createDeleteConfirmationToken, defaultLedgerPath, hashLcmPayload };\nexport type { DeleteConfirmationToken, ProjectIdentity, RawEntry, SessionEntry };\nconst LCM_LEDGER_WARNING_BYTES = 8 * 1024 ** 3;\nconst LCM_LEDGER_MAINTENANCE_BYTES = 10 * 1024 ** 3;\nexport interface LedgerOptions { dbPath?: string; rootDir?: string; project?: ProjectIdentityInput; projectKey?: string; now?: () => number; warningBytes?: number; maintenanceBytes?: number }\nexport type OperationalState = \"healthy\" | \"warning\" | \"maintenance\" | \"degraded\";\nexport interface CheckpointMetrics { mode: \"passive\" | \"truncate\"; busy: number; logPages: number; checkpointedPages: number; truncated: boolean }\nexport interface BackupManifest { format: \"lcm-ledger-backup\"; version: number; source: string; destination: string; sourceSha256: string; backupSha256: string; sourceStateSha256: string; rowCounts: Record<string, number>; integrity: \"ok\" | string; createdAt: number }\ntype LcmSearchMode = \"literal\" | \"phrase\" | \"regex\";\nexport interface LcmSearchOptions { sessionId?: string; query?: string; mode: LcmSearchMode; offset: number; limit: number; scanLimit?: number; match?: \"any\" | \"all\" }\nexport interface LcmSearchPage { rows: RawEntry[]; total: number; scanned: number; complete: boolean }\nexport interface DeleteManifest { format: \"lcm-ledger-delete\"; version: number; projectKey: string; deletedAt: number; integrity: string; remaining: number; remainingByTable: Record<string, number>; unattributed: number; unattributedByTable: Record<string, number> }\nexport interface LedgerMigrationReport { version: number; name: string; applied: boolean; reason?: string; counts: Record<string, number> }\nconst LEDGER_SCHEMA_VERSION = 4;\nconst BACKUP_MANIFEST_VERSION = 3;\nconst DELETE_MANIFEST_VERSION = 2;\nconst PROJECT_KEYED_TABLES = [\"projects\", \"project_aliases\", \"sessions\", \"raw_entries\", \"summary_nodes\", \"summary_node_revisions\", \"frontiers\", \"maintenance_jobs\", \"maintenance_usage\", \"repair_ladder\"] as const;\nconst LCM_SEARCH_SCAN_LIMIT = 5_000;\nconst LCM_SCAN_BATCH = 500;\n\nconst SCHEMA = `\nCREATE TABLE IF NOT EXISTS schema_metadata (key TEXT PRIMARY KEY, value TEXT NOT NULL);\nCREATE TABLE IF NOT EXISTS projects (project_key TEXT PRIMARY KEY, identity_json TEXT NOT NULL, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL);\nCREATE TABLE IF NOT EXISTS project_aliases (alias TEXT PRIMARY KEY, project_key TEXT NOT NULL REFERENCES projects(project_key));\nCREATE TABLE IF NOT EXISTS sessions (project_key TEXT NOT NULL, session_id TEXT NOT NULL, created_at INTEGER NOT NULL, PRIMARY KEY(project_key, session_id));\nCREATE TABLE IF NOT EXISTS raw_entries (project_key TEXT NOT NULL, session_id TEXT NOT NULL, entry_id TEXT NOT NULL, revision INTEGER NOT NULL, role TEXT NOT NULL, content TEXT NOT NULL, content_hash TEXT NOT NULL, payload_json TEXT NOT NULL, parent_entry_id TEXT, branch TEXT, created_at INTEGER NOT NULL, PRIMARY KEY(project_key, session_id, entry_id, revision), UNIQUE(project_key, session_id, entry_id, content_hash));\nCREATE TABLE IF NOT EXISTS summary_nodes (node_id TEXT PRIMARY KEY, project_key TEXT NOT NULL, payload TEXT NOT NULL, created_at INTEGER NOT NULL);\nCREATE TABLE IF NOT EXISTS summary_node_revisions (node_id TEXT NOT NULL REFERENCES summary_nodes(node_id), revision INTEGER NOT NULL, project_key TEXT NOT NULL, text TEXT NOT NULL, model_hash TEXT NOT NULL, created_at INTEGER NOT NULL, PRIMARY KEY(node_id, revision));\nCREATE TABLE IF NOT EXISTS summary_edges (parent_id TEXT NOT NULL REFERENCES summary_nodes(node_id), child_id TEXT NOT NULL REFERENCES summary_nodes(node_id), PRIMARY KEY(parent_id, child_id));\nCREATE TABLE IF NOT EXISTS frontiers (project_key TEXT NOT NULL, frontier_id TEXT NOT NULL, node_id TEXT NOT NULL, created_at INTEGER NOT NULL, PRIMARY KEY(project_key, frontier_id, node_id));\nCREATE TABLE IF NOT EXISTS maintenance_jobs (job_id TEXT PRIMARY KEY, project_key TEXT NOT NULL, status TEXT NOT NULL, payload TEXT NOT NULL, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL);\nCREATE TABLE IF NOT EXISTS maintenance_usage (project_key TEXT NOT NULL, day TEXT NOT NULL, session_id TEXT NOT NULL, calls INTEGER NOT NULL, input_tokens INTEGER NOT NULL, output_tokens INTEGER NOT NULL, cost REAL NOT NULL, wall_ms INTEGER NOT NULL, PRIMARY KEY(project_key,day,session_id));\nCREATE TABLE IF NOT EXISTS repair_ladder (project_key TEXT NOT NULL, fault TEXT NOT NULL, attempts INTEGER NOT NULL, next_at INTEGER NOT NULL, updated_at INTEGER NOT NULL, detail TEXT NOT NULL, PRIMARY KEY(project_key, fault));\nCREATE TABLE IF NOT EXISTS orphaned_rows (migration_version INTEGER NOT NULL, table_name TEXT NOT NULL, row_json TEXT NOT NULL, detected_at INTEGER NOT NULL);\nCREATE INDEX IF NOT EXISTS raw_entries_lookup ON raw_entries(project_key, session_id, entry_id, revision);\nDROP INDEX IF EXISTS raw_entries_recent;\nCREATE INDEX IF NOT EXISTS raw_entries_session_order ON raw_entries(project_key, session_id, created_at, revision);\nCREATE INDEX IF NOT EXISTS summary_nodes_order ON summary_nodes(project_key, created_at, node_id);\nCREATE INDEX IF NOT EXISTS maintenance_jobs_status ON maintenance_jobs(project_key, status);\nCREATE INDEX IF NOT EXISTS summary_edges_child ON summary_edges(child_id, parent_id);\n`;\n\nconst fileHash = (file: string) => crypto.createHash(\"sha256\").update(fs.readFileSync(file)).digest(\"hex\");\nconst snapshotHash = (db: SqliteDatabase): string => {\n const digest = crypto.createHash(\"sha256\");\n for (const [table, order] of [[\"schema_metadata\", \"key\"], [\"projects\", \"project_key\"], [\"project_aliases\", \"alias\"], [\"sessions\", \"project_key,session_id\"], [\"raw_entries\", \"project_key,session_id,entry_id,revision\"], [\"summary_nodes\", \"node_id\"], [\"summary_edges\", \"parent_id,child_id\"], [\"frontiers\", \"project_key,frontier_id,node_id\"], [\"maintenance_jobs\", \"job_id\"], [\"maintenance_usage\", \"project_key,day,session_id\"], [\"repair_ladder\", \"project_key,fault\"], [\"orphaned_rows\", \"migration_version,table_name,row_json\"]] as const) {\n digest.update(`${table}\\0`);\n for (const row of db.prepare(`SELECT * FROM ${table} ORDER BY ${order}`).all()) digest.update(`${JSON.stringify(row)}\\0`);\n }\n return digest.digest(\"hex\");\n};\n\nconst toRawEntry = (row: Record<string, unknown>): RawEntry => ({ projectKey: row.project_key as string, sessionId: row.session_id as string, entryId: row.entry_id as string, revision: Number(row.revision), role: row.role as string, content: row.content as string, contentHash: row.content_hash as string, payloadHash: row.content_hash as string, payloadJson: row.payload_json as string, parentEntryId: row.parent_entry_id as string | null, branch: row.branch as string | null, createdAt: row.created_at as number });\nconst toRawEntries = (rows: unknown[]): RawEntry[] => (rows as Array<Record<string, unknown>>).map(toRawEntry);\n\nconst probeFts5 = (db: SqliteDatabase): boolean => {\n try { db.exec(\"CREATE VIRTUAL TABLE temp.lcm_fts5_probe USING fts5(probe); DROP TABLE temp.lcm_fts5_probe;\"); return true; }\n catch { try { db.exec(\"DROP TABLE IF EXISTS temp.lcm_fts5_probe\"); } catch {} return false; }\n};\n\nconst foldToken = (value: string): string => value.normalize(\"NFD\").replace(/\\p{M}+/gu, \"\").toLowerCase();\nconst tokenize = (value: string): string[] => value.split(/[^\\p{L}\\p{N}]+/u).map(foldToken).filter(token => token.length > 0);\nconst searchPhrases = (query: string, mode: LcmSearchMode): string[][] =>\n (mode === \"phrase\" ? [query] : query.split(/\\s+/)).map(tokenize).filter(phrase => phrase.length > 0);\nconst ftsExpression = (phrases: string[][], match: \"any\" | \"all\"): string =>\n phrases.map(phrase => `\"${phrase.join(\" \")}\"`).join(match === \"all\" ? \" AND \" : \" OR \");\nconst containsPhrase = (tokens: string[], phrase: string[]): boolean => {\n for (let start = 0; start + phrase.length <= tokens.length; start++) {\n let hit = true;\n for (let offset = 0; offset < phrase.length; offset++) if (tokens[start + offset] !== phrase[offset]) { hit = false; break; }\n if (hit) return true;\n }\n return false;\n};\nconst phrasePredicate = (phrases: string[][], match: \"any\" | \"all\"): (content: string) => boolean =>\n match === \"all\"\n ? content => { const tokens = tokenize(content); return phrases.every(phrase => containsPhrase(tokens, phrase)); }\n : content => { const tokens = tokenize(content); return phrases.some(phrase => containsPhrase(tokens, phrase)); };\n\nclass LedgerDegradedError extends Error { constructor(message: string, public readonly cause?: unknown) { super(message); this.name = \"LedgerDegradedError\"; } }\n\nexport class LcmLedger {\n readonly db: SqliteDatabase;\n readonly project: ProjectIdentity;\n private degraded = false;\n private readonly dbPath: string;\n private readonly now: () => number;\n private readonly warningBytes: number;\n private readonly maintenanceBytes: number;\n private writeChain: Promise<void> = Promise.resolve();\n private transactionDepth = 0;\n private closed = false;\n private fts = false;\n readonly migrations: LedgerMigrationReport[] = [];\n constructor(options: LedgerOptions = {}) {\n this.now = options.now ?? Date.now;\n this.warningBytes = options.warningBytes ?? LCM_LEDGER_WARNING_BYTES;\n this.maintenanceBytes = options.maintenanceBytes ?? LCM_LEDGER_MAINTENANCE_BYTES;\n if (!Number.isSafeInteger(this.warningBytes) || !Number.isSafeInteger(this.maintenanceBytes) || this.warningBytes < 0 || this.maintenanceBytes < this.warningBytes) {\n throw new Error(\"invalid ledger size thresholds\");\n }\n const identity = canonicalProjectIdentity(options.project ?? { liveCwd: process.cwd() });\n const adopted = options.projectKey\n ?? (options.dbPath ? identity.key : stableProjectKey(options.rootDir ?? defaultLedgerRoot(), identity, this.now()));\n this.project = adopted === identity.key ? identity : { ...identity, key: adopted };\n const dbPath = options.dbPath ?? defaultLedgerPath(options.rootDir, this.project.key);\n fs.mkdirSync(path.dirname(dbPath), { recursive: true });\n this.dbPath = dbPath;\n this.db = new (sqliteDriver())(dbPath);\n try {\n this.db.exec(\"PRAGMA journal_mode=WAL; PRAGMA synchronous=FULL; PRAGMA busy_timeout=5000; PRAGMA wal_autocheckpoint=1000;\");\n this.db.exec(\"BEGIN IMMEDIATE;\" + SCHEMA + \"COMMIT;\");\n const columns = this.db.prepare(\"PRAGMA table_info(raw_entries)\").all() as Array<{ name: string }>;\n if (!columns.some(column => column.name === \"payload_json\")) {\n if (Number((this.db.prepare(\"SELECT count(*) n FROM raw_entries\").get() as { n: number }).n)) throw new Error(\"raw payloads missing; reimport authoritative session entries\");\n this.db.exec(\"ALTER TABLE raw_entries ADD COLUMN payload_json TEXT NOT NULL DEFAULT ''\");\n }\n this.fts = probeFts5(this.db);\n this.migrateSchema();\n this.db.exec(\"PRAGMA foreign_keys=ON\");\n const result = this.db.prepare(\"PRAGMA integrity_check\").get() as { integrity_check?: string };\n if (result.integrity_check !== \"ok\") throw new Error(String(result.integrity_check));\n this.registerProject(this.project);\n } catch (error) { this.degraded = true; throw new LedgerDegradedError(\"ledger startup failed\", error); }\n }\n readRepairLadder(projectKey = this.project.key): Map<string, { attempts: number; nextAt: number; detail: string; updatedAt: number }> {\n return this.readOnly(db => new Map((db.prepare(\"SELECT fault,attempts,next_at,detail,updated_at FROM repair_ladder WHERE project_key=?\").all(projectKey) as Array<{ fault: string; attempts: number; next_at: number; detail: string; updated_at: number }>).map(row => [row.fault, { attempts: Number(row.attempts), nextAt: Number(row.next_at), detail: row.detail, updatedAt: Number(row.updated_at) }])));\n }\n writeRepairLadder(fault: string, attempts: number, nextAt: number, detail: string): void {\n this.transaction(db => db.prepare(\"INSERT INTO repair_ladder(project_key,fault,attempts,next_at,updated_at,detail) VALUES(?,?,?,?,?,?) ON CONFLICT(project_key,fault) DO UPDATE SET attempts=excluded.attempts,next_at=excluded.next_at,updated_at=excluded.updated_at,detail=excluded.detail\").run(this.project.key, fault, attempts, nextAt, this.now(), detail));\n }\n clearRepairLadder(fault: string): void {\n this.transaction(db => db.prepare(\"DELETE FROM repair_ladder WHERE project_key=? AND fault=?\").run(this.project.key, fault));\n }\n get isDegraded() { return this.degraded; }\n get file(): string { return this.dbPath; }\n get bytes(): number { try { return fs.statSync(this.dbPath).size; } catch { return 0; } }\n get operationalState(): OperationalState {\n if (this.degraded) return \"degraded\";\n try { const size = fs.statSync(this.dbPath).size; if (size >= this.maintenanceBytes) return \"maintenance\"; if (size >= this.warningBytes) return \"warning\"; } catch {}\n return \"healthy\";\n }\n markDegraded(error?: unknown) { this.degraded = true; return new LedgerDegradedError(\"ledger is degraded\", error); }\n private registerProject(identity: ProjectIdentity) {\n const now = this.now();\n this.db.prepare(\"INSERT INTO projects(project_key,identity_json,created_at,updated_at) VALUES(?,?,?,?) ON CONFLICT(project_key) DO UPDATE SET identity_json=excluded.identity_json,updated_at=excluded.updated_at\").run(identity.key, JSON.stringify(identity), now, now);\n for (const alias of identity.aliases) {\n const existing = this.db.prepare(\"SELECT project_key FROM project_aliases WHERE alias=?\").get(alias) as { project_key?: string } | undefined;\n if (existing && existing.project_key !== identity.key) throw new LedgerDegradedError(`ambiguous project alias: ${alias}`);\n this.db.prepare(\"INSERT OR IGNORE INTO project_aliases(alias,project_key) VALUES(?,?)\").run(alias, identity.key);\n }\n }\n get ftsAvailable() { return this.fts; }\n private schemaVersion(): number {\n const row = this.db.prepare(\"SELECT value FROM schema_metadata WHERE key='version'\").get() as { value?: string } | undefined;\n const version = Number(row?.value ?? 0);\n return Number.isSafeInteger(version) && version > 0 ? version : 0;\n }\n private hasObject(type: string, name: string): boolean {\n return this.db.prepare(\"SELECT 1 FROM sqlite_master WHERE type=? AND name=?\").get(type, name) !== undefined;\n }\n private indexOutOfStep(): boolean {\n if (this.fts !== this.hasObject(\"table\", \"raw_entries_fts\")) return true;\n if (!this.fts) return false;\n if (!this.hasObject(\"trigger\", \"raw_entries_fts_insert\")) return true;\n return Number((this.db.prepare(\"SELECT count(*) n FROM raw_entries_fts\").get() as { n: number }).n) !== Number((this.db.prepare(\"SELECT count(*) n FROM raw_entries\").get() as { n: number }).n);\n }\n private migrateSchema(): void {\n const version = this.schemaVersion();\n if (version < 2 || this.indexOutOfStep()) this.migrations.push(this.migrateFullTextIndex());\n if (version < 3 || (this.db.prepare(\"PRAGMA foreign_key_list(summary_edges)\").all().length === 0)) this.migrations.push(this.migrateDerivedForeignKeys());\n if (version !== LEDGER_SCHEMA_VERSION) this.db.prepare(\"INSERT INTO schema_metadata(key,value) VALUES('version',?) ON CONFLICT(key) DO UPDATE SET value=excluded.value\").run(String(LEDGER_SCHEMA_VERSION));\n }\n private migrateFullTextIndex(): LedgerMigrationReport {\n if (!this.fts) {\n this.db.exec(\"DROP TRIGGER IF EXISTS raw_entries_fts_insert\");\n return { version: 2, name: \"raw-entries-fts\", applied: false, reason: \"sqlite driver has no fts5 module\", counts: { indexed: 0 } };\n }\n let indexed = 0;\n this.transaction(db => {\n db.exec(\"CREATE VIRTUAL TABLE IF NOT EXISTS raw_entries_fts USING fts5(content, project_key UNINDEXED, session_id UNINDEXED, entry_id UNINDEXED, revision UNINDEXED)\");\n db.exec(\"CREATE TRIGGER IF NOT EXISTS raw_entries_fts_insert AFTER INSERT ON raw_entries BEGIN INSERT INTO raw_entries_fts(content,project_key,session_id,entry_id,revision) VALUES(new.content,new.project_key,new.session_id,new.entry_id,new.revision); END\");\n indexed = Number((db.prepare(\"SELECT count(*) n FROM raw_entries\").get() as { n: number }).n);\n if (Number((db.prepare(\"SELECT count(*) n FROM raw_entries_fts\").get() as { n: number }).n) === indexed) return;\n db.exec(\"DELETE FROM raw_entries_fts\");\n db.exec(\"INSERT INTO raw_entries_fts(content,project_key,session_id,entry_id,revision) SELECT content,project_key,session_id,entry_id,revision FROM raw_entries\");\n });\n return { version: 2, name: \"raw-entries-fts\", applied: true, counts: { indexed } };\n }\n private migrateDerivedForeignKeys(): LedgerMigrationReport {\n const counts: Record<string, number> = { summary_edges: 0, summary_node_revisions: 0 };\n this.transaction(db => {\n const detectedAt = this.now();\n const known = \"(SELECT node_id FROM summary_nodes)\";\n const quarantine = (table: string, orphaned: string): void => {\n const rows = db.prepare(`SELECT * FROM ${table} WHERE ${orphaned}`).all() as Array<Record<string, unknown>>;\n for (const row of rows) db.prepare(\"INSERT INTO orphaned_rows(migration_version,table_name,row_json,detected_at) VALUES(?,?,?,?)\").run(LEDGER_SCHEMA_VERSION, table, JSON.stringify(row), detectedAt);\n counts[table] = rows.length;\n };\n quarantine(\"summary_edges\", `parent_id NOT IN ${known} OR child_id NOT IN ${known}`);\n db.exec(`CREATE TABLE summary_edges_next (parent_id TEXT NOT NULL REFERENCES summary_nodes(node_id), child_id TEXT NOT NULL REFERENCES summary_nodes(node_id), PRIMARY KEY(parent_id, child_id));\nINSERT INTO summary_edges_next(parent_id,child_id) SELECT parent_id,child_id FROM summary_edges WHERE parent_id IN ${known} AND child_id IN ${known};\nDROP TABLE summary_edges;\nALTER TABLE summary_edges_next RENAME TO summary_edges;`);\n quarantine(\"summary_node_revisions\", `node_id NOT IN ${known}`);\n db.exec(`CREATE TABLE summary_node_revisions_next (node_id TEXT NOT NULL REFERENCES summary_nodes(node_id), revision INTEGER NOT NULL, project_key TEXT NOT NULL, text TEXT NOT NULL, model_hash TEXT NOT NULL, created_at INTEGER NOT NULL, PRIMARY KEY(node_id, revision));\nINSERT INTO summary_node_revisions_next(node_id,revision,project_key,text,model_hash,created_at) SELECT node_id,revision,project_key,text,model_hash,created_at FROM summary_node_revisions WHERE node_id IN ${known};\nDROP TABLE summary_node_revisions;\nALTER TABLE summary_node_revisions_next RENAME TO summary_node_revisions;`);\n });\n return { version: 3, name: \"derived-foreign-keys\", applied: true, counts };\n }\n private guard() { if (this.degraded) throw new LedgerDegradedError(\"ledger is degraded\"); }\n private assertProjectKey(projectKey: string) { if (projectKey !== this.project.key) throw new Error(\"project key does not match ledger project\"); }\n async serialize<T>(operation: () => T): Promise<T> { const previous = this.writeChain; let release!: () => void; this.writeChain = new Promise<void>(resolve => { release = resolve }); await previous; try { this.guard(); return operation(); } finally { release(); } }\n appendRaw(entry: SessionEntry): RawEntry {\n this.guard();\n if (entry.projectKey !== this.project.key) throw new Error(\"entry project does not match ledger project\");\n if (entry.entryId.trim().length === 0) throw new Error(\"entry ID is required\");\n if (typeof entry.payloadJson !== \"string\" || !entry.payloadJson.trim()) throw new Error(\"full payload JSON is required\");\n let payload: Record<string, unknown>;\n try { payload = JSON.parse(entry.payloadJson) as Record<string, unknown>; } catch { throw new Error(\"invalid payload JSON\"); }\n if (!payload || typeof payload !== \"object\" || typeof payload.type !== \"string\" || typeof payload.id !== \"string\" || payload.id !== entry.entryId) throw new Error(\"payload must be a full SessionEntry\");\n const payloadJson = canonicalLcmPayload(payload);\n const contentHash = hashLcmPayload(payload);\n const ownsTransaction = this.transactionDepth === 0;\n if (ownsTransaction) this.db.exec(\"BEGIN IMMEDIATE\");\n try {\n const existing = this.db.prepare(\"SELECT revision,created_at FROM raw_entries WHERE project_key=? AND session_id=? AND entry_id=? AND content_hash=?\").get(entry.projectKey, entry.sessionId, entry.entryId, contentHash) as { revision: number; created_at: number } | undefined;\n if (existing) { if (ownsTransaction) this.db.exec(\"COMMIT\"); return { ...entry, payloadJson, payloadHash: contentHash, revision: existing.revision, contentHash, createdAt: existing.created_at }; }\n const latest = this.db.prepare(\"SELECT COALESCE(MAX(revision),0) revision FROM raw_entries WHERE project_key=? AND session_id=? AND entry_id=?\").get(entry.projectKey, entry.sessionId, entry.entryId) as { revision: number };\n const revision = latest.revision + 1; const createdAt = entry.createdAt ?? this.now();\n this.db.prepare(\"INSERT OR IGNORE INTO sessions(project_key,session_id,created_at) VALUES(?,?,?)\").run(entry.projectKey, entry.sessionId, createdAt);\n this.db.prepare(\"INSERT INTO raw_entries(project_key,session_id,entry_id,revision,role,content,content_hash,payload_json,parent_entry_id,branch,created_at) VALUES(?,?,?,?,?,?,?,?,?,?,?)\").run(entry.projectKey,entry.sessionId,entry.entryId,revision,entry.role,entry.content,contentHash,payloadJson,entry.parentEntryId ?? null,entry.branch ?? null,createdAt);\n if (ownsTransaction) this.db.exec(\"COMMIT\");\n return { ...entry, payloadJson, payloadHash: contentHash, revision, contentHash, createdAt };\n } catch (error) {\n if (ownsTransaction) this.db.exec(\"ROLLBACK\");\n const code = (error as NodeJS.ErrnoException).code; if (code === \"ENOSPC\" || code === \"SQLITE_FULL\" || String(error).includes(\"database or disk is full\")) this.degraded = true; throw new LedgerDegradedError(\"ledger write failed\", error);\n }\n }\n readRaw(projectKey = this.project.key, sessionId?: string): RawEntry[] { this.guard(); this.assertProjectKey(projectKey); const rows = sessionId ? this.db.prepare(\"SELECT * FROM raw_entries WHERE project_key=? AND session_id=? ORDER BY created_at,revision,rowid\").all(projectKey,sessionId) : this.db.prepare(\"SELECT * FROM raw_entries WHERE project_key=? ORDER BY created_at,session_id,entry_id,revision\").all(projectKey); return toRawEntries(rows); }\n readRawPage(projectKey = this.project.key, sessionId?: string, offset = 0, limit = 100): RawEntry[] { if (!Number.isSafeInteger(offset) || offset < 0 || !Number.isSafeInteger(limit) || limit < 1) throw new Error(\"invalid raw page\"); this.guard(); this.assertProjectKey(projectKey); const rows = sessionId ? this.db.prepare(\"SELECT * FROM raw_entries WHERE project_key=? AND session_id=? ORDER BY created_at,revision,rowid LIMIT ? OFFSET ?\").all(projectKey,sessionId,limit,offset) : this.db.prepare(\"SELECT * FROM raw_entries WHERE project_key=? ORDER BY created_at,session_id,entry_id,revision LIMIT ? OFFSET ?\").all(projectKey,limit,offset); return toRawEntries(rows); }\n readRawEntry(projectKey: string, sessionId: string, entryId: string, revision: number): RawEntry | undefined { this.guard(); this.assertProjectKey(projectKey); const row = this.db.prepare(\"SELECT * FROM raw_entries WHERE project_key=? AND session_id=? AND entry_id=? AND revision=?\").get(projectKey,sessionId,entryId,revision) as Record<string, unknown> | undefined; return row ? toRawEntry(row) : undefined; }\n searchRaw(projectKey: string | undefined, options: LcmSearchOptions): LcmSearchPage {\n this.guard();\n const key = projectKey ?? this.project.key;\n this.assertProjectKey(key);\n const { offset, limit, sessionId } = options;\n if (!Number.isSafeInteger(offset) || offset < 0 || !Number.isSafeInteger(limit) || limit < 1) throw new Error(\"invalid raw page\");\n const scanLimit = options.scanLimit ?? LCM_SEARCH_SCAN_LIMIT;\n if (!Number.isSafeInteger(scanLimit) || scanLimit < 1) throw new Error(\"invalid scan limit\");\n const query = options.query?.trim() ?? \"\";\n if (query.length === 0) return this.recentPage(key, sessionId, offset, limit);\n if (options.mode === \"regex\") {\n let pattern: RegExp;\n try { pattern = new RegExp(query, \"iu\"); } catch { return { rows: [], total: 0, scanned: 0, complete: false }; }\n return this.scanPage(key, sessionId, content => pattern.test(content), offset, limit, scanLimit, false);\n }\n const match = options.match ?? \"any\";\n const phrases = searchPhrases(query, options.mode);\n if (phrases.length === 0) return { rows: [], total: 0, scanned: 0, complete: true };\n if (this.fts) { try { return this.indexPage(key, sessionId, ftsExpression(phrases, match), offset, limit); } catch {} }\n return this.scanPage(key, sessionId, phrasePredicate(phrases, match), offset, limit, scanLimit, true);\n }\n private recentPage(key: string, sessionId: string | undefined, offset: number, limit: number): LcmSearchPage {\n const counted = (sessionId\n ? this.db.prepare(\"SELECT count(*) n FROM raw_entries WHERE project_key=? AND session_id=?\").get(key, sessionId)\n : this.db.prepare(\"SELECT count(*) n FROM raw_entries WHERE project_key=?\").get(key)) as { n: number };\n const total = Number(counted.n);\n const rows = sessionId\n ? this.db.prepare(\"SELECT * FROM raw_entries WHERE project_key=? AND session_id=? ORDER BY created_at DESC, revision DESC, rowid DESC LIMIT ? OFFSET ?\").all(key, sessionId, limit, offset)\n : this.db.prepare(\"SELECT * FROM raw_entries WHERE project_key=? ORDER BY created_at DESC, revision DESC, rowid DESC LIMIT ? OFFSET ?\").all(key, limit, offset);\n return { rows: toRawEntries(rows), total, scanned: total, complete: true };\n }\n private indexPage(key: string, sessionId: string | undefined, expression: string, offset: number, limit: number): LcmSearchPage {\n const source = \"FROM raw_entries_fts JOIN raw_entries r ON r.project_key=raw_entries_fts.project_key AND r.session_id=raw_entries_fts.session_id AND r.entry_id=raw_entries_fts.entry_id AND r.revision=CAST(raw_entries_fts.revision AS INTEGER) WHERE raw_entries_fts MATCH ? AND raw_entries_fts.project_key=?\" + (sessionId ? \" AND raw_entries_fts.session_id=?\" : \"\");\n const filters = sessionId ? [expression, key, sessionId] : [expression, key];\n const total = Number((this.db.prepare(`SELECT count(*) n ${source}`).get(...filters) as { n: number }).n);\n const rows = this.db.prepare(`SELECT r.* ${source} ORDER BY r.created_at DESC, r.revision DESC, r.rowid DESC LIMIT ? OFFSET ?`).all(...filters, limit, offset);\n return { rows: toRawEntries(rows), total, scanned: total, complete: true };\n }\n private scanPage(key: string, sessionId: string | undefined, matches: (content: string) => boolean, offset: number, limit: number, scanLimit: number, degraded: boolean): LcmSearchPage {\n const statement = sessionId\n ? this.db.prepare(\"SELECT session_id,entry_id,revision,content FROM raw_entries WHERE project_key=? AND session_id=? ORDER BY created_at DESC, revision DESC, rowid DESC LIMIT ? OFFSET ?\")\n : this.db.prepare(\"SELECT session_id,entry_id,revision,content FROM raw_entries WHERE project_key=? ORDER BY created_at DESC, revision DESC, rowid DESC LIMIT ? OFFSET ?\");\n const found: Array<{ sessionId: string; entryId: string; revision: number }> = [];\n let scanned = 0;\n let exhausted = false;\n while (scanned < scanLimit) {\n const size = Math.min(LCM_SCAN_BATCH, scanLimit - scanned);\n const batch = (sessionId ? statement.all(key, sessionId, size, scanned) : statement.all(key, size, scanned)) as Array<Record<string, unknown>>;\n scanned += batch.length;\n for (const row of batch) if (matches(row.content as string)) found.push({ sessionId: row.session_id as string, entryId: row.entry_id as string, revision: Number(row.revision) });\n if (batch.length < size) { exhausted = true; break; }\n }\n const rows: RawEntry[] = [];\n for (const identity of found.slice(offset, offset + limit)) {\n const entry = this.readRawEntry(key, identity.sessionId, identity.entryId, identity.revision);\n if (entry) rows.push(entry);\n }\n return { rows, total: found.length, scanned, complete: degraded ? false : exhausted };\n }\n /** Identity columns only, so a coverage scan never loads payloads. */\n readRawKeys(projectKey = this.project.key, sessionId?: string, limit = 100_000): Array<{ sessionId: string; entryId: string; revision: number; contentHash: string }> {\n this.guard(); this.assertProjectKey(projectKey);\n const rows = sessionId\n ? this.db.prepare(\"SELECT session_id, entry_id, revision, content_hash FROM raw_entries WHERE project_key=? AND session_id=? ORDER BY created_at,revision,rowid LIMIT ?\").all(projectKey, sessionId, limit)\n : this.db.prepare(\"SELECT session_id, entry_id, revision, content_hash FROM raw_entries WHERE project_key=? ORDER BY created_at,session_id,entry_id,revision LIMIT ?\").all(projectKey, limit);\n return (rows as Array<Record<string, unknown>>).map(row => ({ sessionId: row.session_id as string, entryId: row.entry_id as string, revision: Number(row.revision), contentHash: row.content_hash as string }));\n }\n /** Total stored payload bytes for one session, as a single aggregate. */\n payloadBytes(projectKey = this.project.key, sessionId?: string): number {\n this.guard(); this.assertProjectKey(projectKey);\n const row = sessionId\n ? this.db.prepare(\"SELECT coalesce(sum(length(payload_json)),0) n FROM raw_entries WHERE project_key=? AND session_id=?\").get(projectKey, sessionId)\n : this.db.prepare(\"SELECT coalesce(sum(length(payload_json)),0) n FROM raw_entries WHERE project_key=?\").get(projectKey);\n return Number((row as { n: number }).n);\n }\n readOnly<T>(fn: (db: SqliteDatabase) => T): T { this.guard(); return fn(this.db); }\n transaction<T>(fn: (db: SqliteDatabase) => T): T { this.guard(); if (this.transactionDepth > 0) return fn(this.db); this.db.exec(\"BEGIN IMMEDIATE\"); this.transactionDepth = 1; try { const result = fn(this.db); this.db.exec(\"COMMIT\"); return result; } catch (error) { this.db.exec(\"ROLLBACK\"); throw error; } finally { this.transactionDepth = 0; } }\n checkpoint(mode: \"passive\" | \"truncate\" = \"passive\"): CheckpointMetrics {\n const row = this.db.prepare(`PRAGMA wal_checkpoint(${mode.toUpperCase()})`).get() as { busy?: number; log?: number; checkpointed?: number };\n const busy = row.busy ?? 0;\n const logPages = row.log ?? 0;\n return { mode, busy, logPages, checkpointedPages: row.checkpointed ?? 0, truncated: mode === \"truncate\" && busy === 0 && logPages === 0 };\n }\n backup(destination: string): BackupManifest {\n this.guard();\n return this.serializeSync(() => {\n const target = path.resolve(destination);\n fs.mkdirSync(path.dirname(target), { recursive: true });\n if (fs.existsSync(target)) throw new Error(\"backup destination exists\");\n this.db.exec(`VACUUM INTO '${target.replace(/'/g, \"''\")}'`);\n fs.chmodSync(target, 0o600);\n const copy = new (sqliteDriver())(target);\n let integrity = \"unknown\";\n let backupStateSha256 = \"\";\n const rowCounts: Record<string, number> = {};\n try {\n integrity = (copy.prepare(\"PRAGMA integrity_check\").get() as { integrity_check?: string }).integrity_check ?? \"unknown\";\n for (const table of [\"projects\", \"sessions\", \"raw_entries\", \"summary_nodes\", \"summary_node_revisions\", \"summary_edges\", \"frontiers\", \"maintenance_jobs\", \"maintenance_usage\", \"repair_ladder\", \"orphaned_rows\"]) {\n rowCounts[table] = Number((copy.prepare(`SELECT count(*) n FROM ${table}`).get() as { n: number }).n);\n }\n backupStateSha256 = snapshotHash(copy);\n } finally {\n copy.close();\n }\n const manifest: BackupManifest = { format: \"lcm-ledger-backup\", version: BACKUP_MANIFEST_VERSION, source: this.dbPath, destination: target, sourceSha256: fileHash(this.dbPath), backupSha256: fileHash(target), sourceStateSha256: backupStateSha256, rowCounts, integrity, createdAt: this.now() };\n fs.writeFileSync(`${target}.manifest.json`, JSON.stringify(manifest), { mode: 0o600 });\n fs.chmodSync(`${target}.manifest.json`, 0o600);\n return manifest;\n });\n }\n exportBackup(destination: string): BackupManifest { return this.backup(destination); }\n private orphanOwner(db: SqliteDatabase, rowJson: string): string | undefined {\n let row: Record<string, unknown>;\n try { row = JSON.parse(rowJson) as Record<string, unknown>; } catch { return undefined; }\n if (typeof row.project_key === \"string\") return row.project_key;\n for (const column of [\"node_id\", \"parent_id\", \"child_id\"]) {\n const nodeId = row[column];\n if (typeof nodeId !== \"string\") continue;\n const owner = db.prepare(\"SELECT project_key FROM summary_nodes WHERE node_id=?\").get(nodeId) as { project_key?: string } | undefined;\n if (owner?.project_key !== undefined) return owner.project_key;\n }\n return undefined;\n }\n private projectFootprint(): { remaining: Record<string, number>; unattributed: Record<string, number> } {\n const key = this.project.key;\n const count = (sql: string, ...params: unknown[]): number => Number((this.db.prepare(sql).get(...params) as { n: number }).n);\n const remaining: Record<string, number> = {};\n for (const table of PROJECT_KEYED_TABLES) remaining[table] = count(`SELECT count(*) n FROM ${table} WHERE project_key=?`, key);\n remaining.summary_edges = count(\"SELECT count(*) n FROM summary_edges WHERE parent_id IN (SELECT node_id FROM summary_nodes WHERE project_key=?) OR child_id IN (SELECT node_id FROM summary_nodes WHERE project_key=?)\", key, key);\n if (this.fts) remaining.raw_entries_fts = count(\"SELECT count(*) n FROM raw_entries_fts WHERE project_key=?\", key);\n const unattributed: Record<string, number> = {};\n remaining.orphaned_rows = 0;\n for (const row of this.db.prepare(\"SELECT row_json FROM orphaned_rows\").all() as Array<{ row_json: string }>) {\n const owner = this.orphanOwner(this.db, row.row_json);\n if (owner === key) remaining.orphaned_rows++;\n else if (owner === undefined) unattributed.orphaned_rows = (unattributed.orphaned_rows ?? 0) + 1;\n }\n const dangling = count(\"SELECT count(*) n FROM summary_edges WHERE parent_id NOT IN (SELECT node_id FROM summary_nodes) OR child_id NOT IN (SELECT node_id FROM summary_nodes)\");\n if (dangling > 0) unattributed.summary_edges = dangling;\n return { remaining, unattributed };\n }\n deleteProject(token: DeleteConfirmationToken, backupManifest: BackupManifest): void {\n this.guard();\n if (token.__brand !== \"DeleteConfirmationToken\" || token.projectKey !== this.project.key || token.value !== hash(`delete:${this.project.key}`)) throw new Error(\"invalid delete confirmation token\");\n if (backupManifest.version !== BACKUP_MANIFEST_VERSION) throw new Error(`backup manifest version ${backupManifest.version} predates this ledger (expected ${BACKUP_MANIFEST_VERSION}); take a fresh backup`);\n const backupDb = fs.existsSync(backupManifest.destination) ? new (sqliteDriver())(backupManifest.destination) : undefined;\n let backupStateSha256: string | undefined;\n try {\n if (backupDb) backupStateSha256 = snapshotHash(backupDb);\n } finally {\n backupDb?.close();\n }\n if (backupManifest.integrity !== \"ok\" || backupManifest.source !== this.dbPath || !backupManifest.backupSha256 || backupManifest.backupSha256 !== fileHash(backupManifest.destination) || !backupManifest.sourceStateSha256 || backupManifest.sourceStateSha256 !== backupStateSha256 || backupManifest.sourceSha256 !== fileHash(this.dbPath) || backupManifest.sourceStateSha256 !== snapshotHash(this.db)) throw new Error(\"backup verification failed\");\n this.transaction(db => {\n const purge = db.prepare(\"DELETE FROM orphaned_rows WHERE rowid=?\");\n for (const row of db.prepare(\"SELECT rowid AS id, row_json FROM orphaned_rows\").all() as Array<{ id: number; row_json: string }>) {\n if (this.orphanOwner(db, row.row_json) === this.project.key) purge.run(row.id);\n }\n db.prepare(\"DELETE FROM summary_edges WHERE parent_id IN (SELECT node_id FROM summary_nodes WHERE project_key=?) OR child_id IN (SELECT node_id FROM summary_nodes WHERE project_key=?)\").run(this.project.key, this.project.key);\n for (const table of [\"raw_entries\", \"sessions\", \"frontiers\", \"summary_node_revisions\", \"summary_nodes\", \"maintenance_jobs\", \"maintenance_usage\", \"repair_ladder\"]) db.prepare(`DELETE FROM ${table} WHERE project_key=?`).run(this.project.key);\n if (this.fts) db.prepare(\"DELETE FROM raw_entries_fts WHERE project_key=?\").run(this.project.key);\n db.prepare(\"DELETE FROM project_aliases WHERE project_key=?\").run(this.project.key);\n db.prepare(\"DELETE FROM projects WHERE project_key=?\").run(this.project.key);\n });\n const integrity = (this.db.prepare(\"PRAGMA integrity_check\").get() as { integrity_check?: string }).integrity_check;\n if (integrity !== \"ok\") throw new Error(`post-delete integrity failed: ${integrity}`);\n const footprint = this.projectFootprint();\n const total = (counts: Record<string, number>): number => Object.values(counts).reduce((sum, value) => sum + value, 0);\n const audit: DeleteManifest = { format: \"lcm-ledger-delete\", version: DELETE_MANIFEST_VERSION, projectKey: this.project.key, deletedAt: this.now(), integrity, remaining: total(footprint.remaining), remainingByTable: footprint.remaining, unattributed: total(footprint.unattributed), unattributedByTable: footprint.unattributed };\n fs.writeFileSync(`${backupManifest.destination}.delete-manifest.json`, JSON.stringify(audit), { mode: 0o600 });\n }\n private serializeSync<T>(operation: () => T): T { this.guard(); return operation(); }\n close() { if (this.closed) return; this.db.close(); this.closed = true; }\n}\n", "import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { writeJsonAtomic } from \"../core/atomic-write.js\";\nimport { defaultLedgerPath, type ProjectIdentity } from \"./lcm-identity.js\";\n\nconst DIRECTORY_FILE = \"projects.json\";\nconst DIRECTORY_VERSION = 1;\nconst SWEEP_INTERVAL_MS = 24 * 60 * 60 * 1_000;\nconst RETENTION_MS = 30 * 24 * 60 * 60 * 1_000;\n\ninterface LcmDirectoryRecord {\n key: string;\n path: string;\n updatedAt: number;\n}\n\ninterface LcmDirectoryFile {\n version: number;\n sweptAt: number;\n projects: LcmDirectoryRecord[];\n}\n\nexport interface LcmSweepResult {\n removed: string[];\n bytes: number;\n skipped: boolean;\n}\n\nconst empty = (): LcmDirectoryFile => ({ version: DIRECTORY_VERSION, sweptAt: 0, projects: [] });\n\nconst directoryFile = (rootDir: string): string => path.join(rootDir, DIRECTORY_FILE);\n\nconst read = (rootDir: string): LcmDirectoryFile => {\n try {\n const parsed = JSON.parse(fs.readFileSync(directoryFile(rootDir), \"utf8\")) as Partial<LcmDirectoryFile>;\n if (parsed.version !== DIRECTORY_VERSION || !Array.isArray(parsed.projects)) return empty();\n return {\n version: DIRECTORY_VERSION,\n sweptAt: typeof parsed.sweptAt === \"number\" ? parsed.sweptAt : 0,\n projects: parsed.projects.filter(\n (record): record is LcmDirectoryRecord =>\n typeof record?.key === \"string\" && typeof record.path === \"string\" && typeof record.updatedAt === \"number\",\n ),\n };\n } catch {\n return empty();\n }\n};\n\n/** Merges against the file on disk so a concurrent instance never loses its record. */\nconst write = (rootDir: string, file: LcmDirectoryFile, owned: readonly string[]): void => {\n try {\n fs.mkdirSync(rootDir, { recursive: true });\n const current = read(rootDir);\n const merged = new Map(current.projects.map((record) => [record.path, record] as const));\n for (const path of owned) merged.delete(path);\n for (const record of file.projects) merged.set(record.path, record);\n writeJsonAtomic(directoryFile(rootDir), {\n version: DIRECTORY_VERSION,\n sweptAt: Math.max(file.sweptAt, current.sweptAt),\n projects: [...merged.values()],\n });\n } catch {}\n};\n\nconst ledgerFiles = (key: string, rootDir: string): string[] => {\n const base = defaultLedgerPath(rootDir, key);\n return [base, `${base}-wal`, `${base}-shm`];\n};\n\n/** Remembers the key a canonical path was first filed under, so history follows the path across inode changes. */\nexport const stableProjectKey = (rootDir: string, identity: ProjectIdentity, now = Date.now()): string => {\n const canonicalPath = identity.canonicalPath;\n if (!canonicalPath) return identity.key;\n const file = read(rootDir);\n const record = file.projects.find((candidate) => candidate.path === canonicalPath);\n const adopted = record && record.key !== identity.key && fs.existsSync(defaultLedgerPath(rootDir, record.key))\n ? record.key\n : identity.key;\n write(rootDir, { ...file, projects: [{ key: adopted, path: canonicalPath, updatedAt: now }] }, [canonicalPath]);\n return adopted;\n};\n\n/** Removes ledgers whose project directory is gone and that nothing wrote for the retention window. */\nexport const sweepLedgers = (\n rootDir: string,\n options: { keepKey: string; now?: number; retentionMs?: number; force?: boolean },\n): LcmSweepResult => {\n const now = options.now ?? Date.now();\n const retentionMs = options.retentionMs ?? RETENTION_MS;\n const file = read(rootDir);\n if (!options.force && now - file.sweptAt < SWEEP_INTERVAL_MS) return { removed: [], bytes: 0, skipped: true };\n const removed: string[] = [];\n let bytes = 0;\n const kept: LcmDirectoryRecord[] = [];\n for (const record of file.projects) {\n const ledger = defaultLedgerPath(rootDir, record.key);\n let stats: fs.Stats | undefined;\n try {\n stats = fs.statSync(ledger);\n } catch {\n continue;\n }\n const abandoned =\n record.key !== options.keepKey &&\n !fs.existsSync(record.path) &&\n now - Math.max(stats.mtimeMs, record.updatedAt) >= retentionMs;\n if (!abandoned) {\n kept.push(record);\n continue;\n }\n try {\n for (const target of ledgerFiles(record.key, rootDir)) fs.rmSync(target, { force: true });\n } catch {\n kept.push(record);\n continue;\n }\n bytes += stats.size;\n removed.push(record.path);\n }\n write(rootDir, { ...file, sweptAt: now, projects: kept }, file.projects.map((record) => record.path));\n return { removed, bytes, skipped: false };\n};\n", "import crypto from \"node:crypto\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { sqliteDriver, type SqliteDatabase } from \"./sqlite.js\";\nimport { sessionsDirRoot, sessionDirNamesForCwd } from \"../memory/discovery.js\";\nimport { canonicalLcmPayload, canonicalProjectIdentity, defaultLedgerPath, hashLcmPayload, LcmLedger } from \"./lcm-ledger.js\";\n\nexport interface MigrationOptions {\n agentDir: string;\n ledgerRoot?: string;\n ledger?: LcmLedger;\n files?: string[];\n candidateDirs?: string[];\n projectCwd?: string;\n liveCwd?: string;\n since?: string;\n until?: string;\n onDemand?: boolean;\n now?: number;\n apply?: boolean;\n allowIncompleteDiscovery?: boolean;\n maxFiles?: number;\n maxDiscoveryEntries?: number;\n maxFileBytes?: number;\n maxLineBytes?: number;\n maxTotalBytes?: number;\n onProgress?: (progress: MigrationProgress) => void;\n}\ninterface MigrationProgress {\n projectKey: string;\n sessionPath: string;\n sourceHash: string;\n lineOrdinal: number;\n entryId: string;\n contentHash: string;\n}\ninterface MigrationCounts {\n eligible: number;\n imported: number;\n skippedDuplicate: number;\n skippedOutOfWindow: number;\n malformed: number;\n oversized: number;\n absent: number;\n incompleteDiscovery: number;\n raced: number;\n errors: number;\n}\nexport interface MigrationDrops {\n oversizedFiles: number;\n oversizedFileBytes: number;\n oversizedLines: number;\n oversizedLineBytes: number;\n skippedFiles: number;\n entries: number;\n}\nconst plural = (count: number, noun: string): string => `${count} ${noun}${count === 1 ? \"\" : \"s\"}`;\nconst megabytes = (bytes: number): string => `${(bytes / 1024 ** 2).toFixed(1)} MB`;\n/** One sentence per non-empty drop category; empty when nothing was dropped. */\nexport const migrationDropReasons = (drops: MigrationDrops): string[] => {\n const reasons: string[] = [];\n if (drops.oversizedFiles > 0) reasons.push(`${plural(drops.oversizedFiles, \"session file\")} skipped as oversized (${megabytes(drops.oversizedFileBytes)})`);\n if (drops.oversizedLines > 0) reasons.push(`${plural(drops.oversizedLines, \"line\")} skipped as oversized (${megabytes(drops.oversizedLineBytes)})`);\n if (drops.skippedFiles > 0) reasons.push(`${plural(drops.skippedFiles, \"session file\")} skipped after the total scan budget`);\n return reasons;\n};\nexport interface MigrationResult {\n mode: \"apply\" | \"dry-run\";\n since: string;\n until: string;\n counts: MigrationCounts;\n drops: MigrationDrops;\n degraded: boolean;\n filesScanned: number;\n bytesScanned: number;\n generations: Array<{ sessionPath: string; sourceHash: string }>;\n exitCode: number;\n}\nconst hash = (data: string | Buffer): string => crypto.createHash(\"sha256\").update(data).digest(\"hex\");\nconst record = (value: unknown): Record<string, unknown> | undefined =>\n value !== null && typeof value === \"object\" && !Array.isArray(value) ? value as Record<string, unknown> : undefined;\nconst nonblank = (value: unknown): value is string => typeof value === \"string\" && value.trim().length > 0;\n/** Session JSONL is append-only, so a longer file is the live session growing. */\nexport const sourceStillValid = (before: number, after: number): boolean => after >= before;\nconst SOURCE_READ_ATTEMPTS = 3;\nclass SourceChangedError extends Error {}\ntype SourceRead =\n | { kind: \"data\"; raced: number; data: Buffer }\n | { kind: \"absent\"; raced: number }\n | { kind: \"not-file\"; raced: number }\n | { kind: \"oversized\"; raced: number; size: number }\n | { kind: \"over-budget\"; raced: number }\n | { kind: \"raced\"; raced: number }\n | { kind: \"error\"; raced: number };\nconst readSource = (file: string, maxFileBytes: number, remainingBytes: number): SourceRead => {\n let raced = 0;\n for (let attempt = 0; attempt < SOURCE_READ_ATTEMPTS; attempt += 1) {\n let fd: number | undefined;\n try {\n fd = fs.openSync(file, \"r\");\n const before = fs.fstatSync(fd);\n if (!before.isFile()) return { kind: \"not-file\", raced };\n if (before.size > maxFileBytes) return { kind: \"oversized\", raced, size: before.size };\n if (before.size > remainingBytes) return { kind: \"over-budget\", raced };\n const data = Buffer.allocUnsafe(before.size);\n let offset = 0;\n while (offset < data.length) {\n const size = fs.readSync(fd, data, offset, data.length - offset, offset);\n if (size === 0) throw new SourceChangedError(\"source shortened during read\");\n offset += size;\n }\n if (!sourceStillValid(before.size, fs.fstatSync(fd).size)) throw new SourceChangedError(\"source shrank during read\");\n return { kind: \"data\", raced, data };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return { kind: \"absent\", raced };\n if (!(error instanceof SourceChangedError)) return { kind: \"error\", raced };\n raced += 1;\n } finally { if (fd !== undefined) fs.closeSync(fd); }\n }\n return { kind: \"raced\", raced };\n};\nconst utc = (value: string): number => {\n if (!/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{1,3})?(?:Z|\\+00:00)$/.test(value)) throw new Error(\"timestamps must be explicit UTC ISO-8601 values\");\n const at = Date.parse(value);\n const normalized = value.replace(\"+00:00\", \"Z\").replace(/Z$/, \"\");\n if (!Number.isFinite(at) || new Date(at).toISOString().slice(0, 19) !== normalized.slice(0, 19)) throw new Error(\"invalid UTC timestamp\");\n return at;\n};\nexport function migrationWindow(options: Pick<MigrationOptions, \"since\" | \"until\" | \"now\">): { since: number; until: number } {\n const now = options.now ?? Date.now();\n const since = options.since === undefined ? now - 72 * 60 * 60 * 1000 : utc(options.since);\n const until = options.until === undefined ? now : utc(options.until);\n if (!Number.isFinite(since) || !Number.isFinite(until) || since > until) throw new Error(\"invalid migration window\");\n return { since, until };\n}\nconst positive = (value: number | undefined, fallback: number): number => {\n const result = value ?? fallback;\n if (!Number.isSafeInteger(result) || result < 1) throw new Error(\"scan limits must be positive safe integers\");\n return result;\n};\nexport function discoverMigrationSessions(options: MigrationOptions): { files: string[]; incomplete: number } {\n const maxFiles = positive(options.maxFiles, 10_000);\n const maxEntries = positive(options.maxDiscoveryEntries, 100_000);\n const files = new Set<string>();\n let incomplete = 0;\n let entries = 0;\n const add = (file: string): void => {\n if (files.size >= maxFiles && !files.has(path.resolve(file))) { incomplete++; return; }\n files.add(path.resolve(file));\n };\n if (options.files) {\n for (const file of options.files.slice(0, maxFiles)) add(file);\n if (options.files.length > maxFiles) incomplete++;\n return { files: [...files].sort(), incomplete };\n }\n const list = (dir: string, visit: (entry: fs.Dirent) => void): void => {\n let handle: fs.Dir | undefined;\n try {\n handle = fs.opendirSync(dir);\n let entry: fs.Dirent | null;\n while ((entry = handle.readSync()) !== null) {\n if (++entries > maxEntries) { incomplete++; break; }\n visit(entry);\n }\n } catch { incomplete++; } finally { handle?.closeSync(); }\n };\n const scan = (dir: string): void => list(dir, entry => {\n if (entry.isFile() && entry.name.endsWith(\".jsonl\")) add(path.join(dir, entry.name));\n else if (entry.isSymbolicLink() && entry.name.endsWith(\".jsonl\")) incomplete++;\n });\n if (options.candidateDirs) {\n for (const dir of options.candidateDirs) { if (entries >= maxEntries) { incomplete++; break; } scan(dir); }\n } else if (options.projectCwd) {\n const names = sessionDirNamesForCwd(options.projectCwd);\n let found = false;\n for (const name of [names.canonical, ...names.legacy]) {\n const dir = path.join(sessionsDirRoot(options.agentDir), name);\n try { if (fs.statSync(dir).isDirectory()) { found = true; scan(dir); } }\n catch (error) { if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") incomplete++; }\n }\n if (!found) incomplete++;\n } else {\n const root = sessionsDirRoot(options.agentDir);\n list(root, entry => {\n if (entry.isDirectory()) scan(path.join(root, entry.name));\n else if (entry.isFile() && entry.name.endsWith(\".jsonl\")) add(path.join(root, entry.name));\n else if (entry.isSymbolicLink()) incomplete++;\n });\n }\n return { files: [...files].sort(), incomplete };\n}\nconst CHECKPOINT_SCHEMA = \"CREATE TABLE IF NOT EXISTS migration_checkpoints (project_key TEXT NOT NULL, session_path TEXT NOT NULL, source_hash TEXT NOT NULL, line_ordinal INTEGER NOT NULL, entry_id TEXT NOT NULL, content_hash TEXT NOT NULL, PRIMARY KEY(project_key,session_path,source_hash,line_ordinal,entry_id,content_hash))\";\nexport function reconcileSession(options: Omit<MigrationOptions, \"files\"> & { files: [string] }): MigrationResult {\n return migrateSessions({ ...options, onDemand: true });\n}\n\nexport function migrateSessions(options: MigrationOptions): MigrationResult {\n const window = migrationWindow(options);\n const maxFileBytes = positive(options.maxFileBytes, 64 * 1024 ** 2);\n const maxLineBytes = positive(options.maxLineBytes, 8 * 1024 ** 2);\n const maxTotalBytes = positive(options.maxTotalBytes, 1024 ** 3);\n const discovery = discoverMigrationSessions(options);\n const result: MigrationResult = {\n mode: options.apply ? \"apply\" : \"dry-run\", since: new Date(window.since).toISOString(), until: new Date(window.until).toISOString(),\n counts: { eligible: 0, imported: 0, skippedDuplicate: 0, skippedOutOfWindow: 0, malformed: 0, oversized: 0, absent: 0, incompleteDiscovery: discovery.incomplete, raced: 0, errors: 0 },\n drops: { oversizedFiles: 0, oversizedFileBytes: 0, oversizedLines: 0, oversizedLineBytes: 0, skippedFiles: 0, entries: 0 },\n degraded: false,\n filesScanned: 0, bytesScanned: 0, generations: [], exitCode: 0,\n };\n const counts = result.counts;\n const drops = result.drops;\n const drySeen = new Set<string>();\n files: for (const [position, file] of discovery.files.entries()) {\n const read = readSource(file, maxFileBytes, maxTotalBytes - result.bytesScanned);\n counts.raced += read.raced;\n if (read.kind !== \"data\") {\n switch (read.kind) {\n case \"absent\": counts.absent++; counts.incompleteDiscovery++; break;\n case \"not-file\": counts.incompleteDiscovery++; break;\n case \"oversized\": counts.oversized++; drops.oversizedFiles++; drops.oversizedFileBytes += read.size; break;\n case \"over-budget\": counts.incompleteDiscovery++; drops.skippedFiles += discovery.files.length - position; break files;\n case \"raced\": counts.incompleteDiscovery++; break;\n default: counts.errors++; counts.incompleteDiscovery++;\n }\n continue;\n }\n const data = read.data;\n result.filesScanned++;\n result.bytesScanned += data.length;\n const sourceHash = hash(data);\n result.generations.push({ sessionPath: file, sourceHash });\n let header: Record<string, unknown> | undefined;\n let ledger: LcmLedger | undefined;\n let database: SqliteDatabase | undefined;\n let sessionId = \"\";\n let projectKey = \"\";\n let cwd: string | undefined;\n let ordinal = 0;\n try {\n for (let start = 0; start < data.length;) {\n ordinal++;\n const newline = data.indexOf(10, start);\n const end = newline < 0 ? data.length : newline;\n const bytes = data.subarray(start, end);\n start = newline < 0 ? data.length : end + 1;\n if (bytes.length > maxLineBytes) { counts.oversized++; drops.oversizedLines++; drops.oversizedLineBytes += bytes.length; drops.entries++; continue; }\n const content = bytes.toString(\"utf8\").replace(/\\r$/, \"\");\n if (!content.trim()) continue;\n let row: Record<string, unknown> | undefined;\n try { row = record(JSON.parse(content)); } catch { counts.malformed++; continue; }\n if (!row) { counts.malformed++; continue; }\n if (row.type === \"message_end\") continue;\n if (!header) {\n if (row.type !== \"session\") { if (record(row.message)) counts.malformed++; continue; }\n if (!nonblank(row.id)) { counts.malformed++; break; }\n header = row;\n sessionId = row.id;\n cwd = nonblank(row.cwd) ? row.cwd : options.liveCwd;\n if (!cwd) { counts.malformed++; break; }\n const projectInput = options.liveCwd ? { recordedCwd: cwd, liveCwd: options.liveCwd } : { recordedCwd: cwd };\n projectKey = canonicalProjectIdentity(projectInput).key;\n if (options.ledger && options.ledger.project.key !== projectKey) { counts.errors++; break; }\n if (options.apply) {\n if (options.ledger) ledger = options.ledger;\n else if (options.ledgerRoot) ledger = new LcmLedger({ rootDir: options.ledgerRoot, project: { recordedCwd: cwd } });\n else ledger = new LcmLedger({ project: { recordedCwd: cwd } });\n database = ledger.db;\n database.exec(CHECKPOINT_SCHEMA);\n } else if (options.ledger) database = options.ledger.db;\n else {\n const dbPath = defaultLedgerPath(options.ledgerRoot, projectKey);\n if (fs.existsSync(dbPath)) database = new (sqliteDriver())(dbPath, { readOnly: true });\n }\n continue;\n }\n if (row.type === \"session\" || !nonblank(row.type) || !nonblank(row.id) || (row.parentId !== null && row.parentId !== undefined && typeof row.parentId !== \"string\")) { counts.malformed++; continue; }\n const message = record(row.message);\n if (row.type === \"message\" && (!message || !nonblank(message.role))) { counts.malformed++; continue; }\n let at: number;\n try { at = typeof row.timestamp === \"string\" ? utc(row.timestamp) : NaN; } catch { at = NaN; }\n if (!Number.isFinite(at)) { counts.malformed++; continue; }\n if (!options.onDemand && (at < window.since || at > window.until)) { counts.skippedOutOfWindow++; continue; }\n counts.eligible++;\n const payloadJson = canonicalLcmPayload(row);\n const contentHash = hashLcmPayload(row);\n const identity = JSON.stringify([projectKey, sessionId, row.id, contentHash]);\n const progress: MigrationProgress = { projectKey, sessionPath: file, sourceHash, lineOrdinal: ordinal, entryId: row.id, contentHash };\n const duplicate = drySeen.has(identity) || database?.prepare(\"SELECT 1 FROM raw_entries WHERE project_key=? AND session_id=? AND entry_id=? AND content_hash=?\").get(projectKey, sessionId, row.id, contentHash) !== undefined;\n if (duplicate) counts.skippedDuplicate++;\n else if (ledger) {\n ledger.appendRaw({\n projectKey, sessionId, entryId: row.id, role: message && typeof message.role === \"string\" ? message.role : row.type,\n content, payloadJson, parentEntryId: typeof row.parentId === \"string\" ? row.parentId : null,\n branch: typeof row.branch === \"string\" ? row.branch : typeof row.branchId === \"string\" ? row.branchId : null,\n ...(cwd ? { recordedCwd: cwd } : {}), createdAt: at\n });\n counts.imported++;\n }\n else if (!duplicate) counts.imported++;\n drySeen.add(identity);\n if (ledger) database!.prepare(\"INSERT OR IGNORE INTO migration_checkpoints(project_key,session_path,source_hash,line_ordinal,entry_id,content_hash) VALUES(?,?,?,?,?,?)\")\n .run(projectKey, file, sourceHash, ordinal, row.id, contentHash);\n options.onProgress?.(progress);\n }\n if (!header) counts.malformed++;\n } catch (error) {\n counts.errors++;\n if (options.onProgress) throw error;\n } finally {\n if (ledger && ledger !== options.ledger) ledger.close();\n else if (!ledger && database && database !== options.ledger?.db) database.close();\n }\n }\n result.degraded = drops.entries > 0 || drops.oversizedFiles > 0 || drops.skippedFiles > 0;\n result.exitCode = counts.errors || counts.malformed || counts.oversized || (counts.incompleteDiscovery && !options.allowIncompleteDiscovery) ? 1 : 0;\n return result;\n}\n", "import crypto from \"node:crypto\";\nimport { hashLcmPayload, type RawEntry } from \"../storage/lcm-identity.js\";\nimport type { LcmLedger } from \"../storage/lcm-ledger.js\";\nimport type { SqliteDatabase } from \"../storage/sqlite.js\";\nimport { utf8Bytes } from \"./bounds.js\";\nimport { buildLcmPrompt, emergencyReduce, type LcmModelResult, type LcmPromptMode, type LcmSummarizer } from \"./lcm-model.js\";\n\ntype LcmNodeState = \"pending\" | \"ready\" | \"running\" | \"failed\";\ntype LcmJobState = \"pending\" | \"running\" | \"completed\" | \"failed\";\nexport interface LcmSourceRef { sessionId: string; entryId: string; revision: number; payloadHash: string; }\ntype RawSourceRef = LcmSourceRef;\nexport interface LcmNode { nodeId: string; projectKey: string; sessionId: string; kind: \"leaf\" | \"condensed\"; sources: LcmSourceRef[]; children: string[]; depth: number; sourceHash: string; policyHash: string; modelHash: string; state: LcmNodeState; text?: string; createdAt: number; }\nexport interface LcmJob { jobId: string; projectKey: string; nodeId: string; priority: number; eligibleAt: number; state: LcmJobState; ownerId?: string; leaseToken?: string; leaseUntil?: number; attempts: number; nextRetryAt: number; error?: string; legacyRecovery?: true; createdAt: number; updatedAt: number; }\nexport interface LcmBudget { calls: number; inputTokens: number; outputTokens: number; cost: number; wallMs: number; }\nexport interface LcmBudgetPolicy extends LcmBudget { sessionCalls: number; }\nconst DEFAULT_LCM_BUDGET: LcmBudgetPolicy = { calls: Number.POSITIVE_INFINITY, inputTokens: Number.POSITIVE_INFINITY, outputTokens: Number.POSITIVE_INFINITY, cost: Number.POSITIVE_INFINITY, wallMs: Number.POSITIVE_INFINITY, sessionCalls: Number.POSITIVE_INFINITY };\nexport interface LcmMaintenanceOptions { now?: () => number; ownerId?: string; policyHash?: string; maxLeafEntries?: number; maxCondenseChildren?: number; maxInputChars?: number; maxOutputChars?: number; modelTimeoutMs?: number; budget?: Partial<LcmBudgetPolicy>; maxConcurrentJobs?: number | (() => number); }\nexport const DEFAULT_LEAF_ENTRIES = 32;\nexport const DEFAULT_MAINTENANCE_CONCURRENCY = 3;\nexport const LEASE_MS = 30_000;\nexport const LEASE_SWEEP_GRACE_MS = 60_000;\nexport type LcmRejectionReason = \"job lease held\" | \"project lease held\" | \"job not eligible\" | \"budget exhausted\" | \"lease fenced\";\nexport class LcmRejection extends Error {\n readonly reason: LcmRejectionReason;\n constructor(reason: LcmRejectionReason) { super(reason); this.name = \"LcmRejection\"; this.reason = reason; }\n}\nexport const isLcmRejection = (error: unknown): error is LcmRejection => error instanceof LcmRejection;\nexport const isLcmCapacityRejection = (error: unknown): boolean => isLcmRejection(error) && (error.reason === \"project lease held\" || error.reason === \"budget exhausted\");\nconst LEGACY_CONTENTION_RETIREMENTS: ReadonlySet<string> = new Set([\"job lease held\", \"project lease held\", \"LcmRejection: job lease held\", \"LcmRejection: project lease held\"]);\nconst hash = (v: unknown) => hashLcmPayload(v);\nconst parse = <T>(v: unknown): T => JSON.parse(String(v));\nconst rawHash = (e: RawEntry) => e.payloadHash;\nconst token = () => crypto.randomUUID();\nconst LCM_MODEL_LEVELS: ReadonlyArray<{ mode: LcmPromptMode; share: number }> = [{ mode: \"detail\", share: 1 }, { mode: \"bullets\", share: 0.5 }];\nconst CLAIMABLE_JOBS_SQL = `SELECT j.payload FROM maintenance_jobs j\nJOIN summary_nodes n ON n.node_id=json_extract(j.payload,'$.nodeId') AND n.project_key=j.project_key\nWHERE j.project_key=?\nAND (j.status='pending' OR (j.status='running' AND CAST(coalesce(json_extract(j.payload,'$.leaseUntil'),0) AS INTEGER)<=?))\nAND CAST(json_extract(j.payload,'$.eligibleAt') AS INTEGER)<=?\nAND CAST(json_extract(j.payload,'$.nextRetryAt') AS INTEGER)<=?\nAND (? IS NULL OR json_extract(n.payload,'$.sessionId')=?)\nORDER BY CAST(json_extract(j.payload,'$.priority') AS INTEGER) DESC, j.created_at, j.job_id\nLIMIT ?`;\nconst LIVE_LEASES_SQL = `SELECT coalesce(json_extract(n.payload,'$.sessionId'),'') sessionId\nFROM maintenance_jobs j\nLEFT JOIN summary_nodes n ON n.node_id=json_extract(j.payload,'$.nodeId') AND n.project_key=j.project_key\nWHERE j.project_key=? AND j.status='running' AND j.job_id<>? AND CAST(coalesce(json_extract(j.payload,'$.leaseUntil'),0) AS INTEGER)>?`;\n\nexport class LcmMaintenance {\n readonly projectKey: string;\n private readonly now: () => number;\n private readonly ownerId: string;\n private readonly policyHash: string;\n private readonly maxLeaf: number;\n private readonly maxChildren: number;\n private readonly maxInputChars: number;\n private readonly maxOutputChars: number;\n private readonly budget: LcmBudgetPolicy;\n private readonly modelTimeoutMs: number;\n private readonly maxConcurrentJobs: number | (() => number);\n constructor(private readonly ledger: LcmLedger, options: LcmMaintenanceOptions = {}) { this.maxConcurrentJobs = options.maxConcurrentJobs ?? DEFAULT_MAINTENANCE_CONCURRENCY; this.projectKey = ledger.project.key; this.now = options.now ?? Date.now; this.ownerId = options.ownerId ?? crypto.randomUUID(); this.policyHash = options.policyHash ?? hash(\"lcm-policy-v1\"); this.maxLeaf = options.maxLeafEntries ?? DEFAULT_LEAF_ENTRIES; this.maxChildren = options.maxCondenseChildren ?? 4; this.maxInputChars = options.maxInputChars ?? 200_000; this.maxOutputChars = options.maxOutputChars ?? 4_096; this.modelTimeoutMs = options.modelTimeoutMs ?? 120_000; this.budget = { ...DEFAULT_LCM_BUDGET, ...options.budget }; }\n budgetPolicy(): LcmBudgetPolicy { return { ...this.budget }; }\n get concurrencyLimit(): number { const raw = typeof this.maxConcurrentJobs === \"function\" ? this.maxConcurrentJobs() : this.maxConcurrentJobs; return Number.isFinite(raw) ? Math.max(1, Math.floor(raw)) : DEFAULT_MAINTENANCE_CONCURRENCY; }\n private liveLeases(db: SqliteDatabase, at: number, excludeJobId?: string): Array<{ sessionId: string }> { return db.prepare(LIVE_LEASES_SQL).all(this.projectKey, excludeJobId ?? \"\", at - LEASE_SWEEP_GRACE_MS) as Array<{ sessionId: string }>; }\n private admits(db: SqliteDatabase, at: number, sessionId: string, leases: ReadonlyArray<{ sessionId: string }>): boolean {\n const day = this.day(at);\n const project = this.usage(db, day);\n const session = this.usage(db, day, sessionId);\n let sessionReserved = 0;\n for (const lease of leases) if (lease.sessionId === sessionId) sessionReserved += 1;\n const reserved = leases.length + 1;\n const fits = (used: number, cap: number): boolean => used < cap && used + (project.calls > 0 ? (used / project.calls) * reserved : 0) <= cap;\n return project.calls + leases.length < this.budget.calls\n && fits(project.inputTokens, this.budget.inputTokens)\n && fits(project.outputTokens, this.budget.outputTokens)\n && fits(project.cost, this.budget.cost)\n && fits(project.wallMs, this.budget.wallMs)\n && session.calls + sessionReserved < this.budget.sessionCalls;\n }\n private recordRevision(db: SqliteDatabase, node: LcmNode): void {\n if (!node.text) return;\n const row = db.prepare(\"SELECT coalesce(max(revision),0) n FROM summary_node_revisions WHERE node_id=?\").get(node.nodeId) as { n: number };\n db.prepare(\"INSERT OR IGNORE INTO summary_node_revisions(node_id,revision,project_key,text,model_hash,created_at) VALUES(?,?,?,?,?,?)\")\n .run(node.nodeId, Number(row.n) + 1, this.projectKey, node.text, node.modelHash, this.now());\n }\n revisionsOf(nodeId: string): Array<{ revision: number; text: string; modelHash: string; createdAt: number }> {\n return this.ledger.readOnly(db => (db.prepare(\"SELECT revision, text, model_hash, created_at FROM summary_node_revisions WHERE node_id=? AND project_key=? ORDER BY revision\").all(nodeId, this.projectKey) as Array<{ revision: number; text: string; model_hash: string; created_at: number }>)\n .map(row => ({ revision: Number(row.revision), text: row.text, modelHash: row.model_hash, createdAt: Number(row.created_at) })));\n }\n selectUpgrades(sessionId?: string, activeSources?: ReadonlySet<string>, limit = 1): LcmNode[] {\n return this.listNodes(100000)\n .filter(node => node.state === \"ready\" && node.modelHash === \"emergency\" && node.policyHash === this.policyHash\n && (!sessionId || node.sessionId === sessionId)\n && (!activeSources || node.sources.every(source => activeSources.has(this.sourceKey(source)))))\n .sort((left, right) => left.depth - right.depth || left.nodeId.localeCompare(right.nodeId))\n .slice(0, limit);\n }\n ancestorsOf(nodeId: string): string[] {\n return this.ledger.readOnly(db => {\n const seen = new Set<string>();\n const stack = [nodeId];\n const order: string[] = [];\n while (stack.length > 0) {\n const current = stack.pop()!;\n const parents = db.prepare(\"SELECT e.parent_id FROM summary_edges e JOIN summary_nodes parent ON parent.node_id=e.parent_id WHERE e.child_id=? AND parent.project_key=?\").all(current, this.projectKey) as Array<{ parent_id: string }>;\n for (const { parent_id: parent } of parents) {\n if (seen.has(parent)) continue;\n seen.add(parent);\n order.push(parent);\n stack.push(parent);\n }\n }\n return order;\n });\n }\n reopen(nodeId: string, force = false): LcmJob {\n return this.ledger.transaction(db => {\n const row = db.prepare(\"SELECT payload FROM summary_nodes WHERE node_id=? AND project_key=?\").get(nodeId, this.projectKey) as { payload?: string } | undefined;\n if (!row?.payload) throw new Error(\"node not found\");\n const node = parse<LcmNode>(row.payload);\n if (node.projectKey !== this.projectKey) throw new Error(\"node project does not match ledger project\");\n if (!force && node.modelHash !== \"emergency\") throw new Error(\"node already carries a model summary\");\n const t = this.now();\n const job: LcmJob = { ...this.job(node), jobId: `job:upgrade:${token()}:${node.nodeId}`, createdAt: t, updatedAt: t };\n db.prepare(\"INSERT INTO maintenance_jobs(job_id,project_key,status,payload,created_at,updated_at) VALUES(?,?,?,?,?,?)\")\n .run(job.jobId, this.projectKey, job.state, JSON.stringify(job), job.createdAt, job.updatedAt);\n return job;\n });\n }\n listNodes(limit = 100, offset = 0): LcmNode[] { return this.ledger.readOnly(db => (db.prepare(\"SELECT payload FROM summary_nodes WHERE project_key=? ORDER BY created_at,node_id LIMIT ? OFFSET ?\").all(this.projectKey, limit, offset) as Array<{payload:string}>).map(r => { const node = parse<LcmNode>(r.payload); if (node.projectKey !== this.projectKey) throw new Error(\"node project does not match ledger project\"); return node; })); }\n getNode(nodeId: string): LcmNode | undefined { return this.ledger.readOnly(db => { const row = db.prepare(\"SELECT payload FROM summary_nodes WHERE node_id=? AND project_key=?\").get(nodeId, this.projectKey) as {payload?:string}|undefined; if (!row?.payload) return undefined; const node = parse<LcmNode>(row.payload); if (node.projectKey !== this.projectKey) throw new Error(\"node project does not match ledger project\"); return node; }); }\n /** Scoped by the live source set when given; drops a condensed child and a contained node. */\n getFrontier(sessionId?: string, activeSources?: ReadonlySet<string>): LcmNode[] { const nodes=this.listNodes(100000).filter(n => n.state === \"ready\" && n.policyHash === this.policyHash && (!sessionId || activeSources !== undefined || n.sessionId === sessionId) && (!activeSources || n.sources.every(s => activeSources.has(this.sourceKey(s))))); const condensed=new Set(nodes.flatMap(n=>n.children)); const standing=nodes.filter(n=>!condensed.has(n.nodeId)); const ranked=[...standing].sort((a,b)=>b.sources.length-a.sources.length||a.nodeId.localeCompare(b.nodeId)); const kept: LcmNode[]=[]; const shadowed=new Set<string>(); for (const node of ranked) { const keys=node.sources.map(s=>this.sourceKey(s)); if (kept.some(other=>{ const held=new Set(other.sources.map(s=>this.sourceKey(s))); return keys.every(key=>held.has(key)); })) { shadowed.add(node.nodeId); continue; } kept.push(node); } return standing.filter(n=>!shadowed.has(n.nodeId)); }\n recentJobs(limit = 200): LcmJob[] { return this.ledger.readOnly(db => (db.prepare(\"SELECT payload FROM maintenance_jobs WHERE project_key=? ORDER BY CASE status WHEN 'failed' THEN 0 WHEN 'running' THEN 1 WHEN 'pending' THEN 2 ELSE 3 END, updated_at DESC LIMIT ?\").all(this.projectKey, limit) as Array<{payload:string}>).map(r => { const job = parse<LcmJob>(r.payload); if (job.projectKey !== this.projectKey) throw new Error(\"job project does not match ledger project\"); return job; })); }\n listJobs(limit = 100): LcmJob[] { return this.ledger.readOnly(db => (db.prepare(\"SELECT payload FROM maintenance_jobs WHERE project_key=? ORDER BY created_at,job_id LIMIT ?\").all(this.projectKey, limit) as Array<{payload:string}>).map(r => { const job = parse<LcmJob>(r.payload); if (job.projectKey !== this.projectKey) throw new Error(\"job project does not match ledger project\"); return job; })); }\n jobForNode(nodeId: string): LcmJob | undefined { return this.ledger.readOnly(db => { const row = db.prepare(\"SELECT payload FROM maintenance_jobs WHERE job_id=? AND project_key=?\").get(`job:${nodeId}`, this.projectKey) as {payload?:string}|undefined; if (!row?.payload) return undefined; const job = parse<LcmJob>(row.payload); if (job.projectKey !== this.projectKey) throw new Error(\"job project does not match ledger project\"); return job; }); }\n claimableJobs(sessionId?: string, limit = 64): LcmJob[] { const t = this.now(); const scope = sessionId ?? null; return this.ledger.readOnly(db => (db.prepare(CLAIMABLE_JOBS_SQL).all(this.projectKey, t - LEASE_SWEEP_GRACE_MS, t, t, scope, scope, limit) as Array<{payload:string}>).map(r => { const job = parse<LcmJob>(r.payload); if (job.projectKey !== this.projectKey) throw new Error(\"job project does not match ledger project\"); return job; })); }\n countJobs(state: LcmJobState, updatedSince = 0): number { return this.ledger.readOnly(db => Number((db.prepare(\"SELECT count(*) n FROM maintenance_jobs WHERE project_key=? AND status=? AND updated_at>=?\").get(this.projectKey, state, updatedSince) as {n:number}).n)); }\n isClaimable(job: LcmJob): boolean { const t = this.now(); return (job.state === \"pending\" || (job.state === \"running\" && (job.leaseUntil ?? 0) + LEASE_SWEEP_GRACE_MS <= t)) && job.eligibleAt <= t && job.nextRetryAt <= t; }\n sweepExpiredLeases(): LcmJob[] { return this.ledger.transaction(db => { const t = this.now() - LEASE_SWEEP_GRACE_MS; const rows = db.prepare(\"SELECT payload FROM maintenance_jobs WHERE project_key=? AND status=?\").all(this.projectKey, \"running\") as Array<{payload:string}>; const swept: LcmJob[] = []; for (const row of rows) { const old = parse<LcmJob>(row.payload); if (old.projectKey !== this.projectKey) throw new Error(\"job project does not match ledger project\"); if ((old.leaseUntil ?? 0) > t) continue; const now = this.now(); const { ownerId: _ownerId, leaseToken: _leaseToken, leaseUntil: _leaseUntil, ...base } = old; const job: LcmJob = { ...base, state: \"pending\", error: \"lease expired\", eligibleAt: now, nextRetryAt: now, updatedAt: now }; db.prepare(\"UPDATE maintenance_jobs SET status=?,payload=?,updated_at=? WHERE job_id=? AND project_key=?\").run(job.state, JSON.stringify(job), job.updatedAt, job.jobId, this.projectKey); swept.push(job); } return swept; }); }\n expiredLeases(): number { const t = this.now() - LEASE_SWEEP_GRACE_MS; return this.ledger.readOnly(db => Number((db.prepare(\"SELECT count(*) n FROM maintenance_jobs WHERE project_key=? AND status=? AND coalesce(json_extract(payload,'$.leaseUntil'),0)<=?\").get(this.projectKey, \"running\", t) as {n:number}).n)); }\n retryFailedJobs(): LcmJob[] { return this.ledger.transaction(db => { const rows = db.prepare(\"SELECT payload FROM maintenance_jobs WHERE project_key=? AND status=?\").all(this.projectKey, \"failed\") as Array<{payload:string}>; const retried: LcmJob[] = []; for (const row of rows) { const old = parse<LcmJob>(row.payload); if (old.projectKey !== this.projectKey) throw new Error(\"job project does not match ledger project\"); const t = this.now(); const { error: _error, ownerId: _ownerId, leaseToken: _leaseToken, leaseUntil: _leaseUntil, ...base } = old; const job: LcmJob = { ...base, state: \"pending\", attempts: 0, eligibleAt: t, nextRetryAt: t, updatedAt: t }; db.prepare(\"UPDATE maintenance_jobs SET status=?,payload=?,updated_at=? WHERE job_id=? AND project_key=?\").run(job.state, JSON.stringify(job), job.updatedAt, job.jobId, this.projectKey); retried.push(job); } return retried; }); }\n recoverLegacyContentionRetirements(): LcmJob[] { return this.ledger.transaction(db => { const rows = db.prepare(\"SELECT payload FROM maintenance_jobs WHERE project_key=? AND status=?\").all(this.projectKey, \"failed\") as Array<{payload:string}>; const recovered: LcmJob[] = []; for (const row of rows) { const old = parse<LcmJob>(row.payload); if (old.projectKey !== this.projectKey) throw new Error(\"job project does not match ledger project\"); if (old.legacyRecovery || !LEGACY_CONTENTION_RETIREMENTS.has(old.error ?? \"\")) continue; const t = this.now(); const { error: _error, ...base } = old; const job: LcmJob = { ...base, state: \"pending\", attempts: 0, legacyRecovery: true, eligibleAt: t, nextRetryAt: t, updatedAt: t }; db.prepare(\"UPDATE maintenance_jobs SET status=?,payload=?,updated_at=? WHERE job_id=? AND project_key=?\").run(job.state, JSON.stringify(job), job.updatedAt, job.jobId, this.projectKey); recovered.push(job); } return recovered; }); }\n recordFailure(job: LcmJob, error: unknown): LcmJob | undefined { return this.ledger.transaction(db => { const row = db.prepare(\"SELECT payload FROM maintenance_jobs WHERE job_id=? AND project_key=?\").get(job.jobId, this.projectKey) as {payload?:string}|undefined; if (!row?.payload) return undefined; const old = parse<LcmJob>(row.payload); if (old.projectKey !== this.projectKey) throw new Error(\"job project does not match ledger project\"); const t = this.now(); if (old.state === \"completed\" || old.attempts !== job.attempts) return old; if (old.state === \"running\" && (old.leaseUntil ?? 0) > t && old.leaseToken !== job.leaseToken) return old; const attempts = old.attempts + 1; const delay = Math.min(900_000, 30_000 * 2 ** (attempts - 1)); const { ownerId: _ownerId, leaseToken: _leaseToken, leaseUntil: _leaseUntil, ...base } = old; const next: LcmJob = { ...base, attempts, error: String(error), state: attempts >= 3 ? \"failed\" : \"pending\", eligibleAt: t + delay, nextRetryAt: t + delay, updatedAt: t }; db.prepare(\"UPDATE maintenance_jobs SET status=?,payload=?,updated_at=? WHERE job_id=? AND project_key=?\").run(next.state, JSON.stringify(next), next.updatedAt, next.jobId, this.projectKey); return next; }); }\n selectLeaf(entries = this.ledger.readRaw(this.projectKey), activeSources?: ReadonlySet<string>): RawEntry[] { const first = entries[0]; if (!first) return []; const nodes = this.listNodes(100000).filter(n => n.state !== \"failed\" && n.policyHash === this.policyHash && (n.sessionId === first.sessionId || (activeSources !== undefined && n.state === \"ready\")) && (!activeSources || n.sources.every(s => activeSources.has(this.sourceKey(s))))); const covered = new Set(nodes.flatMap(n => n.sources.map(s => this.sourceKey(s)))); const candidates = entries.filter(e => e.sessionId === first.sessionId && !covered.has(this.sourceKey(e))); const picked: RawEntry[] = []; let chars = 0; for (const entry of candidates) { if (picked.length >= this.maxLeaf) break; const size = entry.payloadJson.length; if (picked.length > 0 && chars + size > this.maxInputChars) break; picked.push(entry); chars += size; } return picked; }\n selectCondensation(sessionId?: string, activeSources?: ReadonlySet<string>): LcmNode[] { const nodes = this.listNodes(100000).filter(n => n.state === \"ready\" && n.policyHash === this.policyHash && (!sessionId || n.sessionId === sessionId) && (!activeSources || n.sources.every(s => activeSources.has(this.sourceKey(s))))); const eligible = new Set(nodes.map(n => n.nodeId)); const edges = this.ledger.readOnly(db => db.prepare(\"SELECT e.parent_id,e.child_id FROM summary_edges e JOIN summary_nodes parent ON parent.node_id=e.parent_id AND parent.project_key=? JOIN summary_nodes child ON child.node_id=e.child_id AND child.project_key=parent.project_key WHERE parent.project_key=?\").all(this.projectKey, this.projectKey) as Array<{parent_id:string;child_id:string}>); const consumed = new Set(edges.filter(e => eligible.has(e.parent_id)).map(e => e.child_id)); const candidates = nodes.filter(n => !consumed.has(n.nodeId)); const first = candidates[0]; if (!first) return []; const depth = Math.min(...candidates.map(n => n.depth)); const sameDepth = candidates.filter(n => n.depth === depth); if (depth > 0 && sameDepth.length < 2) return []; return candidates.filter(n => n.projectKey === first.projectKey && n.sessionId === first.sessionId && n.depth === depth).sort((a,b) => a.nodeId.localeCompare(b.nodeId)).slice(0, this.maxChildren); }\n createLeaf(entries: RawEntry[]): LcmNode | undefined { if (!entries.length) return undefined; const source = entries.map((e, index) => { if (e.projectKey !== this.projectKey) throw new Error(\"entry project does not match ledger project\"); const payload = parse<{type?: unknown; id?: unknown}>(e.payloadJson); if (typeof payload.type !== \"string\" || !payload.type || payload.id !== e.entryId) throw new Error(\"invalid raw payload\"); if (hash(payload) !== rawHash(e)) throw new Error(\"payload hash mismatch\"); return { sessionId:e.sessionId, entryId:e.entryId, revision:e.revision, payloadHash:rawHash(e) }; }); this.validateSources(source); const node: LcmNode = { nodeId:`leaf:${hash({ projectKey:this.projectKey, source, policyHash:this.policyHash })}`, projectKey:this.projectKey, sessionId:entries[0]!.sessionId, kind:\"leaf\", sources:source, children:[], depth:0, sourceHash:hash(source.map(s=>s.payloadHash)), policyHash:this.policyHash, modelHash:\"\", state:\"pending\", createdAt:this.now() }; this.publish(node); return node; }\n createCondensed(children: LcmNode[]): LcmNode | undefined { if (!children.length) return undefined; if (children.some(c => c.state !== \"ready\")) throw new Error(\"condensation requires ready children\"); if (new Set(children.map(c=>c.sessionId)).size !== 1 || new Set(children.map(c=>c.depth)).size !== 1) throw new Error(\"mixed session or depth\"); const storedChildren = children.map((child) => this.getNode(child.nodeId)); if (storedChildren.some((child) => !child || child.projectKey !== this.projectKey)) throw new Error(\"child project does not match ledger project\"); if (storedChildren.some((child, index) => JSON.stringify(child) !== JSON.stringify(children[index]))) throw new Error(\"child payload changed\"); const source = [...new Map(storedChildren.flatMap(c => c!.sources).map((value) => [this.sourceKey(value), value])).values()]; this.validateSources(source); const node: LcmNode = { nodeId:`condensed:${hash({ projectKey:this.projectKey, children:storedChildren.map(c=>c!.nodeId), policyHash:this.policyHash })}`, projectKey:this.projectKey, sessionId:children[0]!.sessionId, kind:\"condensed\", sources:source, children:children.map(c=>c.nodeId), depth:Math.max(...children.map(c=>c.depth))+1, sourceHash:hash(children.map(c=>c.sourceHash)), policyHash:this.policyHash, modelHash:\"\", state:\"pending\", createdAt:this.now() }; this.publish(node); return node; }\n private validateSources(source: LcmSourceRef[]) { const seen = new Set<string>(); for (const s of source) { if (seen.has(this.sourceKey(s))) throw new Error(\"duplicate source identity\"); seen.add(this.sourceKey(s)); } if (new Set(source.map(s => s.sessionId)).size !== 1) throw new Error(\"cross-session ranges\"); }\n private sourceKey(source: Pick<LcmSourceRef, \"entryId\" | \"payloadHash\">) { return `${source.entryId}:${source.payloadHash}`; }\n private publish(node: LcmNode) { this.ledger.transaction(db => { if (node.children.includes(node.nodeId)) throw new Error(\"cycle\"); for (const child of node.children) if (!db.prepare(\"SELECT 1 FROM summary_nodes WHERE node_id=? AND project_key=?\").get(child,this.projectKey)) throw new Error(\"missing child\"); db.prepare(\"INSERT OR IGNORE INTO summary_nodes(node_id,project_key,payload,created_at) VALUES(?,?,?,?)\").run(node.nodeId,this.projectKey,JSON.stringify(node),node.createdAt); for (const child of node.children) db.prepare(\"INSERT OR IGNORE INTO summary_edges(parent_id,child_id) VALUES(?,?)\").run(node.nodeId,child); const job = this.job(node); db.prepare(\"INSERT OR IGNORE INTO maintenance_jobs(job_id,project_key,status,payload,created_at,updated_at) VALUES(?,?,?,?,?,?)\").run(job.jobId,this.projectKey,job.state,JSON.stringify(job),job.createdAt,job.updatedAt); }); }\n private job(node:LcmNode): LcmJob { const t=this.now(); return {jobId:`job:${node.nodeId}`,projectKey:this.projectKey,nodeId:node.nodeId,priority:node.kind === \"condensed\" ? 20 : 10,eligibleAt:t,state:\"pending\",attempts:0,nextRetryAt:t,createdAt:t,updatedAt:t}; }\n claim(jobId: string, ownerId = this.ownerId): LcmJob { return this.ledger.transaction(db => { const row = db.prepare(\"SELECT payload FROM maintenance_jobs WHERE job_id=? AND project_key=?\").get(jobId,this.projectKey) as {payload?:string}|undefined; if (!row?.payload) throw new Error(\"job not found\"); const old=parse<LcmJob>(row.payload); if (old.projectKey !== this.projectKey) throw new Error(\"job project does not match ledger project\"); const t=this.now(); const expired = old.state === \"running\" && (old.leaseUntil ?? 0) + LEASE_SWEEP_GRACE_MS <= t; if (old.state === \"running\" && !expired) throw new LcmRejection(\"job lease held\"); if ((old.state !== \"pending\" && !expired) || old.eligibleAt > t || old.nextRetryAt > t) throw new LcmRejection(\"job not eligible\"); const leases = this.liveLeases(db, t, old.jobId); if (leases.length >= this.concurrencyLimit) throw new LcmRejection(\"project lease held\"); const nodeRow = db.prepare(\"SELECT payload FROM summary_nodes WHERE node_id=? AND project_key=?\").get(old.nodeId,this.projectKey) as {payload?:string}|undefined; const sessionId = nodeRow?.payload ? parse<LcmNode>(nodeRow.payload).sessionId : \"\"; if (!this.admits(db, t, sessionId, leases)) throw new LcmRejection(\"budget exhausted\"); const out={...old,state:\"running\" as const,ownerId,leaseToken:token(),leaseUntil:t+LEASE_MS,updatedAt:t}; db.prepare(\"UPDATE maintenance_jobs SET status=?,payload=?,updated_at=? WHERE job_id=? AND project_key=?\").run(out.state,JSON.stringify(out),t,jobId,this.projectKey); return out; }); }\n claimEmergency(jobId: string, ownerId = this.ownerId): LcmJob { return this.ledger.transaction(db => { const row = db.prepare(\"SELECT payload FROM maintenance_jobs WHERE job_id=? AND project_key=?\").get(jobId,this.projectKey) as {payload?:string}|undefined; if (!row?.payload) throw new Error(\"job not found\"); const old = parse<LcmJob>(row.payload); if (old.projectKey !== this.projectKey) throw new Error(\"job project does not match ledger project\"); const t = this.now(); const expired = old.state === \"running\" && (old.leaseUntil ?? 0) <= t; if (old.state === \"running\" && !expired) throw new LcmRejection(\"job lease held\"); if (old.state === \"completed\") throw new Error(\"job already completed\"); const out = { ...old, state: \"running\" as const, ownerId, leaseToken: token(), leaseUntil: t + LEASE_MS, updatedAt: t }; db.prepare(\"UPDATE maintenance_jobs SET status=?,payload=?,updated_at=? WHERE job_id=? AND project_key=?\").run(out.state,JSON.stringify(out),t,jobId,this.projectKey); return out; }); }\n renew(job:LcmJob): LcmJob { return this.fenced(job, old => ({...old,leaseUntil:this.now()+LEASE_MS,updatedAt:this.now()})); }\n private validateText(text: unknown): asserts text is string { if (typeof text !== \"string\" || text.length === 0) throw new Error(\"invalid summary text\"); let length = 0; for (const _ of text) { length += 1; if (length > this.maxOutputChars) throw new Error(\"summary exceeds output bound\"); } }\n private validateShrink(text: string, inputBytes: number): void { if (!Number.isSafeInteger(inputBytes) || inputBytes < 0) throw new Error(\"invalid input bound\"); if (utf8Bytes(text) >= inputBytes) throw new Error(\"summary does not shrink its input\"); }\n withinBudget(sessionId: string, excludeJobId?: string): boolean { return this.ledger.readOnly(db => { const at = this.now(); return this.admits(db, at, sessionId, this.liveLeases(db, at, excludeJobId)); }); }\n private accountRejected(sessionId: string, result: LcmModelResult): void { if (![result.inputTokens,result.outputTokens,result.cost,result.wallMs].every((value) => Number.isFinite(value) && value >= 0)) return; try { this.ledger.transaction(db => this.account(db, sessionId, result)); } catch {} }\n complete(job:LcmJob, result:LcmModelResult, inputBytes: number): LcmNode { this.validateText(result.text); this.validateShrink(result.text, inputBytes); return this.ledger.transaction(db => { const current=this.readJob(db,job.jobId); this.assertLease(current,job); if (current.nodeId !== job.nodeId) throw new Error(\"job node mismatch\"); const row=db.prepare(\"SELECT payload FROM summary_nodes WHERE node_id=? AND project_key=?\").get(job.nodeId,this.projectKey) as {payload?:string}|undefined; if (!row?.payload) throw new Error(\"node not found\"); const node=parse<LcmNode>(row.payload); if (node.projectKey !== this.projectKey || node.nodeId !== current.nodeId) throw new Error(\"node project does not match ledger project\"); for (const source of node.sources) { const raw=db.prepare(\"SELECT payload_json,session_id FROM raw_entries WHERE project_key=? AND session_id=? AND entry_id=? AND revision=?\").get(this.projectKey,source.sessionId,source.entryId,source.revision) as {payload_json?:string;session_id?:string}|undefined; if (!raw?.payload_json || hash(parse(raw.payload_json)) !== source.payloadHash || raw.session_id !== source.sessionId) throw new Error(\"stale source\"); } if (![result.inputTokens,result.outputTokens,result.cost,result.wallMs].every((value) => Number.isFinite(value) && value >= 0)) throw new Error(\"invalid model usage\"); const projectUsage = this.usage(db, this.day(this.now())); const sessionUsage = this.usage(db, this.day(this.now()), node.sessionId); if (projectUsage.calls + 1 > this.budget.calls || projectUsage.inputTokens + result.inputTokens > this.budget.inputTokens || projectUsage.outputTokens + result.outputTokens > this.budget.outputTokens || projectUsage.cost + result.cost > this.budget.cost || projectUsage.wallMs + result.wallMs > this.budget.wallMs || sessionUsage.calls + 1 > this.budget.sessionCalls) throw new Error(\"budget exhausted\"); this.recordRevision(db, node); const out={...node,state:\"ready\" as const,text:result.text,modelHash:result.modelHash}; this.account(db,node.sessionId,result); db.prepare(\"UPDATE summary_nodes SET payload=? WHERE node_id=? AND project_key=?\").run(JSON.stringify(out),node.nodeId,this.projectKey); const { ownerId: _ownerId, leaseToken: _leaseToken, leaseUntil: _leaseUntil, ...base } = current; const done={...base,state:\"completed\" as const,updatedAt:this.now()}; db.prepare(\"UPDATE maintenance_jobs SET status=?,payload=?,updated_at=? WHERE job_id=? AND project_key=?\").run(done.state,JSON.stringify(done),done.updatedAt,done.jobId,this.projectKey); return out; }); }\n completeEmergency(job:LcmJob, text:string): LcmNode { this.validateText(text); return this.ledger.transaction(db => { const current=this.readJob(db,job.jobId); this.assertLease(current,job); if (current.nodeId !== job.nodeId) throw new Error(\"job node mismatch\"); const row=db.prepare(\"SELECT payload FROM summary_nodes WHERE node_id=? AND project_key=?\").get(job.nodeId,this.projectKey) as {payload?:string}|undefined; if (!row?.payload) throw new Error(\"node not found\"); const node=parse<LcmNode>(row.payload); if (node.projectKey !== this.projectKey || node.nodeId !== current.nodeId) throw new Error(\"node project does not match ledger project\"); for (const source of node.sources) { const raw=db.prepare(\"SELECT payload_json,session_id FROM raw_entries WHERE project_key=? AND session_id=? AND entry_id=? AND revision=?\").get(this.projectKey,source.sessionId,source.entryId,source.revision) as {payload_json?:string;session_id?:string}|undefined; if (!raw?.payload_json || hash(parse(raw.payload_json)) !== source.payloadHash || raw.session_id !== source.sessionId) throw new Error(\"stale source\"); } this.recordRevision(db, node); const out={...node,state:\"ready\" as const,text,modelHash:\"emergency\"}; db.prepare(\"UPDATE summary_nodes SET payload=? WHERE node_id=? AND project_key=?\").run(JSON.stringify(out),node.nodeId,this.projectKey); const { ownerId: _ownerId, leaseToken: _leaseToken, leaseUntil: _leaseUntil, ...base } = current; const done={...base,state:\"completed\" as const,updatedAt:this.now()}; db.prepare(\"UPDATE maintenance_jobs SET status=?,payload=?,updated_at=? WHERE job_id=? AND project_key=?\").run(done.state,JSON.stringify(done),done.updatedAt,done.jobId,this.projectKey); return out; }); }\n fail(job:LcmJob,error:string): LcmJob { return this.fenced(job, old => { const attempts=old.attempts+1; const delay=Math.min(900_000,30_000*2**(attempts-1)); const { ownerId: _ownerId, leaseToken: _leaseToken, leaseUntil: _leaseUntil, ...base } = old; return {...base,attempts,error,state:attempts>=3?\"failed\":\"pending\",eligibleAt:this.now()+delay,nextRetryAt:this.now()+delay,updatedAt:this.now()}; }); }\n async run(job:LcmJob, model:LcmSummarizer, input:string, signal=new AbortController().signal): Promise<LcmNode> {\n let sources: LcmSourceRef[] = [];\n let claimed: LcmJob | undefined;\n const controller = new AbortController();\n let renew: ReturnType<typeof setInterval> | undefined;\n const timer = setTimeout(() => controller.abort(), this.modelTimeoutMs);\n const abort = () => controller.abort();\n signal.addEventListener(\"abort\", abort, { once: true });\n const inputBytes = utf8Bytes(input);\n try {\n claimed = this.claim(job.jobId, job.ownerId ?? this.ownerId);\n const node = this.getNode(claimed.nodeId);\n sources = node?.sources ?? [];\n const kind = node?.kind ?? \"leaf\";\n const sessionId = node?.sessionId ?? \"\";\n renew = setInterval(() => { try { if (claimed) claimed = this.renew(claimed); } catch {} }, 10_000);\n let lastError: unknown = new Error(\"LCM summarization did not converge\");\n for (const [index, level] of LCM_MODEL_LEVELS.entries()) {\n if (controller.signal.aborted) break;\n if (index > 0 && !this.withinBudget(sessionId, job.jobId)) break;\n const target = Math.max(1, Math.min(Math.floor(this.maxOutputChars * level.share), inputBytes - 1));\n let result: LcmModelResult;\n try {\n result = await Promise.race([\n model.generate({ prompt: buildLcmPrompt(kind, input, this.maxInputChars, level.mode, target), sessionId, signal: controller.signal }),\n new Promise<never>((_, reject) => controller.signal.addEventListener(\"abort\", () => reject(new Error(\"LCM timeout\")), { once: true })),\n ]);\n } catch (error) { lastError = error; continue; }\n if (utf8Bytes(result.text) >= inputBytes) { this.accountRejected(sessionId, result); lastError = new Error(\"summary does not shrink its input\"); continue; }\n return this.complete(claimed, result, inputBytes);\n }\n throw lastError;\n } catch (error) {\n if (!claimed) throw error;\n const fallback = emergencyReduce(input, this.maxOutputChars, sources);\n try { return this.completeEmergency(claimed, fallback); }\n catch (fenced) {\n if (isLcmRejection(fenced) && fenced.reason === \"lease fenced\") throw fenced;\n try { this.fail(claimed, String(error)); } catch {}\n throw error;\n }\n } finally { clearTimeout(timer); if (renew) clearInterval(renew); signal.removeEventListener(\"abort\", abort); }\n }\n private day(ms:number): string { return new Date(ms).toISOString().slice(0,10); }\n private usage(db:any, day:string, sessionId?:string): LcmBudget { const q = sessionId === undefined ? \"SELECT COALESCE(SUM(calls),0) calls,COALESCE(SUM(input_tokens),0) inputTokens,COALESCE(SUM(output_tokens),0) outputTokens,COALESCE(SUM(cost),0) cost,COALESCE(SUM(wall_ms),0) wallMs FROM maintenance_usage WHERE project_key=? AND day=?\" : \"SELECT COALESCE(SUM(calls),0) calls,COALESCE(SUM(input_tokens),0) inputTokens,COALESCE(SUM(output_tokens),0) outputTokens,COALESCE(SUM(cost),0) cost,COALESCE(SUM(wall_ms),0) wallMs FROM maintenance_usage WHERE project_key=? AND day=? AND session_id=?\"; const r=(sessionId === undefined ? db.prepare(q).get(this.projectKey,day) : db.prepare(q).get(this.projectKey,day,sessionId)) as LcmBudget; return r; }\n private account(db:any, sessionId:string, result:LcmModelResult) { const d=this.day(this.now()); db.prepare(\"INSERT INTO maintenance_usage(project_key,day,session_id,calls,input_tokens,output_tokens,cost,wall_ms) VALUES(?,?,?,?,?,?,?,?) ON CONFLICT(project_key,day,session_id) DO UPDATE SET calls=calls+excluded.calls,input_tokens=input_tokens+excluded.input_tokens,output_tokens=output_tokens+excluded.output_tokens,cost=cost+excluded.cost,wall_ms=wall_ms+excluded.wall_ms\").run(this.projectKey,d,sessionId,1,result.inputTokens,result.outputTokens,result.cost,result.wallMs); }\n private readJob(db: any,id:string):LcmJob { const row=db.prepare(\"SELECT payload FROM maintenance_jobs WHERE job_id=? AND project_key=?\").get(id,this.projectKey) as {payload:string}|undefined; if(!row) throw new Error(\"job not found\"); const job=parse<LcmJob>(row.payload); if(job.projectKey!==this.projectKey) throw new Error(\"job project does not match ledger project\"); return job; }\n private assertLease(current:LcmJob, expected:LcmJob) { if(current.ownerId!==expected.ownerId || current.leaseToken!==expected.leaseToken || current.state!==\"running\" || (current.leaseUntil??0)<this.now()) throw new LcmRejection(\"lease fenced\"); }\n private fenced(job:LcmJob, update:(old:LcmJob)=>LcmJob):LcmJob { return this.ledger.transaction(db => { const old=this.readJob(db,job.jobId); this.assertLease(old,job); const out=update(old); db.prepare(\"UPDATE maintenance_jobs SET status=?,payload=?,updated_at=? WHERE job_id=? AND project_key=?\").run(out.state,JSON.stringify(out),out.updatedAt,out.jobId,this.projectKey); return out; }); }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["fs", "fs", "path", "record", "path", "fs", "token", "path", "crypto", "fs", "path", "hash", "crypto", "fs", "path", "read", "crypto", "hash", "crypto", "kept", "fs"]
7
7
  }