diff --git a/setup-gbrain/SKILL.md b/setup-gbrain/SKILL.md index 19d18afb7..c1abd775c 100644 --- a/setup-gbrain/SKILL.md +++ b/setup-gbrain/SKILL.md @@ -785,8 +785,10 @@ implemented as a dispatcher binary. ``` Capture the JSON output. It contains: `gbrain_on_path`, `gbrain_version`, -`gbrain_config_exists`, `gbrain_engine`, `gbrain_doctor_ok`, -`gstack_brain_sync_mode`, `gstack_brain_git`. +`gbrain_config_exists`, `gbrain_engine`, `gbrain_doctor_ok`, `gbrain_mcp_mode`, +`gstack_brain_sync_mode`, `gstack_brain_git`, `gstack_artifacts_remote`, and +the v1.34.0.0+ `gbrain_local_status` field (one of: `ok`, `no-cli`, +`missing-config`, `broken-config`, `broken-db`). Skip downstream steps that are already done. Report the detected state in one line so the user knows what you found: @@ -799,6 +801,75 @@ invocation flags here and skip to the matching step. --- +## Step 1.5: Broken-local-engine remediation (plan D4) + +Read `gbrain_local_status` from the Step 1 detect output. **If it's `broken-db` +or `broken-config` AND no shortcut flag was passed**, the user has a +non-working local engine (Garry's repro: `~/.gbrain/config.json` points at a +dead Postgres URL). Fire a targeted AskUserQuestion BEFORE Step 2: + +> D# — Your local gbrain engine isn't responding. How do you want to fix it? +> Project/branch/task: +> ELI10: gbrain has a config at `~/.gbrain/config.json` but the engine it points +> at isn't reachable. That could be a transient outage (Postgres container +> stopped, Tailscale down) OR a stale config you want to abandon. Different +> remediation for each case. +> Stakes if we pick wrong: "Switch to PGLite" overwrites your existing config +> (one-way door if the user actually wanted the broken engine). "Retry" preserves +> existing state for transient cases. +> Recommendation: A (Retry) — always try the cheap option first; if engine is +> just temporarily down it'll come back without any destructive change. +> Note: options differ in kind, not coverage — no completeness score. +> A) Retry — re-probe the engine (recommended; ~80ms) +> ✅ Cheapest test: re-runs `gbrain sources list` to see if engine is back +> ✅ Zero side effects; existing config preserved +> ❌ If engine is permanently dead, retries forever; user must choose another option +> B) Switch to local PGLite (one-way — moves existing config to .bak) +> ✅ Fastest path to a working local engine if user has abandoned the old one +> ✅ ~30s; no accounts; private to this machine +> ❌ Destructive — existing config moved to ~/.gbrain/config.json.gstack-bak-{ts} +> C) Switch brain mode (continue to Step 2 path picker) +> ✅ Lets user pick Path 1/2/3/4 to re-init from scratch +> ✅ Preserves existing config until they explicitly init the new one +> ❌ Longer flow if user just wants to repair to PGLite +> D) Quit (do nothing) +> ✅ No cons — this is a hard-stop choice +> ❌ N/A +> Net: A is the right starting move; B/C are explicit destructive paths; D bails. + +**If A (Retry)**: re-run `~/.claude/skills/gstack/bin/gstack-gbrain-detect` +with `GSTACK_DETECT_NO_CACHE=1` (busts the 60s cache). If the new +`gbrain_local_status` is `ok`, continue to Step 2. If still `broken-db` or +`broken-config`, fire the same AskUserQuestion again (the user picks again). + +**If B (Switch to PGLite)** — execute the rollback-safe init sequence (plan D7): + +```bash +BACKUP="$HOME/.gbrain/config.json.gstack-bak-$(date +%s)" +mv "$HOME/.gbrain/config.json" "$BACKUP" +if ! gbrain init --pglite --json; then + # Restore on failure + mv "$BACKUP" "$HOME/.gbrain/config.json" + echo "gbrain init failed. Your previous config was restored at $HOME/.gbrain/config.json." >&2 + echo "PGLite directory at ~/.gbrain/pglite/ may be in a partial state — \`rm -rf ~/.gbrain/pglite\` if needed before retrying." >&2 + exit 1 +fi +echo "Switched to local PGLite. Previous config saved at $BACKUP — review before deleting." +``` + +Then jump to Step 5a (MCP registration; the new PGLite engine is registered as +local-stdio). + +**If C (Switch brain mode)**: continue to Step 2's normal path picker. + +**If D (Quit)**: STOP the skill cleanly. + +For `gbrain_local_status` values of `no-cli` or `missing-config`, do NOT fire +Step 1.5 — fall through to Step 2 (where `no-cli` triggers Step 3 install and +`missing-config` triggers Step 4 init). + +--- + ## Step 2: Pick a path (AskUserQuestion) Only fire this if Step 1 shows no existing working config AND no shortcut @@ -1034,11 +1105,60 @@ Capture two values from the verify output for downstream steps: - `URL_FORM_SUPPORTED` (`true|false`) — passed to `gstack-artifacts-init` in Step 7 to control which form of the brain-admin hookup command is printed. -**4d. Skip Steps 3, 4 (other paths), 5 (local doctor), 7.5 (transcript ingest).** -All four require a working local `gbrain` CLI that Path 4 does not install. -The skill jumps straight to Step 5a (HTTP+bearer registration) → Step 6 -(per-remote policy) → Step 7 (artifacts repo) → Step 8 (CLAUDE.md) → Step 9 -(remote smoke test) → Step 10 (verdict). +**4d. (Path 4) Offer local PGLite for code search.** Per plan D10/D11, ask: + +> D# — Want symbol-aware code search on this machine? +> Project/branch/task: +> ELI10: The remote brain at `` is great for cross-machine knowledge, +> but symbol queries like `gbrain code-def` / `code-refs` / `code-callers` need +> a local index of THIS machine's code. We can spin up a tiny isolated PGLite +> database (~30 seconds, no accounts, ~120 MB disk) just for code, separate +> from your remote brain. Transcripts and artifacts continue routing through +> the artifacts repo to the remote brain — local PGLite stays code-only. +> Stakes: without it, semantic code search in this repo's worktrees falls +> back to Grep. +> Recommendation: A — 30 seconds, no ongoing cost, unlocks the symbol tools. +> Completeness: A=10/10 (full split-engine), B=7/10 (remote-only). +> A) Yes, set up local PGLite for code (recommended) +> ✅ Unlocks `gbrain code-def`, `code-refs`, `code-callers` per worktree +> ✅ Independent engine — won't disturb remote brain or share transcripts +> B) No, remote MCP only +> ✅ Zero local state — only `~/.claude.json` MCP registration +> ❌ Symbol code queries fall back to Grep in this repo's worktrees +> Net: A = full split-engine; B = remote-only. + +**If A (Yes)**: install + init local PGLite with rollback-safe semantics (D7): + +```bash +~/.claude/skills/gstack/bin/gstack-gbrain-install || exit $? +# At this point the local gbrain CLI is on PATH. Init PGLite, but back up any +# existing ~/.gbrain/config.json first (rollback if init fails). +if [ -f "$HOME/.gbrain/config.json" ]; then + BACKUP="$HOME/.gbrain/config.json.gstack-bak-$(date +%s)" + mv "$HOME/.gbrain/config.json" "$BACKUP" +fi +if ! gbrain init --pglite --json; then + if [ -n "${BACKUP:-}" ] && [ -f "$BACKUP" ]; then mv "$BACKUP" "$HOME/.gbrain/config.json"; fi + echo "gbrain init failed. Existing config (if any) was restored. PGLite at ~/.gbrain/pglite/ may be in a partial state — \`rm -rf ~/.gbrain/pglite\` to reset." >&2 + echo "Continuing setup without local code search; you can re-run /setup-gbrain to retry." >&2 +fi +``` + +Then continue to Step 5a. The remote-http MCP registration in 5a runs as +today; the local PGLite is independent of MCP registration (Claude Code talks +to the remote brain via MCP for queries; `gbrain` CLI talks to local PGLite +for code-def/refs/callers). + +**If B (No)**: skip the install + init. The local engine stays absent. +`gbrain_local_status` will be `missing-config` (or `no-cli` if gbrain isn't +installed). `/sync-gbrain` will SKIP the code stage cleanly per plan D12. + +**4e. Skip Steps 3, 4 (other paths) and 5 (local doctor) when B was picked.** +When A was picked, Step 3 already ran (via gstack-gbrain-install) and Step 4 +already ran (via `gbrain init --pglite`); jump straight to Step 5a. When B +was picked, Steps 3/4/5 are no-ops; also skip Step 7.5 (transcript ingest) +since memory-stage routes through the artifacts pipeline in remote-http mode +per plan D11. The bearer token (`GBRAIN_MCP_TOKEN`) stays in process env until Step 5a's `claude mcp add --header` consumes it; then `unset GBRAIN_MCP_TOKEN` @@ -1475,7 +1595,8 @@ gbrain status: GREEN (mode: remote-http) Repo policy ..... OK {read-write|read-only|deny} Artifacts repo .. OK {gstack_artifacts_remote URL} Artifacts sync .. OK {artifacts_sync_mode} - Transcripts ..... N/A remote mode (ingest happens on brain host) + Transcripts ..... OK route to artifacts repo → remote brain (plan D11) + Code search ..... {OK local-pglite (~/.gbrain/pglite) | N/A declined at Step 4d} CLAUDE.md ....... OK Smoke test ...... INFO printed for post-restart manual verification @@ -1483,6 +1604,16 @@ Restart Claude Code to pick up the `mcp__gbrain__*` tools. Re-run `/setup-gbrain` any time the bearer rotates or the URL moves. ``` +The **Code search** row reflects the choice at Step 4d: +- If user picked A (Yes): `OK local-pglite` and `gbrain_local_status == "ok"` going forward. +- If user picked B (No): `N/A declined at Step 4d` — `gstack-config set local_code_index_offered true` to silence future migration notices. + +The **Transcripts** row changed in v1.34.0.0: in remote-http mode, +gstack-memory-ingest now persists staged transcripts to +`~/.gstack/transcripts/run--/` and gstack-brain-sync pushes them +to the artifacts repo. Brain admin's pull job indexes into the remote brain. +Local PGLite (when present) stays code-only — no transcript pollution. + ### Paths 1, 2a, 2b, 3 (Local stdio) ``` diff --git a/setup-gbrain/SKILL.md.tmpl b/setup-gbrain/SKILL.md.tmpl index a2a49cee1..a0bc59769 100644 --- a/setup-gbrain/SKILL.md.tmpl +++ b/setup-gbrain/SKILL.md.tmpl @@ -63,8 +63,10 @@ implemented as a dispatcher binary. ``` Capture the JSON output. It contains: `gbrain_on_path`, `gbrain_version`, -`gbrain_config_exists`, `gbrain_engine`, `gbrain_doctor_ok`, -`gstack_brain_sync_mode`, `gstack_brain_git`. +`gbrain_config_exists`, `gbrain_engine`, `gbrain_doctor_ok`, `gbrain_mcp_mode`, +`gstack_brain_sync_mode`, `gstack_brain_git`, `gstack_artifacts_remote`, and +the v1.34.0.0+ `gbrain_local_status` field (one of: `ok`, `no-cli`, +`missing-config`, `broken-config`, `broken-db`). Skip downstream steps that are already done. Report the detected state in one line so the user knows what you found: @@ -77,6 +79,75 @@ invocation flags here and skip to the matching step. --- +## Step 1.5: Broken-local-engine remediation (plan D4) + +Read `gbrain_local_status` from the Step 1 detect output. **If it's `broken-db` +or `broken-config` AND no shortcut flag was passed**, the user has a +non-working local engine (Garry's repro: `~/.gbrain/config.json` points at a +dead Postgres URL). Fire a targeted AskUserQuestion BEFORE Step 2: + +> D# — Your local gbrain engine isn't responding. How do you want to fix it? +> Project/branch/task: +> ELI10: gbrain has a config at `~/.gbrain/config.json` but the engine it points +> at isn't reachable. That could be a transient outage (Postgres container +> stopped, Tailscale down) OR a stale config you want to abandon. Different +> remediation for each case. +> Stakes if we pick wrong: "Switch to PGLite" overwrites your existing config +> (one-way door if the user actually wanted the broken engine). "Retry" preserves +> existing state for transient cases. +> Recommendation: A (Retry) — always try the cheap option first; if engine is +> just temporarily down it'll come back without any destructive change. +> Note: options differ in kind, not coverage — no completeness score. +> A) Retry — re-probe the engine (recommended; ~80ms) +> ✅ Cheapest test: re-runs `gbrain sources list` to see if engine is back +> ✅ Zero side effects; existing config preserved +> ❌ If engine is permanently dead, retries forever; user must choose another option +> B) Switch to local PGLite (one-way — moves existing config to .bak) +> ✅ Fastest path to a working local engine if user has abandoned the old one +> ✅ ~30s; no accounts; private to this machine +> ❌ Destructive — existing config moved to ~/.gbrain/config.json.gstack-bak-{ts} +> C) Switch brain mode (continue to Step 2 path picker) +> ✅ Lets user pick Path 1/2/3/4 to re-init from scratch +> ✅ Preserves existing config until they explicitly init the new one +> ❌ Longer flow if user just wants to repair to PGLite +> D) Quit (do nothing) +> ✅ No cons — this is a hard-stop choice +> ❌ N/A +> Net: A is the right starting move; B/C are explicit destructive paths; D bails. + +**If A (Retry)**: re-run `~/.claude/skills/gstack/bin/gstack-gbrain-detect` +with `GSTACK_DETECT_NO_CACHE=1` (busts the 60s cache). If the new +`gbrain_local_status` is `ok`, continue to Step 2. If still `broken-db` or +`broken-config`, fire the same AskUserQuestion again (the user picks again). + +**If B (Switch to PGLite)** — execute the rollback-safe init sequence (plan D7): + +```bash +BACKUP="$HOME/.gbrain/config.json.gstack-bak-$(date +%s)" +mv "$HOME/.gbrain/config.json" "$BACKUP" +if ! gbrain init --pglite --json; then + # Restore on failure + mv "$BACKUP" "$HOME/.gbrain/config.json" + echo "gbrain init failed. Your previous config was restored at $HOME/.gbrain/config.json." >&2 + echo "PGLite directory at ~/.gbrain/pglite/ may be in a partial state — \`rm -rf ~/.gbrain/pglite\` if needed before retrying." >&2 + exit 1 +fi +echo "Switched to local PGLite. Previous config saved at $BACKUP — review before deleting." +``` + +Then jump to Step 5a (MCP registration; the new PGLite engine is registered as +local-stdio). + +**If C (Switch brain mode)**: continue to Step 2's normal path picker. + +**If D (Quit)**: STOP the skill cleanly. + +For `gbrain_local_status` values of `no-cli` or `missing-config`, do NOT fire +Step 1.5 — fall through to Step 2 (where `no-cli` triggers Step 3 install and +`missing-config` triggers Step 4 init). + +--- + ## Step 2: Pick a path (AskUserQuestion) Only fire this if Step 1 shows no existing working config AND no shortcut @@ -312,11 +383,60 @@ Capture two values from the verify output for downstream steps: - `URL_FORM_SUPPORTED` (`true|false`) — passed to `gstack-artifacts-init` in Step 7 to control which form of the brain-admin hookup command is printed. -**4d. Skip Steps 3, 4 (other paths), 5 (local doctor), 7.5 (transcript ingest).** -All four require a working local `gbrain` CLI that Path 4 does not install. -The skill jumps straight to Step 5a (HTTP+bearer registration) → Step 6 -(per-remote policy) → Step 7 (artifacts repo) → Step 8 (CLAUDE.md) → Step 9 -(remote smoke test) → Step 10 (verdict). +**4d. (Path 4) Offer local PGLite for code search.** Per plan D10/D11, ask: + +> D# — Want symbol-aware code search on this machine? +> Project/branch/task: +> ELI10: The remote brain at `` is great for cross-machine knowledge, +> but symbol queries like `gbrain code-def` / `code-refs` / `code-callers` need +> a local index of THIS machine's code. We can spin up a tiny isolated PGLite +> database (~30 seconds, no accounts, ~120 MB disk) just for code, separate +> from your remote brain. Transcripts and artifacts continue routing through +> the artifacts repo to the remote brain — local PGLite stays code-only. +> Stakes: without it, semantic code search in this repo's worktrees falls +> back to Grep. +> Recommendation: A — 30 seconds, no ongoing cost, unlocks the symbol tools. +> Completeness: A=10/10 (full split-engine), B=7/10 (remote-only). +> A) Yes, set up local PGLite for code (recommended) +> ✅ Unlocks `gbrain code-def`, `code-refs`, `code-callers` per worktree +> ✅ Independent engine — won't disturb remote brain or share transcripts +> B) No, remote MCP only +> ✅ Zero local state — only `~/.claude.json` MCP registration +> ❌ Symbol code queries fall back to Grep in this repo's worktrees +> Net: A = full split-engine; B = remote-only. + +**If A (Yes)**: install + init local PGLite with rollback-safe semantics (D7): + +```bash +~/.claude/skills/gstack/bin/gstack-gbrain-install || exit $? +# At this point the local gbrain CLI is on PATH. Init PGLite, but back up any +# existing ~/.gbrain/config.json first (rollback if init fails). +if [ -f "$HOME/.gbrain/config.json" ]; then + BACKUP="$HOME/.gbrain/config.json.gstack-bak-$(date +%s)" + mv "$HOME/.gbrain/config.json" "$BACKUP" +fi +if ! gbrain init --pglite --json; then + if [ -n "${BACKUP:-}" ] && [ -f "$BACKUP" ]; then mv "$BACKUP" "$HOME/.gbrain/config.json"; fi + echo "gbrain init failed. Existing config (if any) was restored. PGLite at ~/.gbrain/pglite/ may be in a partial state — \`rm -rf ~/.gbrain/pglite\` to reset." >&2 + echo "Continuing setup without local code search; you can re-run /setup-gbrain to retry." >&2 +fi +``` + +Then continue to Step 5a. The remote-http MCP registration in 5a runs as +today; the local PGLite is independent of MCP registration (Claude Code talks +to the remote brain via MCP for queries; `gbrain` CLI talks to local PGLite +for code-def/refs/callers). + +**If B (No)**: skip the install + init. The local engine stays absent. +`gbrain_local_status` will be `missing-config` (or `no-cli` if gbrain isn't +installed). `/sync-gbrain` will SKIP the code stage cleanly per plan D12. + +**4e. Skip Steps 3, 4 (other paths) and 5 (local doctor) when B was picked.** +When A was picked, Step 3 already ran (via gstack-gbrain-install) and Step 4 +already ran (via `gbrain init --pglite`); jump straight to Step 5a. When B +was picked, Steps 3/4/5 are no-ops; also skip Step 7.5 (transcript ingest) +since memory-stage routes through the artifacts pipeline in remote-http mode +per plan D11. The bearer token (`GBRAIN_MCP_TOKEN`) stays in process env until Step 5a's `claude mcp add --header` consumes it; then `unset GBRAIN_MCP_TOKEN` @@ -753,7 +873,8 @@ gbrain status: GREEN (mode: remote-http) Repo policy ..... OK {read-write|read-only|deny} Artifacts repo .. OK {gstack_artifacts_remote URL} Artifacts sync .. OK {artifacts_sync_mode} - Transcripts ..... N/A remote mode (ingest happens on brain host) + Transcripts ..... OK route to artifacts repo → remote brain (plan D11) + Code search ..... {OK local-pglite (~/.gbrain/pglite) | N/A declined at Step 4d} CLAUDE.md ....... OK Smoke test ...... INFO printed for post-restart manual verification @@ -761,6 +882,16 @@ Restart Claude Code to pick up the `mcp__gbrain__*` tools. Re-run `/setup-gbrain` any time the bearer rotates or the URL moves. ``` +The **Code search** row reflects the choice at Step 4d: +- If user picked A (Yes): `OK local-pglite` and `gbrain_local_status == "ok"` going forward. +- If user picked B (No): `N/A declined at Step 4d` — `gstack-config set local_code_index_offered true` to silence future migration notices. + +The **Transcripts** row changed in v1.34.0.0: in remote-http mode, +gstack-memory-ingest now persists staged transcripts to +`~/.gstack/transcripts/run--/` and gstack-brain-sync pushes them +to the artifacts repo. Brain admin's pull job indexes into the remote brain. +Local PGLite (when present) stays code-only — no transcript pollution. + ### Paths 1, 2a, 2b, 3 (Local stdio) ``` diff --git a/sync-gbrain/SKILL.md b/sync-gbrain/SKILL.md index afebd31f1..8dba77386 100644 --- a/sync-gbrain/SKILL.md +++ b/sync-gbrain/SKILL.md @@ -788,28 +788,20 @@ Before doing anything, check that /setup-gbrain has been run on this Mac. ~/.claude/skills/gstack/bin/gstack-gbrain-detect 2>/dev/null ``` -**Split-engine model.** Code stage always runs locally against a per-machine -PGLite brain (or whatever `gbrain config` points to), with each worktree of a -repo registered as its own source. Artifacts/memory stages route through -whatever `setup-gbrain` configured — including remote-MCP (Path 4). The two -sides are independent: code lookups are local + worktree-scoped, artifacts -remain cross-machine. +**Split-engine model (v1.34.0.0+).** Code stage runs locally against the +per-machine gbrain engine (PGLite or whatever `gbrain config` points to), +with each worktree of a repo registered as its own source. **Memory stage +also runs locally** in local-stdio MCP mode — `gstack-memory-ingest` shells +out to `gbrain import` against the same local engine. In remote-http MCP +mode (Path 4), the memory stage instead persists staged markdown to +`~/.gstack/transcripts//` and the artifacts pipeline pushes it to +the brain admin's pull job (plan D11). Brain-sync (the `gstack-brain-sync` +push to git) is the one stage that never touches local engine and runs +regardless of mode. -A previous version of this skill bounced remote-MCP users out of the code -stage entirely. That was wrong: the code-stage CLI calls (`gbrain sources -add`, `sync --strategy code`, `sources attach`) target the LOCAL gbrain CLI -+ DB regardless of whether `~/.claude.json` has `gbrain` registered as a -remote HTTP MCP for artifacts. We no longer skip the code stage in -remote-MCP mode. - -If `gbrain_on_path=false` OR `gbrain_config_exists=false`, STOP and tell -the user: - -> "/sync-gbrain requires /setup-gbrain to be run first. Run `/setup-gbrain` -> to install gbrain, register the MCP server, and set per-repo trust policy." - -Do NOT continue — the skill is unsafe when the local gbrain CLI is missing -(we'd write a CLAUDE.md guidance block referencing tools that don't exist). +Practically: local PGLite stays code-only on remote-http machines; the +remote brain holds everything else. Local-stdio machines mix code + +transcripts in one local engine, as they always have. Also check the per-repo trust policy. If `gstack-gbrain-repo-policy get` for this repo returns `deny`, STOP: @@ -819,6 +811,44 @@ this repo returns `deny`, STOP: --- +## Step 1.5: Local engine pre-flight (plan D12) + +Read `gbrain_local_status` from the Step 1 detect output. Branch as follows +BEFORE invoking the orchestrator: + +- **`ok`**: proceed to Step 2 normally. +- **`no-cli`**: STOP. "Local gbrain CLI not installed. Run `/setup-gbrain` + first." +- **`missing-config`** AND `gbrain_mcp_mode == "remote-http"`: tell the user + "Your brain queries (the `mcp__gbrain__*` tools) work via remote MCP, but + symbol code search needs a local PGLite. Run `/setup-gbrain` and pick + 'Yes' at the new 'local code index' prompt (Step 4.5), or run + `gbrain init --pglite --json` directly. Continuing without code stage." + Then proceed to Step 2 — the orchestrator's `runCodeImport()` and + `runMemoryIngest()` will return SKIP per plan D12; only `runBrainSyncPush()` + will run. Do NOT abort. +- **`missing-config`** AND `gbrain_mcp_mode != "remote-http"`: STOP. "Local + gbrain CLI is installed but no engine config. Run `/setup-gbrain` first." +- **`broken-config`** OR **`broken-db`**: STOP with a clear message: + ``` + Local gbrain config at ~/.gbrain/config.json points at an unreachable + engine (status: {gbrain_local_status}). Two options: + 1. Re-run /setup-gbrain — Step 1.5 offers Retry / Switch to PGLite / + Switch brain mode / Quit (plan D4). + 2. Repair manually: mv ~/.gbrain/config.json ~/.gbrain/config.json.bak + && gbrain init --pglite --json + Re-run /sync-gbrain after. + ``` + Do NOT continue — the orchestrator would skip code+memory and only run + brain-sync, which is a degraded state the user should fix explicitly. + +This pre-flight short-circuits the orchestrator before it spends ~80ms +probing the engine again. The orchestrator independently runs the same +classifier for defense-in-depth, but Step 1.5's STOP is where the user +gets the actionable remediation message. + +--- + ## Step 2: Run the orchestrator Pass user args to the orchestrator. Do not paraphrase them — pass through diff --git a/sync-gbrain/SKILL.md.tmpl b/sync-gbrain/SKILL.md.tmpl index f40e05052..b05c39066 100644 --- a/sync-gbrain/SKILL.md.tmpl +++ b/sync-gbrain/SKILL.md.tmpl @@ -66,28 +66,20 @@ Before doing anything, check that /setup-gbrain has been run on this Mac. ~/.claude/skills/gstack/bin/gstack-gbrain-detect 2>/dev/null ``` -**Split-engine model.** Code stage always runs locally against a per-machine -PGLite brain (or whatever `gbrain config` points to), with each worktree of a -repo registered as its own source. Artifacts/memory stages route through -whatever `setup-gbrain` configured — including remote-MCP (Path 4). The two -sides are independent: code lookups are local + worktree-scoped, artifacts -remain cross-machine. +**Split-engine model (v1.34.0.0+).** Code stage runs locally against the +per-machine gbrain engine (PGLite or whatever `gbrain config` points to), +with each worktree of a repo registered as its own source. **Memory stage +also runs locally** in local-stdio MCP mode — `gstack-memory-ingest` shells +out to `gbrain import` against the same local engine. In remote-http MCP +mode (Path 4), the memory stage instead persists staged markdown to +`~/.gstack/transcripts//` and the artifacts pipeline pushes it to +the brain admin's pull job (plan D11). Brain-sync (the `gstack-brain-sync` +push to git) is the one stage that never touches local engine and runs +regardless of mode. -A previous version of this skill bounced remote-MCP users out of the code -stage entirely. That was wrong: the code-stage CLI calls (`gbrain sources -add`, `sync --strategy code`, `sources attach`) target the LOCAL gbrain CLI -+ DB regardless of whether `~/.claude.json` has `gbrain` registered as a -remote HTTP MCP for artifacts. We no longer skip the code stage in -remote-MCP mode. - -If `gbrain_on_path=false` OR `gbrain_config_exists=false`, STOP and tell -the user: - -> "/sync-gbrain requires /setup-gbrain to be run first. Run `/setup-gbrain` -> to install gbrain, register the MCP server, and set per-repo trust policy." - -Do NOT continue — the skill is unsafe when the local gbrain CLI is missing -(we'd write a CLAUDE.md guidance block referencing tools that don't exist). +Practically: local PGLite stays code-only on remote-http machines; the +remote brain holds everything else. Local-stdio machines mix code + +transcripts in one local engine, as they always have. Also check the per-repo trust policy. If `gstack-gbrain-repo-policy get` for this repo returns `deny`, STOP: @@ -97,6 +89,44 @@ this repo returns `deny`, STOP: --- +## Step 1.5: Local engine pre-flight (plan D12) + +Read `gbrain_local_status` from the Step 1 detect output. Branch as follows +BEFORE invoking the orchestrator: + +- **`ok`**: proceed to Step 2 normally. +- **`no-cli`**: STOP. "Local gbrain CLI not installed. Run `/setup-gbrain` + first." +- **`missing-config`** AND `gbrain_mcp_mode == "remote-http"`: tell the user + "Your brain queries (the `mcp__gbrain__*` tools) work via remote MCP, but + symbol code search needs a local PGLite. Run `/setup-gbrain` and pick + 'Yes' at the new 'local code index' prompt (Step 4.5), or run + `gbrain init --pglite --json` directly. Continuing without code stage." + Then proceed to Step 2 — the orchestrator's `runCodeImport()` and + `runMemoryIngest()` will return SKIP per plan D12; only `runBrainSyncPush()` + will run. Do NOT abort. +- **`missing-config`** AND `gbrain_mcp_mode != "remote-http"`: STOP. "Local + gbrain CLI is installed but no engine config. Run `/setup-gbrain` first." +- **`broken-config`** OR **`broken-db`**: STOP with a clear message: + ``` + Local gbrain config at ~/.gbrain/config.json points at an unreachable + engine (status: {gbrain_local_status}). Two options: + 1. Re-run /setup-gbrain — Step 1.5 offers Retry / Switch to PGLite / + Switch brain mode / Quit (plan D4). + 2. Repair manually: mv ~/.gbrain/config.json ~/.gbrain/config.json.bak + && gbrain init --pglite --json + Re-run /sync-gbrain after. + ``` + Do NOT continue — the orchestrator would skip code+memory and only run + brain-sync, which is a degraded state the user should fix explicitly. + +This pre-flight short-circuits the orchestrator before it spends ~80ms +probing the engine again. The orchestrator independently runs the same +classifier for defense-in-depth, but Step 1.5's STOP is where the user +gets the actionable remediation message. + +--- + ## Step 2: Run the orchestrator Pass user args to the orchestrator. Do not paraphrase them — pass through