---
name: sync-gbrain
description: 'Keep gbrain current with this repo''s code and refresh agent search
  guidance in CLAUDE.md. Wraps the gstack-gbrain-sync orchestrator with state probing,
  native code-surface registration, capability checks, and a verdict block. Re-runnable,
  idempotent. Use when: "sync gbrain", "refresh gbrain", "re-index this repo", "gbrain
  search isn''t finding things". (gstack)'
---

## Skill routing

When the user's request matches an available skill, invoke it via the Skill tool. When in doubt, invoke the skill.

Key routing rules:
- Product ideas/brainstorming → invoke /office-hours
- Strategy/scope → invoke /plan-ceo-review
- Architecture → invoke /plan-eng-review
- Design system/plan review → invoke /design-consultation or /plan-design-review
- Full review pipeline → invoke /autoplan
- Bugs/errors → invoke /investigate
- QA/testing site behavior → invoke /qa or /qa-only
- Code review/diff check → invoke /review
- Visual polish → invoke /design-review
- Ship/deploy/PR → invoke /ship or /land-and-deploy
- Save progress → invoke /context-save
- Resume context → invoke /context-restore
```

Then commit the change: `git add CLAUDE.md && git commit -m "chore: add gstack skill routing rules to CLAUDE.md"`

If B: run `~/.claude/skills/gstack/bin/gstack-config set routing_declined true` and say they can re-enable with `gstack-config set routing_declined false`.

This only happens once per project. Skip if `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`.

If `VENDORED_GSTACK` is `yes`, warn once via AskUserQuestion unless `~/.gstack/.vendoring-warned-$SLUG` exists:

> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated.
> Migrate to team mode?

Options:
- A) Yes, migrate to team mode now
- B) No, I'll handle it myself

If A:
1. Run `git rm -r .claude/skills/gstack/`
2. Run `echo '.claude/skills/gstack/' >> .gitignore`
3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`)
4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"`
5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`"

If B: say "OK, you're on your own to keep the vendored copy up to date."

Always run (regardless of choice):
```bash
eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true
touch ~/.gstack/.vendoring-warned-${SLUG:-unknown}
```

If marker exists, skip.

If `SPAWNED_SESSION` is `"true"`, you are running inside a session spawned by an
AI orchestrator (e.g., OpenClaw). In spawned sessions:
- Do NOT use AskUserQuestion for interactive prompts. Auto-choose the recommended option.
- Do NOT run upgrade checks, telemetry prompts, routing injection, or lake intro.
- Focus on completing the task and reporting results via prose output.
- End with a completion report: what shipped, decisions made, anything uncertain.

## User-invocable

When the user types `/sync-gbrain`, run this skill. Argument modes (parsed by
the skill itself, not a dispatcher binary):

- `/sync-gbrain` — incremental sync (default; mtime fast-path; ~50ms steady-state)
- `/sync-gbrain --full` — full code reindex via `gbrain reindex-code` (~25-35 min on a big repo)
- `/sync-gbrain --code-only` — only run the code stage; skip memory + brain-sync
- `/sync-gbrain --dry-run` — preview what would sync; no writes anywhere
- `/sync-gbrain --no-memory` / `--no-brain-sync` — selectively skip stages
- `/sync-gbrain --quiet` — suppress per-stage output

Pass-through args go straight to the orchestrator at
`~/.claude/skills/gstack/bin/gstack-gbrain-sync.ts`.

---

## Step 1: State probe

Before doing anything, check that /setup-gbrain has been run on this Mac.

```bash
~/.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.

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).

Also check the per-repo trust policy. If `gstack-gbrain-repo-policy get` for
this repo returns `deny`, STOP:

> "This repo's gbrain trust policy is `deny`. Run `/setup-gbrain --repo` to
> change it before syncing."

---

## Step 2: Run the orchestrator

Pass user args to the orchestrator. Do not paraphrase them — pass through
as-is.

```bash
bun run ~/.claude/skills/gstack/bin/gstack-gbrain-sync.ts <user-args>
```

The orchestrator runs three stages: code → memory → brain-sync (per the
plan's storage tiering). Each stage failure is non-fatal; subsequent stages
still run. State is persisted to `~/.gstack/.gbrain-sync-state.json` via
tmp-file + atomic rename. Concurrent runs are blocked by a lock file at
`~/.gstack/.sync-gbrain.lock` (5-min stale-takeover).

---

## Step 3: Code-index health check

After the sync run, query gbrain for the cwd source's page_count:

```bash
SOURCE_ID=$(grep -o '"source_id":"[^"]*"' ~/.gstack/.gbrain-sync-state.json 2>/dev/null \
  | head -1 | sed 's/.*"source_id":"//;s/".*//')
PAGES=$(gbrain sources list --json 2>/dev/null \
  | jq -r --arg id "$SOURCE_ID" '.sources[] | select(.id==$id) | .page_count' 2>/dev/null \
  || echo 0)
echo "cwd source: $SOURCE_ID, page_count: $PAGES"
```

If `PAGES` is 0 or empty AND the user did NOT pass `--no-code` AND mode was
not `--full`, AskUserQuestion via the format in the preamble:

> D1 — This repo has 0 indexed pages in gbrain. Run a full code reindex now?
>
> ELI10: gbrain hasn't indexed this repo's code yet. The semantic search
> tools (`gbrain search`, `code-def`, `code-refs`) will return nothing
> until we run a full pass. Takes ~25-35 minutes on a big Mac.
>
> Recommendation: A — the brain is unusable for code search until indexed,
> and Step 2 of this skill already verified gbrain is configured correctly.
>
> Note: options differ in kind, not coverage — no completeness score.
>
> A) Run /sync-gbrain --full now (recommended)
> B) Skip — I'll run it later

If A: re-invoke the orchestrator with `--full --code-only`.
If B: continue to Step 4 with the empty-corpus state recorded.

---

## Step 4: Refresh `## GBrain Search Guidance` block in CLAUDE.md

Capability check (per /plan-eng-review §6):

```bash
SLUG="_capability_check_$$"
if [ -f ~/.gbrain/config.json ] && \
   gbrain --version 2>/dev/null | grep -q '^gbrain ' && \
   echo "ping" | gbrain put "$SLUG" >/dev/null 2>&1 && \
   gbrain search "ping" 2>/dev/null | grep -q "$SLUG"; then
  CAPABILITY_OK=1
else
  CAPABILITY_OK=0
fi
gbrain delete "$SLUG" 2>/dev/null || true
```

Then update CLAUDE.md based on capability state:

**If `CAPABILITY_OK=1`** — write or update the block. Idempotent: find the
HTML-comment-delimited block; replace its body if it exists; append at the
end of CLAUDE.md if it doesn't. NEVER duplicate. Block is machine-AGNOSTIC
(no engine, no page counts, no last-sync time — those are in the existing
`## GBrain Configuration` block).

Verbatim block content (copy exactly):

```markdown
## GBrain Search Guidance (configured by /sync-gbrain)
<!-- gstack-gbrain-search-guidance:start -->

GBrain is set up and synced on this machine. The agent should prefer gbrain
over Grep when the question is semantic or when you don't know the exact
identifier yet.

**This worktree is pinned to a worktree-scoped code source** via the
`.gbrain-source` file in the repo root (kubectl-style context). Any
`gbrain code-def`, `code-refs`, `code-callers`, `code-callees`, or `query`
call from anywhere under this worktree routes to that source by default —
no `--source` flag needed. Conductor sibling worktrees of the same repo
each have their own pin and their own indexed pages, so semantic results
match the actual code on disk in this worktree.

Two indexed corpora available via the `gbrain` CLI:
- This worktree's code (auto-pinned via `.gbrain-source`).
- `~/.gstack/` curated memory (registered as `gstack-brain-<user>` source via
  the existing federation pipeline).

Prefer gbrain when:
- "Where is X handled?" / semantic intent, no exact string yet:
    `gbrain search "<terms>"` or `gbrain query "<question>"`
- "Where is symbol Y defined?" / symbol-based code questions:
    `gbrain code-def <symbol>` or `gbrain code-refs <symbol>`
- "What calls Y?" / "What does Y depend on?":
    `gbrain code-callers <symbol>` / `gbrain code-callees <symbol>`
- "What did we decide last time?" / past plans, retros, learnings:
    `gbrain search "<terms>" --source gstack-brain-<user>`

Grep is still right for known exact strings, regex, multiline patterns, and
file globs. Run `/sync-gbrain` after meaningful code changes; for ongoing
auto-sync across all worktrees, run `gbrain autopilot --install` once per
machine — gbrain's daemon handles incremental refresh on a schedule.

<!-- gstack-gbrain-search-guidance:end -->
```

Use the Read + Edit tools. The find-and-replace target is the entire region
from `<!-- gstack-gbrain-search-guidance:start -->` through
`<!-- gstack-gbrain-search-guidance:end -->`. If those markers are missing,
search for `## GBrain Search Guidance (configured by /sync-gbrain)` heading
and replace from there to the next `## ` or EOF. If no heading exists, append
the entire block at the end of CLAUDE.md.

**Atomic write:** write the new CLAUDE.md content to a tmp file alongside it
(e.g., `CLAUDE.md.sync-gbrain.tmp`) then `mv` to atomic-rename, so a crash
mid-write never leaves the file half-modified.

**If `CAPABILITY_OK=0`** — REMOVE the block entirely if present. Use the same
Edit tool to strip the start/end-marker region. The `## GBrain Configuration`
block stays in place (it's a record of the install, not a capability claim).

Do NOT crash if CLAUDE.md is missing or unwritable — log a warning and
continue.

---

## Step 5: Verdict block (idempotent doctor output)

Print a status block matching `/setup-gbrain` Step 10 conventions. Each row
is `[OK]/[FIX]/[WARN]/[ERR]`. Reuse `gbrain doctor --json --fast` for
informational rows but DO NOT gate the guidance block on doctor (per
/plan-eng-review §6 — doctor is too strict for unrelated reasons).

```
gbrain status: GREEN

  CLI ............. OK   <gbrain version>
  Engine .......... OK   <pglite|supabase>
  Capability ...... OK   write+search round-trip
  CWD source ...... OK   <gstack-code-{repo_slug}> (page_count=<N>)
  ~/.gstack source. OK   <gstack-brain-{user}> (page_count=<N>) — managed by /setup-gbrain
  Memory sync ..... OK   <artifacts_sync_mode>
  CLAUDE.md ....... OK   ## GBrain Search Guidance present
  Last sync ....... OK   <last_sync from state file>

Run `/sync-gbrain` again any time gbrain feels off; safe and idempotent.
```

If any row is YELLOW or RED, the verdict line says so and the failing rows
surface a one-line "next action" (e.g., `Capability ...... ERR  capability
check failed; CLAUDE.md guidance block REMOVED — run /setup-gbrain to repair`).

---

## Concurrency note

This skill is safe to run concurrently from multiple terminals on the same
Mac. The orchestrator acquires a lock at `~/.gstack/.sync-gbrain.lock` before
any state-file or CLAUDE.md mutation and exits with code 2 if another sync is
in flight. Stale locks (process died) auto-clear after 5 minutes.

## Cross-machine note

The `## GBrain Search Guidance` block is committed to the repo's CLAUDE.md
and travels with `git push`/`git pull` — NOT through `~/.gstack/.brain-allowlist`
(which is for `~/.gstack/` brain-sync only). On a different Mac with a synced
CLAUDE.md but no local gbrain, /sync-gbrain detects the mismatch via the
capability check and REMOVES the block (the local agent shouldn't be told to
use a tool that isn't installed).

## Status reporting

End with a Completion Status (per the preamble protocol):
- **DONE** — all stages green, CLAUDE.md guidance block present, verdict GREEN.
- **DONE_WITH_CONCERNS** — sync ran but at least one stage failed or capability
  check failed. List which.
- **BLOCKED** — could not acquire lock, gbrain not on PATH, or per-repo policy
  is deny. State the blocker.
- **NEEDS_CONTEXT** — /setup-gbrain has not been run, or `gbrain doctor` shows
  a state that requires user decision (e.g., engine migration).
