From 2f722a4bccc0740469d9f3d97996d02431668a5d Mon Sep 17 00:00:00 2001 From: Lourince Daging Date: Wed, 22 Jul 2026 16:27:44 +0200 Subject: [PATCH] fix(miner): register ranked-candidates + deny-hook-synthesis in doctor/migrate store lists status.ts's storeIntegrityChecks and migrate-cli.ts's STORES both enumerate every durable local SQLite store so `loopover-miner doctor` reports each store's integrity and `loopover-miner migrate` applies pending migrations to each. Two stores were missing from both lists: ranked-candidates and deny-hook-synthesis -- so doctor never checked them and migrate never migrated them, unlike every sibling store. Add both to storeIntegrityChecks (via resolveRankedCandidatesDbPath / resolveDenyHookSynthesisDbPath) and to STORES (with their initRankedCandidatesStore / initDenyHookSynthesisStore openers), and update the pinned store-list tests (count and expected names) plus a #8008 regression assertion mirroring the existing #6768 one. Closes #8008 --- packages/loopover-miner/lib/migrate-cli.ts | 4 ++++ packages/loopover-miner/lib/status.ts | 4 ++++ test/unit/miner-migrate-cli.test.ts | 6 +++++- test/unit/miner-status.test.ts | 6 ++++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/loopover-miner/lib/migrate-cli.ts b/packages/loopover-miner/lib/migrate-cli.ts index 736bcfdc40..a8fffcc9c4 100644 --- a/packages/loopover-miner/lib/migrate-cli.ts +++ b/packages/loopover-miner/lib/migrate-cli.ts @@ -25,6 +25,8 @@ import { openWorktreeAllocator, resolveWorktreeAllocatorDbPath } from "./worktre import { initContributionProfileCache, resolveContributionProfileCacheDbPath } from "./contribution-profile-cache.js"; import { initPolicyVerdictCacheStore, resolvePolicyVerdictCacheDbPath } from "./policy-verdict-cache.js"; import { initPolicyDocCacheStore, resolvePolicyDocCacheDbPath } from "./policy-doc-cache.js"; +import { initRankedCandidatesStore, resolveRankedCandidatesDbPath } from "./ranked-candidates.js"; +import { initDenyHookSynthesisStore, resolveDenyHookSynthesisDbPath } from "./deny-hook-synthesis.js"; const MIGRATE_USAGE = "Usage: loopover-miner migrate [--json]"; @@ -76,6 +78,8 @@ const STORES: MigrateStoreDescriptor[] = [ }, { name: "policy-verdict-cache", resolveDbPath: resolvePolicyVerdictCacheDbPath, open: initPolicyVerdictCacheStore }, { name: "policy-doc-cache", resolveDbPath: resolvePolicyDocCacheDbPath, open: initPolicyDocCacheStore }, + { name: "ranked-candidates", resolveDbPath: resolveRankedCandidatesDbPath, open: initRankedCandidatesStore }, + { name: "deny-hook-synthesis", resolveDbPath: resolveDenyHookSynthesisDbPath, open: initDenyHookSynthesisStore }, ]; /** Read a store file's stamped schema version without ever creating it -- matches checkStoreIntegrity's diff --git a/packages/loopover-miner/lib/status.ts b/packages/loopover-miner/lib/status.ts index e8708201e4..4b096b54b2 100644 --- a/packages/loopover-miner/lib/status.ts +++ b/packages/loopover-miner/lib/status.ts @@ -28,6 +28,8 @@ import { resolveWorktreeAllocatorDbPath } from "./worktree-allocator.js"; import { resolveContributionProfileCacheDbPath } from "./contribution-profile-cache.js"; import { resolvePolicyVerdictCacheDbPath } from "./policy-verdict-cache.js"; import { resolvePolicyDocCacheDbPath } from "./policy-doc-cache.js"; +import { resolveRankedCandidatesDbPath } from "./ranked-candidates.js"; +import { resolveDenyHookSynthesisDbPath } from "./deny-hook-synthesis.js"; // Slim laptop-mode CLI commands (#2288): `status` (what's installed + where local state lives) and `doctor` (is // this laptop set up correctly). Both are read-only and 100% local — no repo-scanning, no coding-agent invocation, @@ -376,6 +378,8 @@ function storeIntegrityChecks(env: Record): DoctorCh ["contribution-profile", resolveContributionProfileCacheDbPath(env)], ["policy-verdict-cache", resolvePolicyVerdictCacheDbPath(env)], ["policy-doc-cache", resolvePolicyDocCacheDbPath(env)], + ["ranked-candidates", resolveRankedCandidatesDbPath(env)], + ["deny-hook-synthesis", resolveDenyHookSynthesisDbPath(env)], ]; return stores.map(([name, dbPath]) => checkStoreIntegrity(`store-integrity:${name}`, dbPath)); } diff --git a/test/unit/miner-migrate-cli.test.ts b/test/unit/miner-migrate-cli.test.ts index 7068513032..2b5b57341a 100644 --- a/test/unit/miner-migrate-cli.test.ts +++ b/test/unit/miner-migrate-cli.test.ts @@ -32,6 +32,8 @@ const STORE_NAMES = [ "contribution-profile", "policy-verdict-cache", "policy-doc-cache", + "ranked-candidates", + "deny-hook-synthesis", ]; afterEach(() => { @@ -40,13 +42,15 @@ afterEach(() => { }); describe("loopover-miner migrate (#4871)", () => { - it("covers the exact same fourteen stores doctor's store-integrity sweep covers, in the same order, and skips every one when nothing has been created yet", () => { + it("covers the exact same sixteen stores doctor's store-integrity sweep covers, in the same order, and skips every one when nothing has been created yet", () => { const env = tempEnv(); const results = runMigrateChecks(env); expect(results.map((result) => result.name)).toEqual(STORE_NAMES); // REGRESSION (#6768): these four durable stores were previously omitted from both migrate and doctor. expect(STORE_NAMES).toEqual(expect.arrayContaining(["governor-state", "attempt-log", "replay-snapshot", "worktree-allocator"])); + // REGRESSION (#8008): ranked-candidates and deny-hook-synthesis were likewise omitted from both lists. + expect(STORE_NAMES).toEqual(expect.arrayContaining(["ranked-candidates", "deny-hook-synthesis"])); for (const result of results) { expect(result.ok).toBe(true); expect(result.status).toBe("skipped"); diff --git a/test/unit/miner-status.test.ts b/test/unit/miner-status.test.ts index 3eed665aa2..6eca51550f 100644 --- a/test/unit/miner-status.test.ts +++ b/test/unit/miner-status.test.ts @@ -142,6 +142,8 @@ describe("loopover-miner status/doctor (#2288)", () => { "store-integrity:contribution-profile", "store-integrity:policy-verdict-cache", "store-integrity:policy-doc-cache", + "store-integrity:ranked-candidates", + "store-integrity:deny-hook-synthesis", ]); // REGRESSION (#6768): doctor previously omitted these four durable local stores from the integrity sweep. expect(checks.map((check) => check.name)).toEqual( @@ -152,6 +154,10 @@ describe("loopover-miner status/doctor (#2288)", () => { "store-integrity:worktree-allocator", ]), ); + // REGRESSION (#8008): ranked-candidates and deny-hook-synthesis were likewise omitted from the sweep. + expect(checks.map((check) => check.name)).toEqual( + expect.arrayContaining(["store-integrity:ranked-candidates", "store-integrity:deny-hook-synthesis"]), + ); expect(runDoctor([], env, cwd)).toBe(0); expect(log).toHaveBeenCalled(); });