From 269a37525d266333f6731a37ebfcda01c9068b7c Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Wed, 6 May 2026 12:15:34 -0700 Subject: [PATCH] fix(upgrade): post-upgrade auto-applies pending schema migrations (X1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prior behavior: `gbrain upgrade` → `gbrain post-upgrade` → `apply-migrations` only WARNs at apply-migrations.ts:296-302 when schema version is behind LATEST_VERSION, telling the user to run `gbrain init --migrate-only`. 11 wedge incidents over 2 years have proven users don't read that WARN — they file an issue instead. This commit makes `runPostUpgrade` explicitly call `engine.initSchema()` after the orchestrator migration pass, mirroring `init --migrate-only`'s flow. Side-effect: `gbrain upgrade` now walks away with a healthy brain in the cluster A wedge case (#670, #661, #657, #651, #625, #615, #609). Defensive: wrapped in try/catch so a connection or DDL failure falls back to the existing user-facing WARN. The hint to run `gbrain init --migrate-only` is preserved as the manual escape hatch. Pairs with v0.28.5's A1 (hasPendingMigrations probe in connectEngine): the upgrade path runs initSchema explicitly here, while every other code path that goes through connectEngine gets the cheap probe. Codex outside-voice review caught this gap during plan review: "the plan still does not prove `upgrade` will actually run schema migrations." This is the load-bearing fix that makes v0.28.5's headline outcome ("run upgrade, brain works") literally true for cluster A. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/commands/upgrade.ts | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/commands/upgrade.ts b/src/commands/upgrade.ts index 1baefda81..328c4d8ba 100644 --- a/src/commands/upgrade.ts +++ b/src/commands/upgrade.ts @@ -218,6 +218,37 @@ export async function runPostUpgrade(args: string[] = []): Promise { console.error('Run `gbrain apply-migrations --yes` manually to retry.'); } + // v0.28.5 (X1): explicitly apply pending schema migrations. + // apply-migrations runs orchestrator migrations and only WARNs about + // schema-version drift (apply-migrations.ts:296-302). Without this hook, + // `gbrain upgrade` leaves wedged brains wedged — the user has to read + // the WARN and run `gbrain init --migrate-only` themselves. We've shipped + // 11 wedge incidents asking users to read warnings; close the loop here. + // A1's hasPendingMigrations probe in connectEngine is belt-and-suspenders + // for any path that bypasses upgrade (autopilot, direct CLI on stale brain). + try { + const { loadConfig: lcSchema, toEngineConfig: toCfgSchema } = await import('../core/config.ts'); + const { createEngine } = await import('../core/engine-factory.ts'); + const cfgSchema = lcSchema(); + if (cfgSchema) { + const engine = await createEngine(toCfgSchema(cfgSchema)); + try { + await engine.connect(toCfgSchema(cfgSchema)); + await engine.initSchema(); + console.log(' Schema up to date.'); + } finally { + try { await engine.disconnect(); } catch { /* best-effort */ } + } + } + } catch (e) { + // Non-fatal: connection or DDL failure here falls back to the existing + // user-facing WARN. apply-migrations.ts:296-302 already surfaces the + // hint to run `gbrain init --migrate-only`. + const msg = e instanceof Error ? e.message : String(e); + console.warn(`\nSchema auto-apply skipped: ${msg}`); + console.warn('Run `gbrain init --migrate-only` manually if your brain is wedged.'); + } + // v0.25.1: agent-readable advisory listing recommended skills the // workspace hasn't installed yet. No-op when everything is installed. try {