diff --git a/packages/loopover-miner/lib/governor-ledger.js b/packages/loopover-miner/lib/governor-ledger.js index 7620121acd..4b5ecd30b6 100644 --- a/packages/loopover-miner/lib/governor-ledger.js +++ b/packages/loopover-miner/lib/governor-ledger.js @@ -1,8 +1,7 @@ -import { chmodSync, mkdirSync } from "node:fs"; import { homedir } from "node:os"; -import { dirname, join } from "node:path"; -import { DatabaseSync } from "node:sqlite"; +import { join } from "node:path"; import { normalizeGovernorLedgerEvent } from "@loopover/engine"; +import { openLocalStoreDb } from "./local-store.js"; import { applySchemaMigrations } from "./schema-version.js"; import { GOVERNOR_LEDGER_PURGE_SPEC, @@ -96,10 +95,7 @@ function rowToDecision(row) { */ export function initGovernorLedger(dbPath = resolveGovernorLedgerDbPath()) { const resolvedPath = normalizeDbPath(dbPath); - mkdirSync(dirname(resolvedPath), { recursive: true, mode: 0o700 }); - const db = new DatabaseSync(resolvedPath); - chmodSync(resolvedPath, 0o600); - db.exec("PRAGMA busy_timeout = 5000"); + const db = openLocalStoreDb(resolvedPath); db.exec(` CREATE TABLE IF NOT EXISTS governor_events ( id INTEGER PRIMARY KEY AUTOINCREMENT, diff --git a/packages/loopover-miner/lib/plan-store.js b/packages/loopover-miner/lib/plan-store.js index c5a23f8757..8d7a3be3fa 100644 --- a/packages/loopover-miner/lib/plan-store.js +++ b/packages/loopover-miner/lib/plan-store.js @@ -1,7 +1,6 @@ -import { chmodSync, mkdirSync } from "node:fs"; import { homedir } from "node:os"; -import { dirname, join } from "node:path"; -import { DatabaseSync } from "node:sqlite"; +import { join } from "node:path"; +import { openLocalStoreDb } from "./local-store.js"; import { applySchemaMigrations } from "./schema-version.js"; // Local SQLite persistence for the stateless MCP plan DAG (#2318). `loopover_build_plan`/`plan_status`/ @@ -150,13 +149,9 @@ function rowToRecord(row) { */ export function openPlanStore(dbPath = resolvePlanStoreDbPath()) { const resolvedPath = normalizeDbPath(dbPath); - // The store is a persistent local file; the special in-memory path (':memory:') has no file to create or chmod. - if (resolvedPath !== ":memory:") { - mkdirSync(dirname(resolvedPath), { recursive: true, mode: 0o700 }); - } - const db = new DatabaseSync(resolvedPath); - if (resolvedPath !== ":memory:") chmodSync(resolvedPath, 0o600); - db.exec("PRAGMA busy_timeout = 5000"); + // openLocalStoreDb centralizes the mkdir(0o700)/chmod(0o600)/busy_timeout + crash-safe cleanup registration and + // treats ':memory:' as a no-file special case, so this store no longer hand-rolls that boilerplate (#4826). + const db = openLocalStoreDb(resolvedPath); db.exec(` CREATE TABLE IF NOT EXISTS miner_plans ( plan_id TEXT PRIMARY KEY, diff --git a/packages/loopover-miner/lib/prediction-ledger.js b/packages/loopover-miner/lib/prediction-ledger.js index ce576af2ab..45545e5ec0 100644 --- a/packages/loopover-miner/lib/prediction-ledger.js +++ b/packages/loopover-miner/lib/prediction-ledger.js @@ -1,7 +1,6 @@ -import { chmodSync, mkdirSync } from "node:fs"; import { homedir } from "node:os"; -import { dirname, join } from "node:path"; -import { DatabaseSync } from "node:sqlite"; +import { join } from "node:path"; +import { openLocalStoreDb } from "./local-store.js"; import { PREDICTION_LEDGER_PURGE_SPEC, PREDICTION_LEDGER_RETENTION_SPEC, @@ -135,10 +134,7 @@ function rowToEntry(row) { */ export function initPredictionLedger(dbPath = resolvePredictionLedgerDbPath()) { const resolvedPath = normalizeDbPath(dbPath); - mkdirSync(dirname(resolvedPath), { recursive: true, mode: 0o700 }); - const db = new DatabaseSync(resolvedPath); - chmodSync(resolvedPath, 0o600); - db.exec("PRAGMA busy_timeout = 5000"); + const db = openLocalStoreDb(resolvedPath); db.exec(` CREATE TABLE IF NOT EXISTS predictions ( id INTEGER PRIMARY KEY AUTOINCREMENT,