fix(gbrain): classify probe timeout as its own status; sync proceeds instead of skipping (#1964)

The 5s engine probe misclassified healthy-but-slow engines (cold Supabase
pooler connections measured at 6.9-10.7s) as broken-config, so /sync-gbrain
silently skipped code+memory and told the user their config was malformed.

- New "timeout" status: probe killed at the deadline with no recognized
  stderr pattern. Default deadline is now 15s, overridable via
  GSTACK_GBRAIN_PROBE_TIMEOUT_MS (tests set 300ms against a fake that
  sleeps 2s).
- Sync stages PROCEED on timeout with a stderr warning naming the env knob;
  a genuinely-dead engine surfaces its real error at the first operation
  instead of a false config diagnosis.
- Consistency everywhere "ok" gated behavior: gstack-gbrain-detect --is-ok
  exits 0 on timeout, and gen-skill-docs' detection gate accepts it, so a
  slow engine no longer silently suppresses brain-aware features.
- Status cache: key now includes the effective probe timeout (raising it
  invalidates a cached timeout) and GBRAIN_HOME; config detection honors
  GBRAIN_HOME so relocated-home users stop being misclassified as
  missing-config.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-06-11 20:27:46 -07:00
co-authored by Claude Fable 5
parent 8e4662e930
commit da06ef1504
10 changed files with 278 additions and 54 deletions
+3 -1
View File
@@ -47,7 +47,9 @@ function loadGbrainOverride(): { detected: boolean } {
const detectionPath = path.join(stateDir, 'gbrain-detection.json');
try {
const json = JSON.parse(fs.readFileSync(detectionPath, 'utf-8')) as { gbrain_local_status?: string };
return { detected: json.gbrain_local_status === 'ok' };
// "timeout" = slow-but-healthy engine (#1964) — same treatment as "ok",
// matching gstack-gbrain-detect --is-ok.
return { detected: json.gbrain_local_status === 'ok' || json.gbrain_local_status === 'timeout' };
} catch {
return { detected: false };
}