v1.29.0.0 feat: worktree-aware gbrain code sources via path-hash IDs and CWD pin (#1382)

* feat: worktree-aware gbrain code sources via path-hash IDs and CWD pin

Conductor sibling worktrees of the same repo no longer collide on a shared
gstack-code-<slug> source ID. /sync-gbrain now derives a path-hashed source
ID per worktree, runs gbrain sources attach to write .gbrain-source in the
worktree root, and removes the legacy unsuffixed source on first new-format
sync to prevent orphan accumulation.

Bug fixes surfaced by /codex during /ship:
- Silent attach failure now treated as stage failure (no more ok:true while
  pin is missing → unqualified code-def hits wrong source).
- Startup preamble checks .gbrain-source in the cwd worktree, not global
  state, so an unsynced worktree no longer claims "indexed" because a
  sibling synced.
- Code stage no longer skipped on remote-MCP (Path 4); the early-exit was
  in the SKILL template, not the orchestrator.
- Source registration routes through lib/gbrain-sources.ts only; deleted
  the near-duplicate ensureSourceRegisteredSync from the orchestrator.

Requires gbrain v0.30.0+ (uses sources attach). Phase 0 spike report:
~/.gstack/projects/garrytan-gstack/2026-05-08-gbrain-split-engine-spike.md

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* chore: bump version and changelog (v1.29.0.0)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-05-08 12:46:15 -07:00
committed by GitHub
parent 443bde054c
commit 06605477e2
49 changed files with 928 additions and 721 deletions

View File

@@ -46,30 +46,29 @@ _BRAIN_SYNC_BIN="${ctx.paths.binDir}/gstack-brain-sync"
_BRAIN_CONFIG_BIN="${ctx.paths.binDir}/gstack-config"
# /sync-gbrain context-load: teach the agent to use gbrain when it's available.
# Mutually exclusive variants per /plan-eng-review §4. Empty string when gbrain
# is not configured (zero context cost for non-gbrain users).
# Per-worktree pin: post-spike redesign uses kubectl-style \`.gbrain-source\` in the
# git toplevel to scope queries. Look for the pin in the worktree (not a global
# state file) so that opening worktree B without a pin doesn't claim "indexed"
# just because worktree A was synced. Empty string when gbrain is not
# configured (zero context cost for non-gbrain users).
_GBRAIN_CONFIG="$HOME/.gbrain/config.json"
if [ -f "$_GBRAIN_CONFIG" ] && command -v gbrain >/dev/null 2>&1; then
_GBRAIN_VERSION_OK=$(gbrain --version 2>/dev/null | grep -c '^gbrain ' || echo 0)
if [ "$_GBRAIN_VERSION_OK" -gt 0 ] 2>/dev/null; then
_SYNC_STATE="$_GSTACK_HOME/.gbrain-sync-state.json"
_CWD_PAGES=0
if [ -f "$_SYNC_STATE" ]; then
# Flatten newlines so the regex works against pretty-printed JSON too.
_CWD_PAGES=$(tr -d '\\n' < "$_SYNC_STATE" 2>/dev/null \\
| grep -o '"name": *"code"[^}]*"detail": *{[^}]*"page_count": *[0-9]*' \\
| grep -o '"page_count": *[0-9]*' | grep -o '[0-9]\\+' | head -1)
_CWD_PAGES=\${_CWD_PAGES:-0}
_GBRAIN_PIN_PATH=""
_REPO_TOP=$(git rev-parse --show-toplevel 2>/dev/null || echo "")
if [ -n "$_REPO_TOP" ] && [ -f "$_REPO_TOP/.gbrain-source" ]; then
_GBRAIN_PIN_PATH="$_REPO_TOP/.gbrain-source"
fi
if [ "$_CWD_PAGES" -gt 0 ] 2>/dev/null; then
if [ -n "$_GBRAIN_PIN_PATH" ]; then
echo "GBrain configured. Prefer \\\`gbrain search\\\`/\\\`gbrain query\\\` over Grep for"
echo "semantic questions; use \\\`gbrain code-def\\\`/\\\`code-refs\\\`/\\\`code-callers\\\` for"
echo "symbol-aware code lookup. See \\"## GBrain Search Guidance\\" in CLAUDE.md."
echo "Run /sync-gbrain to refresh."
else
echo "GBrain configured but this repo isn't indexed yet. Run \\\`/sync-gbrain --full\\\`"
echo "before relying on \\\`gbrain search\\\` for code questions in this repo."
echo "Falls back to Grep until indexed."
echo "GBrain configured but this worktree isn't pinned yet. Run \\\`/sync-gbrain --full\\\`"
echo "before relying on \\\`gbrain search\\\` for code questions in this worktree."
echo "Falls back to Grep until pinned."
fi
fi
fi