From 0e978d4565e8e3e0a3c4eff47af86ac06baa0582 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Tue, 31 Mar 2026 17:34:05 -0500 Subject: [PATCH] =?UTF-8?q?fix(state):=20always=20run=20disk=E2=86=92DB=20?= =?UTF-8?q?reconciliation=20when=20DB=20is=20available=20(#2631)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When DB was available but empty, deriveState skipped deriveStateFromDb entirely, bypassing the disk→DB sync logic. Milestones created outside the DB write path were never discovered. --- src/resources/extensions/gsd/state.ts | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/resources/extensions/gsd/state.ts b/src/resources/extensions/gsd/state.ts index 9e1b3f311..7f9a0504c 100644 --- a/src/resources/extensions/gsd/state.ts +++ b/src/resources/extensions/gsd/state.ts @@ -228,19 +228,15 @@ export async function deriveState(basePath: string): Promise { const stopTimer = debugTime("derive-state-impl"); let result: GSDState; - // Dual-path: try DB-backed derivation first when hierarchy tables are populated + // Dual-path: try DB-backed derivation when DB is available. + // Always go through deriveStateFromDb when DB is open — even if hierarchy + // tables are empty — because it contains disk→DB reconciliation logic that + // discovers milestones created outside the DB write path (#2631). if (isDbAvailable()) { - const dbMilestones = getAllMilestones(); - if (dbMilestones.length > 0) { - const stopDbTimer = debugTime("derive-state-db"); - result = await deriveStateFromDb(basePath); - stopDbTimer({ phase: result.phase, milestone: result.activeMilestone?.id }); - _telemetry.dbDeriveCount++; - } else { - // DB open but empty hierarchy tables — pre-migration project, use filesystem - result = await _deriveStateImpl(basePath); - _telemetry.markdownDeriveCount++; - } + const stopDbTimer = debugTime("derive-state-db"); + result = await deriveStateFromDb(basePath); + stopDbTimer({ phase: result.phase, milestone: result.activeMilestone?.id }); + _telemetry.dbDeriveCount++; } else { result = await _deriveStateImpl(basePath); _telemetry.markdownDeriveCount++;