Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions packages/loopover-miner/lib/migrate-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,7 @@ const STORES: MigrateStoreDescriptor[] = [
{ name: "plan-store", resolveDbPath: resolvePlanStoreDbPath, open: openPlanStore },
{ name: "governor-state", resolveDbPath: resolveGovernorStateDbPath, open: openGovernorState },
{ name: "attempt-log", resolveDbPath: resolveAttemptLogDbPath, open: initAttemptLog },
{
name: "replay-snapshot",
// resolveReplaySnapshotDbPath's own (not-yet-converted) .d.ts types `env` as `NodeJS.ProcessEnv`, unlike
// every sibling resolver here (`Record<string, string | undefined>`) -- a pre-existing inconsistency, not
// introduced by this batch. process.env genuinely satisfies both shapes at runtime, so this cast is safe.
resolveDbPath: resolveReplaySnapshotDbPath as (env?: Record<string, string | undefined>) => string,
open: openReplaySnapshotStore,
},
{ name: "replay-snapshot", resolveDbPath: resolveReplaySnapshotDbPath, open: openReplaySnapshotStore },
{
name: "worktree-allocator",
resolveDbPath: resolveWorktreeAllocatorDbPath,
Expand Down
3 changes: 1 addition & 2 deletions packages/loopover-miner/lib/status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,7 @@ function storeIntegrityChecks(env: Record<string, string | undefined>): DoctorCh
["plan-store", resolvePlanStoreDbPath(env)],
["governor-state", resolveGovernorStateDbPath(env)],
["attempt-log", resolveAttemptLogDbPath(env)],
// replay-snapshot's .d.ts still types env as ProcessEnv (not yet migrated); cast is lossless.
["replay-snapshot", resolveReplaySnapshotDbPath(env as NodeJS.ProcessEnv)],
["replay-snapshot", resolveReplaySnapshotDbPath(env)],
["worktree-allocator", resolveWorktreeAllocatorDbPath(env)],
["contribution-profile", resolveContributionProfileCacheDbPath(env)],
["policy-verdict-cache", resolvePolicyVerdictCacheDbPath(env)],
Expand Down
13 changes: 13 additions & 0 deletions test/unit/miner-migrate-cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { resolveEventLedgerDbPath } from "../../packages/loopover-miner/lib/even
import { applySchemaMigrations, BASELINE_SCHEMA_VERSION } from "../../packages/loopover-miner/lib/schema-version.js";
import { openWorktreeAllocator, resolveWorktreeAllocatorDbPath } from "../../packages/loopover-miner/lib/worktree-allocator.js";
import { openLaptopStateStore, resolveLaptopStateDbPath } from "../../packages/loopover-miner/lib/laptop-init.js";
import { openReplaySnapshotStore, resolveReplaySnapshotDbPath } from "../../packages/loopover-miner/lib/replay-snapshot.js";

const roots: string[] = [];

Expand Down Expand Up @@ -119,6 +120,18 @@ describe("loopover-miner migrate (#4871)", () => {
expect(again).toMatchObject({ ok: true, status: "up-to-date", versionBefore: BASELINE_SCHEMA_VERSION });
});

// REGRESSION (#8642): migrate/status used to cast resolveReplaySnapshotDbPath's env as NodeJS.ProcessEnv
// behind a stale "not yet migrated" comment. The resolver already accepts Record<string, string | undefined>
// like every sibling — calling it without a cast must still open + report up-to-date for a fresh store.
it("REGRESSION (#8642): replay-snapshot migrate open adapter resolves env without a ProcessEnv cast", () => {
const env = tempEnv();
openReplaySnapshotStore(resolveReplaySnapshotDbPath(env)).close();
const row = runMigrateChecks(env).find((result) => result.name === "replay-snapshot");
expect(row).toMatchObject({ ok: true, status: "up-to-date" });
expect(row?.versionBefore).toBe(row?.versionAfter);
expect(row?.versionBefore).toEqual(expect.any(Number));
});

it("actually migrates a pre-existing older-schema portfolio-queue file, bumping its stamped version and adding the missing column", () => {
const env = tempEnv();
const dbPath = resolvePortfolioQueueDbPath(env);
Expand Down