fix(gbrain-detect): classify gbrain >= 0.43 held-lock refusal as engine-locked

gbrain 0.43+ refuses a held PGLite lock with exit 1 and the message
"GBrain's local database is already open through `gbrain serve` (MCP,
PID N)" instead of the pre-0.43 exit 124 + "connect timed out" that
the #2194 branch matches. The message matches no known pattern, so the
classifier falls through to the defensive broken-config default — and
Step 1.5 of /setup-gbrain and /sync-gbrain then tell the user to move a
perfectly healthy config.json aside and re-init the engine.

Reproduced live on gbrain 0.43.0.0, 0.44.0.0 and 0.46.30.0: with a
serve holding the lock, gstack-gbrain-detect reports
gbrain_local_status=broken-config; after stopping the serve it reports
ok with the same untouched config.

Match on the stable substring "already open through", mirroring the
existing #2194 branch semantics: engine-locked for pglite, broken-db
otherwise. Adds a fake-gbrain behavior for the 0.43+ refusal plus two
cases (pglite -> engine-locked, postgres -> broken-db).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Peter van Leeuwen
2026-08-31 20:56:32 +00:00
committed by Garry Tan
co-authored by Claude Fable 5
parent 3599a3d4df
commit 5424ac5fe0
2 changed files with 28 additions and 2 deletions
+11
View File
@@ -464,6 +464,17 @@ function freshClassify(env?: NodeJS.ProcessEnv): LocalEngineStatus {
return configuredEngine(env) === "pglite" ? "engine-locked" : "broken-db";
}
// gbrain >= 0.43 refuses the same held-lock case with exit 1 and its
// own message: "GBrain's local database is already open through `gbrain
// serve` (MCP, PID N). This brain uses PGLite, ...". That string matches
// none of the branches above, so without this check it falls through to
// the defensive broken-config default — whose remediation tells the user
// to move a perfectly healthy config.json aside and re-init the engine
// (#2194 follow-up).
if (stderr.includes("already open through")) {
return configuredEngine(env) === "pglite" ? "engine-locked" : "broken-db";
}
// Probe killed by the timeout with no recognized error: the engine is
// most likely healthy but slow (cold pooler connections measured at
// 6.9-10.7s in #1964). Don't tell the user their config is malformed.