name: sync-gbrain preamble-tier: 2 version: 1.0.0 description: | Keep gbrain current with this repo's code and refresh agent search guidance in AGENTS.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) triggers:
- sync gbrain
- refresh gbrain
- reindex repo
- update gbrain allowed-tools:
- Bash
- Read
- Write
- Edit
- Glob
- Grep
- ask the user in chat
{{PREAMBLE}}
/skill:sync-gbrain — Keep gbrain current and teach the agent to use it
You are running the canonical "keep this brain up to date" verb. /skill:setup-gbrain
installs gbrain once; /skill:sync-gbrain runs every time the user wants the brain
refreshed against this repo's current state, and refreshes the agent-side
guidance in AGENTS.md so the coding agent knows when to prefer gbrain
search over Grep.
Architecture (post-codex review): This skill uses gbrain v0.20.0+'s
native code surfaces (gbrain sources add, gbrain sync --strategy code,
gbrain reindex-code, gbrain code-def/code-refs/code-callers/code-callees).
It does NOT use gbrain import (that path is for markdown directories).
It does NOT touch ~/.gstack/ indexing (the existing gstack-gbrain-source-wireup
owns that — never double-store).
User-invocable
When the user types /skill:sync-gbrain, run this skill. Argument modes (parsed by
the skill itself, not a dispatcher binary):
/skill:sync-gbrain— incremental sync (default; mtime fast-path; ~50ms steady-state)/skill:sync-gbrain --full— full code reindex viagbrain reindex-code(~25-35 min on a big repo). Auto-builds the call graph (gbrain dream) only when it was never built./skill:sync-gbrain --dream— build this source's call graph (gbrain code-callers/code-callees) via a source-scopedgbrain dream --source <id>cycle; ~minutes; runs lock-free after the sync stages. Always forces, even if already built. Only produces a graph on a code-aware schema pack; otherwise the run reports a WARN explaining why the graph is still empty./skill:sync-gbrain --no-dream— skip the dream cycle that--fullwould otherwise auto-run./skill:sync-gbrain --code-only— only run the code stage; skip memory + brain-sync/skill:sync-gbrain --dry-run— preview what would sync; no writes anywhere/skill:sync-gbrain --no-memory/--no-brain-sync— selectively skip stages/skill:sync-gbrain --quiet— suppress per-stage output/skill:sync-gbrain --refresh-cache— force-rebuild brain-aware planning cache (v1.48; replaces /brain-refresh-context per D1 fold). Skips code + memory stages; routes togstack-brain-cache refresh --project <slug>./skill:sync-gbrain --audit— emit summary of gstack-owned pages per project + sensitive-content audit (v1.48 / D10 lifecycle). Read-only.
Pass-through args go straight to the orchestrator at
{{BIN_DIR}}/gstack-gbrain-sync.ts.
--refresh-cache short-circuit: when this flag is present, the skill
runs ONLY the cache refresh (gstack-brain-cache refresh --project <slug>
for the current worktree's slug, plus a cross-project refresh of
user-profile if gstack/user-profile/<user-slug> exists). Code +
memory + brain-sync stages are skipped. Useful when the user knows the
brain has new info gstack should pick up before the next planning skill.
--audit short-circuit: when this flag is present, the skill runs
gstack-brain-cache list --project <slug> --json, summarizes by page
type, then scans for any cached salience entries that ended up outside
the SALIENCE_DEFAULT_ALLOWLIST (T17 / D9 leak check). Read-only; no
modifications to brain or cache.
Step 1: State probe
Before doing anything, check that /skill:setup-gbrain has been run on this Mac.
~/.pi/agent/skills/gstack/bin/gstack-gbrain-detect 2>/dev/null
Brain trust policy gate (v1.48 / Phase 1.5 / D4 — added by T13+T5c):
If gbrain_mcp_mode == "remote-http" from the detect output AND the per-
endpoint policy is unset, the policy question MUST fire here before
the orchestrator runs. Local engines auto-set to personal silently per
the per-transport default table.
_HASH=$(~/.pi/agent/skills/gstack/bin/gstack-config endpoint-hash 2>/dev/null)
_POLICY=$(~/.pi/agent/skills/gstack/bin/gstack-config get brain_trust_policy@$_HASH 2>/dev/null || echo unset)
echo "BRAIN_TRUST_POLICY[$_HASH]: $_POLICY"
If _POLICY == "unset" AND _HASH != "local", ask the user in chat per the
Step 9.5 wording in /skill:setup-gbrain (personal vs shared, with persistence
to brain_trust_policy@<hash> and conditional artifacts_sync_mode=full
flip for personal). Then continue.
If _POLICY == "unset" AND _HASH == "local", auto-set personal:
~/.pi/agent/skills/gstack/bin/gstack-config set brain_trust_policy@$_HASH personal
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/<run-id>/ 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.
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:
"This repo's gbrain trust policy is
deny. Run/skill:setup-gbrain --repoto change it before syncing."
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.timeout: proceed to Step 2 — the engine is most likely healthy but slow (cold pooler connection, #1964). Tell the user in one line: "Engine probe timed out (>15s) — proceeding; raiseGSTACK_GBRAIN_PROBE_TIMEOUT_MSif your pooler is slow." Do NOT treat this as a broken config.engine-locked: STOP. "The local PGLite database is busy, usually becausegbrain servefrom a live Claude session owns it. Stop that process or run/skill:sync-gbrainoutside the live session, then retry. This identifies the conflict but does not remove PGLite's single-process limit."no-cli: STOP. "Local gbrain CLI not installed. Run/skill:setup-gbrainfirst."missing-configANDgbrain_mcp_mode == "remote-http": tell the user "Your brain queries (themcp__gbrain__*tools) work via remote MCP, but symbol code search needs a local PGLite. Run/skill:setup-gbrainand pick 'Yes' at the new 'local code index' prompt (Step 4.5), or rungbrain init --pglite --json --embedding-model voyage:voyage-code-3 --embedding-dimensions 1024directly (drop the voyage flags ifVOYAGE_API_KEYisn't set). Continuing without code stage." Then proceed to Step 2 — the orchestrator'srunCodeImport()andrunMemoryIngest()will return SKIP per plan D12; onlyrunBrainSyncPush()will run. Do NOT abort.missing-configANDgbrain_mcp_mode != "remote-http": STOP. "Local gbrain CLI is installed but no engine config. Run/skill:setup-gbrainfirst."broken-configORbroken-db: STOP with a clear message:
Do NOT continue — the orchestrator would skip code+memory and only run brain-sync, which is a degraded state the user should fix explicitly.Local gbrain config at ~/.gbrain/config.json points at an unreachable engine (status: {gbrain_local_status}). Two options: 1. Re-run /skill: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 --embedding-model voyage:voyage-code-3 \ --embedding-dimensions 1024 (drop voyage flags if VOYAGE_API_KEY unset) Re-run /skill:sync-gbrain after.
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 as-is.
bun run ~/.pi/agent/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:
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, ask the user in chat 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 /skill: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 3.5: Call-graph health check (offer --dream)
gbrain code-callers / code-callees (who-calls-this / what-this-calls) return
count: 0 until a gbrain dream cycle runs the resolve_symbol_edges phase for
this source — not done by the code import in Step 2.
One hard prerequisite: building a call graph requires this source's active
schema pack to extract code symbols (the extract_atoms phase). On a pack
that doesn't declare it (e.g. gbrain-base / gbrain-base-v2), a dream cycle
completes but resolve_symbol_edges matches nothing — the graph stays empty no
matter how many times you run it. So "build the call graph" is only meaningful on
a code-aware pack. The --dream stage detects this and reports it honestly
(a WARN row) rather than claiming a build that didn't happen. gbrain exposes pack
capability only at cycle runtime (no pre-flight query as of 0.41.x), so we can't
detect it before running. code-def / code-refs need the same symbol
extraction; they are NOT free "direct lookups" on a non-code-aware pack.
Detect whether this source's call graph is built via doctor's cycle_freshness
check, matching the cwd SOURCE_ID literally:
SOURCE_ID=$(grep -o '"source_id":"[^"]*"' ~/.gstack/.gbrain-sync-state.json 2>/dev/null \
| head -1 | sed 's/.*"source_id":"//;s/".*//')
CYCLE=$(gbrain doctor --json --fast 2>/dev/null \
| jq -r --arg id "$SOURCE_ID" '
(.checks[] | select(.name=="cycle_freshness")) as $c
| if $c.status=="ok" then "completed"
elif ($c.message | index($id)) then "never"
else "unknown" end' 2>/dev/null || echo unknown)
# index($id) = literal substring (NOT test() regex), matching the lib reader in
# cycleCompleted(). A fail/warn that doesn't name this source → "unknown" (don't
# mask other-source failures).
echo "call graph for $SOURCE_ID: $CYCLE"
If CYCLE == never AND the user did NOT pass --dream/--full AND Step 3
PAGES > 0, ask the user in chat via the format in the preamble:
D2 — This repo's call graph isn't built. Build it now?
ELI10:
gbrain code-callers/code-callees(who calls this function / what it calls) return nothing until theresolve_symbol_edgesphase runs for this source.gbrain dream --source <this source>runs it (scoped to this worktree's code, takes a few minutes). It only produces a graph if this source's schema pack extracts code symbols; if it doesn't, the run completes but the graph stays empty and the dream row will say so.Recommendation: A — call-graph queries return 0 until this runs, and the code index is already populated. If A comes back as a WARN ("pack does not extract code symbols"), the fix is a code-aware schema pack, not re-running dream.
Note: options differ in kind, not coverage — no completeness score.
A) Run /skill:sync-gbrain --dream now (recommended) B) Skip — I'll run it later
If A: re-invoke the orchestrator with --dream --code-only (skips memory +
brain-sync; the dream stage still runs because it's gated on --dream). Then
report the dream stage's ACTUAL row — OK call graph built (N edges) vs a
WARN that names why the graph is still empty (non-code-aware pack, missing
embedding key, or 0 edges matched). Do not claim success on a WARN.
If B: continue to Step 4 with the call-graph-not-built state recorded for the
verdict.
If CYCLE == completed or unknown, do not prompt — but note completed means
only that a cycle has run, not that edges exist (a non-code-aware pack reports
completed with an empty graph). Step 5's verdict row surfaces the real state.
Step 4: Refresh ## GBrain Search Guidance block in AGENTS.md
Capability check (per /skill:plan-eng-review §6):
SLUG="_capability_check_$$"
CAPABILITY_OK=0
if [ -f ~/.gbrain/config.json ] && \
gbrain --version 2>/dev/null | grep -q '^gbrain '; then
# Do NOT export GBRAIN_PREPARE here (#1965). gbrain auto-disables prepared
# statements on transaction-mode poolers (port 6543) — forcing them on
# breaks every write with "prepared statement does not exist". Users on a
# session-mode pooler at 6543 can set GBRAIN_PREPARE=true themselves (the
# gbrain banner documents this override).
if echo "ping" | gbrain put "$SLUG" >/dev/null 2>&1; then
# Retry search up to 3 times with 1s delay — under transaction-mode
# pooling the search index may not be visible on the next connection
# immediately after the put.
for _attempt in 1 2 3; do
if gbrain search "ping" 2>/dev/null | grep -q "$SLUG"; then
CAPABILITY_OK=1
break
fi
sleep 1
done
fi
fi
gbrain delete "$SLUG" 2>/dev/null || true
Then update AGENTS.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 AGENTS.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):
## GBrain Search Guidance (configured by /skill: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).
`gbrain code-def`, `code-refs`, `code-callers`, `code-callees`, `search`, and
`query` from anywhere under this worktree route to that source by default —
no `--source` flag needed (gbrain >= 0.41.38.0; on older gbrain the call-graph
commands need `--source "$(cat .gbrain-source)"`). Conductor sibling worktrees
of the same repo each have their own pin and their own indexed pages, so
semantic results match the code on disk here.
Call-graph queries (`code-callers`/`code-callees`) also need the graph to be
built first — run `/skill:sync-gbrain --dream` (or `--full`) if they return
`count: 0`. This only works if this source's gbrain schema pack extracts code
symbols; on a non-code-aware pack `--dream` completes but the graph stays empty
and reports a WARN. `code-def`/`code-refs` need the same extraction.
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 `/skill: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.
Safety: don't run `/skill:sync-gbrain` while `gbrain autopilot` is active — the
orchestrator refuses destructive source ops when it detects a running autopilot
to avoid racing it (#1734). Prefer registering user repos with `gbrain sources
add --path <dir>` (no `--url`): URL-managed sources can auto-reclone, and the
sync code walk for them requires an explicit `--allow-reclone` opt-in.
<!-- 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 /skill:sync-gbrain) heading
and replace from there to the next ## or EOF. If no heading exists, append
the entire block at the end of AGENTS.md.
Atomic write: write the new AGENTS.md content to a tmp file alongside it
(e.g., AGENTS.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 AGENTS.md is missing or unwritable — log a warning and continue.
Step 5: Verdict block (idempotent doctor output)
Print a status block matching /skill: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
/skill: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>)
Call graph ...... OK <N> edges resolved (code-callers/callees live)
~/.gstack source. OK <gstack-brain-{user}> (page_count=<N>) — managed by /skill:setup-gbrain
Memory sync ..... OK <artifacts_sync_mode>
AGENTS.md ....... OK ## GBrain Search Guidance present
Last sync ....... OK <last_sync from state file>
Run `/skill:sync-gbrain` again any time gbrain feels off; safe and idempotent.
The Call graph row reports the most authoritative signal available:
- If a dream stage ran this invocation (
--dream, or--fullauto-build), mirror its row verbatim — it's the ground truth for this run:OK <N> edges resolved (code-callers/callees live)WARN dream ran but this source's schema pack does not extract code symbols — switch to a code-aware pack (\gbrain schema use <pack>`)`WARN dream ran but the embed phase failed (missing embedding key)WARN dream ran but resolved 0 edges (no code symbols matched yet)
- Otherwise fall back to the
CYCLEvalue from Step 3.5, with honest wording (a completed cycle proves a cycle ran, NOT that edges exist):completed→OK cycle complete — code-callers/callees live IF this source's pack extracts code symbolsnever→WARN call graph not built — run /skill:sync-gbrain --dreamunknown→WARN could not probe call graph (doctor unavailable) — run /skill:sync-gbrain --dream if code-callers returns 0
Any WARN Call graph row flips the verdict to YELLOW.
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; AGENTS.md guidance block REMOVED — run /skill:setup-gbrain to repair).
A never/unknown Call graph row flips the verdict to YELLOW.
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 AGENTS.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 AGENTS.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
AGENTS.md but no local gbrain, /skill: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, AGENTS.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 — /skill:setup-gbrain has not been run, or
gbrain doctorshows a state that requires user decision (e.g., engine migration).
Expert Next.js App Router
Developpement
Un skill qui transforme Claude en expert Next.js App Router.
Générateur de README
Developpement
Crée des README.md professionnels et complets pour vos projets.
Rédacteur de Documentation API
Developpement
Génère de la documentation API complète au format OpenAPI/Swagger.