diff --git a/sync-gbrain/SKILL.md b/sync-gbrain/SKILL.md index ffb05ddb9..9c34315f9 100644 --- a/sync-gbrain/SKILL.md +++ b/sync-gbrain/SKILL.md @@ -742,7 +742,9 @@ 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 --full` — full code reindex via `gbrain reindex-code` (~25-35 min on a big repo). Auto-builds the call graph (`gbrain dream`) **only when it was never built**. +- `/sync-gbrain --dream` — build this source's call graph (`gbrain code-callers`/`code-callees`) via a source-scoped `gbrain dream --source ` 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. +- `/sync-gbrain --no-dream` — skip the dream cycle that `--full` would otherwise auto-run. - `/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 @@ -877,6 +879,76 @@ 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: + +```bash +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`, AskUserQuestion 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 the `resolve_symbol_edges` phase runs for this +> source. `gbrain dream --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 /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 CLAUDE.md Capability check (per /plan-eng-review §6): @@ -925,12 +997,19 @@ 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. +`.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 `/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`). @@ -989,6 +1068,7 @@ gbrain status: GREEN Engine .......... OK Capability ...... OK write+search round-trip CWD source ...... OK (page_count=) + Call graph ...... OK edges resolved (code-callers/callees live) ~/.gstack source. OK (page_count=) — managed by /setup-gbrain Memory sync ..... OK CLAUDE.md ....... OK ## GBrain Search Guidance present @@ -997,9 +1077,27 @@ gbrain status: GREEN Run `/sync-gbrain` again any time gbrain feels off; safe and idempotent. ``` +The **Call graph** row reports the most authoritative signal available: + +1. **If a dream stage ran this invocation** (`--dream`, or `--full` auto-build), + mirror its row verbatim — it's the ground truth for this run: + - `OK 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 \`)` + - `WARN dream ran but the embed phase failed (missing embedding key)` + - `WARN dream ran but resolved 0 edges (no code symbols matched yet)` +2. **Otherwise** fall back to the `CYCLE` value 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 symbols` + - `never` → `WARN call graph not built — run /sync-gbrain --dream` + - `unknown` → `WARN could not probe call graph (doctor unavailable) — run /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; CLAUDE.md guidance block REMOVED — run /setup-gbrain to repair`). +A `never`/`unknown` Call graph row flips the verdict to YELLOW. --- diff --git a/sync-gbrain/SKILL.md.tmpl b/sync-gbrain/SKILL.md.tmpl index 8c9151038..3f52ff22e 100644 --- a/sync-gbrain/SKILL.md.tmpl +++ b/sync-gbrain/SKILL.md.tmpl @@ -47,7 +47,9 @@ 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 --full` — full code reindex via `gbrain reindex-code` (~25-35 min on a big repo). Auto-builds the call graph (`gbrain dream`) **only when it was never built**. +- `/sync-gbrain --dream` — build this source's call graph (`gbrain code-callers`/`code-callees`) via a source-scoped `gbrain dream --source ` 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. +- `/sync-gbrain --no-dream` — skip the dream cycle that `--full` would otherwise auto-run. - `/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 @@ -182,6 +184,76 @@ 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: + +```bash +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`, AskUserQuestion 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 the `resolve_symbol_edges` phase runs for this +> source. `gbrain dream --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 /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 CLAUDE.md Capability check (per /plan-eng-review §6): @@ -230,12 +302,19 @@ 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. +`.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 `/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`). @@ -294,6 +373,7 @@ gbrain status: GREEN Engine .......... OK Capability ...... OK write+search round-trip CWD source ...... OK (page_count=) + Call graph ...... OK edges resolved (code-callers/callees live) ~/.gstack source. OK (page_count=) — managed by /setup-gbrain Memory sync ..... OK CLAUDE.md ....... OK ## GBrain Search Guidance present @@ -302,9 +382,27 @@ gbrain status: GREEN Run `/sync-gbrain` again any time gbrain feels off; safe and idempotent. ``` +The **Call graph** row reports the most authoritative signal available: + +1. **If a dream stage ran this invocation** (`--dream`, or `--full` auto-build), + mirror its row verbatim — it's the ground truth for this run: + - `OK 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 \`)` + - `WARN dream ran but the embed phase failed (missing embedding key)` + - `WARN dream ran but resolved 0 edges (no code symbols matched yet)` +2. **Otherwise** fall back to the `CYCLE` value 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 symbols` + - `never` → `WARN call graph not built — run /sync-gbrain --dream` + - `unknown` → `WARN could not probe call graph (doctor unavailable) — run /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; CLAUDE.md guidance block REMOVED — run /setup-gbrain to repair`). +A `never`/`unknown` Call graph row flips the verdict to YELLOW. ---