fix(cli): pre-set GBRAIN_EVAL_CAPTURE/SCRUB_PII env wins over DB stash

The #1475 stash unconditionally overwrote the env vars from the merged DB
plane, silently clobbering an operator's exported value — inverting the
env-above-config precedence the same code comment advertises. Unlike
GBRAIN_EMBEDDING_MULTIMODAL, these keys have no loadConfig() env mapping,
so file/env-wins in loadConfigWithEngine never covered them. Guard the
stash writes: DB fills the gap only when the env var is unset.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-07-22 12:06:59 -07:00
co-authored by Claude Fable 5
parent ee095f1ca2
commit c275fa3fab
+6 -2
View File
@@ -2256,10 +2256,14 @@ async function connectEngine(opts?: { probeOnly?: boolean }): Promise<BrainEngin
// op path and MCP dispatch — it never sees the DB plane directly. The
// gates consult this stash when the file plane is silent, so
// `gbrain config set eval.capture true` actually turns capture on.
if (merged.eval?.capture !== undefined) {
// A pre-set env value wins over the DB plane (env-above-config, the
// incident escape hatch) — unlike GBRAIN_EMBEDDING_MULTIMODAL these
// keys have no loadConfig() env mapping, so without this guard the
// DB stash would silently clobber an operator's export.
if (process.env.GBRAIN_EVAL_CAPTURE === undefined && merged.eval?.capture !== undefined) {
process.env.GBRAIN_EVAL_CAPTURE = String(merged.eval.capture);
}
if (merged.eval?.scrub_pii !== undefined) {
if (process.env.GBRAIN_EVAL_SCRUB_PII === undefined && merged.eval?.scrub_pii !== undefined) {
process.env.GBRAIN_EVAL_SCRUB_PII = String(merged.eval.scrub_pii);
}
// Always re-configure with merged values when DB merge succeeded. The