fix(core): finish deferred agentLogEntries drop when migrations 103+ outrun it
Migration 102 defers the destructive agentLogEntries drop until TaskStore copies legacy rows to JSONL and writes the __meta guard, then relies on a second init() pass gated on schemaVersion < SCHEMA_VERSION. Migrations 103-105 bump the version to 105 on the first pass, so the second pass never fired and the legacy table survived forever. Make the drop version-independent in migrate() and trigger the re-init whenever the legacy table remains. Also pin secrets-schema.test.ts to String(SCHEMA_VERSION) instead of the hardcoded "102" string the schema bump invalidated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@ import { describe, it, expect } from "vitest";
|
||||
import { mkdtempSync, rmSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { Database } from "../db.js";
|
||||
import { Database, SCHEMA_VERSION } from "../db.js";
|
||||
import { createCentralDatabase } from "../central-db.js";
|
||||
|
||||
function createTempDir(prefix: string): string {
|
||||
@@ -42,7 +42,7 @@ describe("secrets schema migrations", () => {
|
||||
const version = db
|
||||
.prepare("SELECT value FROM __meta WHERE key = 'schemaVersion'")
|
||||
.get() as { value: string };
|
||||
expect(version.value).toBe("102");
|
||||
expect(version.value).toBe(String(SCHEMA_VERSION));
|
||||
} finally {
|
||||
db.close();
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
@@ -105,7 +105,7 @@ describe("secrets schema migrations", () => {
|
||||
const version = db
|
||||
.prepare("SELECT value FROM __meta WHERE key = 'schemaVersion'")
|
||||
.get() as { value: string };
|
||||
expect(version.value).toBe("102");
|
||||
expect(version.value).toBe(String(SCHEMA_VERSION));
|
||||
} finally {
|
||||
db.close();
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
@@ -155,7 +155,7 @@ describe("secrets schema migrations", () => {
|
||||
.prepare("SELECT value FROM __meta WHERE key = 'schemaVersion'")
|
||||
.get() as { value: string };
|
||||
|
||||
expect(projectVersion.value).toBe("102");
|
||||
expect(projectVersion.value).toBe(String(SCHEMA_VERSION));
|
||||
expect(centralVersion.value).toBe("13");
|
||||
} finally {
|
||||
projectDb.close();
|
||||
|
||||
@@ -2028,6 +2028,28 @@ export class Database {
|
||||
this.addColumnIfMissing("tasks", "scopeAutoWiden", "TEXT DEFAULT '[]'");
|
||||
}
|
||||
|
||||
// Deferred agentLogEntries drop (companion to migration 102): when the
|
||||
// legacy table still had rows on the first init pass, the destructive drop
|
||||
// was deferred until TaskStore copies the rows to JSONL and writes the
|
||||
// __meta guard, then re-runs init(). Migrations 103+ bump the schema
|
||||
// version past 102 on that first pass, so the re-run can no longer reach
|
||||
// the version-gated 102 block — finish the drop here, version-independent
|
||||
// (and before the early return below, which fires once the version is
|
||||
// current).
|
||||
if (this.hasTable("agentLogEntries")) {
|
||||
const agentLogMigrationComplete = this.getMetaValue("agentLogEntriesToFileMigrationVersion") === "1";
|
||||
const legacyAgentLogTableIsEmpty =
|
||||
(this.db.prepare("SELECT COUNT(*) as count FROM agentLogEntries").get() as { count: number }).count === 0;
|
||||
const hasLegacyAgentLogCitations = this.hasTable("goal_citations")
|
||||
? (this.db.prepare(
|
||||
"SELECT 1 FROM goal_citations WHERE surface = 'agent_log' AND sourceRef GLOB 'agentLog:[0-9]*' LIMIT 1",
|
||||
).get() ?? undefined) !== undefined
|
||||
: false;
|
||||
if (agentLogMigrationComplete || (legacyAgentLogTableIsEmpty && !hasLegacyAgentLogCitations)) {
|
||||
this.db.exec(`DROP TABLE IF EXISTS agentLogEntries`);
|
||||
}
|
||||
}
|
||||
|
||||
if (version >= SCHEMA_VERSION) return;
|
||||
|
||||
if (version < 2) {
|
||||
|
||||
@@ -1443,7 +1443,17 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
await this.migrateActiveArchivedTasksToArchiveDb();
|
||||
await this.migrateAgentLogEntriesToFilesOnce();
|
||||
await this.cleanupNoOpTaskMovedActivityRowsOnce();
|
||||
if (this.db.getSchemaVersion() < SCHEMA_VERSION) {
|
||||
// Re-run init when migrations are pending, or when the deferred
|
||||
// agentLogEntries drop still needs to fire: migration 102 skips the
|
||||
// destructive drop until migrateAgentLogEntriesToFilesOnce() above writes
|
||||
// the __meta guard, but migrations 103+ bump the schema version past 102
|
||||
// on the first pass, so the version check alone no longer triggers the
|
||||
// second pass that performs the drop.
|
||||
const legacyAgentLogTableRemains =
|
||||
this.db
|
||||
.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'agentLogEntries' LIMIT 1")
|
||||
.get() !== undefined;
|
||||
if (this.db.getSchemaVersion() < SCHEMA_VERSION || legacyAgentLogTableRemains) {
|
||||
this.db.init();
|
||||
}
|
||||
await this.importLegacyAgentLogsOnce();
|
||||
|
||||
Reference in New Issue
Block a user