fix(gbrain-local-status): classifier falsely reports broken-db inside repos with their own DATABASE_URL
Problem
/sync-gbrain hard-stops at the Step 1.5 pre-flight with
gbrain_local_status: "broken-db" for any user whose gbrain engine is
healthy but who runs the skill from inside a repo that defines its own
DATABASE_URL in .env (common for web-app repos).
Root cause: gbrain is a Bun binary, and Bun autoloads .env from the
current directory. When lib/gbrain-local-status.ts:freshClassify probes
with gbrain sources list --json, it passes env: env ?? process.env.
Inside such a repo, process.env.DATABASE_URL is the project's app DB, not
gbrain's own DB from ~/.gbrain/config.json. gbrain connects to the wrong
database, sources list fails with "Cannot connect to database", and the
classifier reports broken-db.
It is a pure false negative: the configured gbrain engine is healthy
(gbrain doctor passes, direct DB connection works), but the user is told
to debug their database when nothing is wrong with it.
Second-order amplifier: the 60s status cache key
({home, path_hash, gbrain_bin, version, config_mtime}) does not include
cwd or the effective DATABASE_URL, so one poisoned probe propagates the
false broken-db to clean directories for up to a minute.
Fix
Route the probe env through buildGbrainEnv from lib/gbrain-exec.ts —
the exact helper the sync orchestrator (gstack-gbrain-sync.ts) already
uses to seed DATABASE_URL from ~/.gbrain/config.json. The classifier
inconsistently skipped it. This also makes the probe cwd-independent, so
the cache can no longer propagate a poisoned result. The existing
GSTACK_RESPECT_ENV_DATABASE_URL=1 escape hatch is unaffected.
Verification
- Before: running the probe from inside a repo whose
.envsets a differentDATABASE_URL→broken-dbwhile the gbrain engine is healthy. - After: same directory →
ok, both cached and with the cache bypassed. - A directory with no
.envis unchanged:ok.
Notes
- Companion PR: #1584 (a separate
--fullfirst-run empty-index bug found during the same investigation). - Deeper root cause worth a follow-up in
garrytan/gbrain: because gbrain is a Bun binary, anygbraininvocation from inside an app repo inherits that repo's.envDATABASE_URL. Every downstream tool has to defensively re-seed it. A first-class fix (prefer~/.gbrain/config.jsonover an inheritedDATABASE_URL, or aGBRAIN_DATABASE_URLthat always wins) would remove the need for these guards. Filed as a suggestion, not blocking this PR.
Optional follow-up (not in this PR)
Add the effective DATABASE_URL to the status-cache key as
defense-in-depth, so any future env leak can't be cached across
directories. Kept out to keep this PR focused.
Could you add a focused regression for the poisoned .env case? The production fix now routes freshClassify() through buildGbrainEnv, but there is no test proving a project DATABASE_URL is overridden by ~/.gbrain/config.json for the gbrain sources list --json probe. A fake gbrain shim plus temp HOME/GBRAIN_HOME, mirroring the buildGbrainEnv tests, would pin the false broken-db regression and also prove GSTACK_RESPECT_ENV_DATABASE_URL=1 still opts out.
Thanks @jetsetterfl — gbrain-local-status DB classifier fix shipped in v1.43.2.0 post-Daegu wave (#1642).