From bdb69f957d6c27a304578542c6ae6f189d197a1c Mon Sep 17 00:00:00 2001 From: Steven Sacks Date: Fri, 3 Jul 2026 15:43:43 +0900 Subject: [PATCH] docs(serena): make code-search routing language-agnostic The advisory code-search rule now nudges toward Serena's symbol tools for any language Serena indexes for the project, not only TS/TSX and no longer scoped to app/ or test/. The rule frontmatter triggers on a broad multi-language source glob. The enforcement guard is left untouched and stays TypeScript-conservative and tsconfig-gated, since a wrong hard-block on a non-TS search is worse than a miss while the rule only nudges. The two Serena wiki pages document the split and a CHANGELOG entry records it. Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude/rules/code-search.md | 13 +++++-------- CHANGELOG.md | 1 + wiki/concepts/Serena Integration.md | 4 ++-- wiki/dependencies/Serena.md | 10 ++++++---- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.claude/rules/code-search.md b/.claude/rules/code-search.md index 0b0ff57c..c1984370 100644 --- a/.claude/rules/code-search.md +++ b/.claude/rules/code-search.md @@ -1,14 +1,11 @@ --- paths: - - 'app/**/*.ts' - - 'app/**/*.tsx' - - 'test/**/*.ts' - - 'test/**/*.tsx' + - '**/*.{ts,tsx,js,jsx,mjs,cjs,py,go,rs,java,rb,php,cs,cpp,cc,c,h,hpp,kt,swift,scala}' --- # Code Search -For symbol-level queries on TS/TSX files, prefer [Serena](https://github.com/oraios/serena)'s MCP tools over Read+grep. Serena is LSP-backed, canonical, type-resolved answers vs string matches. +For symbol-level queries on code, prefer [Serena](https://github.com/oraios/serena)'s MCP tools over Read+grep, in any language Serena indexes for this project (TypeScript and any other language server the project configures). Serena is LSP-backed, canonical, type-resolved answers vs string matches. ## Prefer Serena @@ -16,15 +13,15 @@ For symbol-level queries on TS/TSX files, prefer [Serena](https://github.com/ora ## Grep is still right -Prose / comments / string literals, files outside `app/**` and `test/**`, generated / gitignored files (not indexed), cross-language searches. +Prose / comments / string literals, non-code files, files in a language Serena isn't indexing for this project, generated / gitignored files (not indexed), cross-language searches. ## Enforcement -A PreToolUse guard (`.claude/hooks/serena-code-search-guard.sh`) catches a bare-identifier symbol search on either search path and points it at Serena's symbol tools. Through the `Grep` tool it blocks a pattern that is a bare identifier (>= 3 chars, no spaces or regex metacharacters) scoped to `app/**` or `test/**` TS/TSX. Through `Bash` it blocks a single `grep`/`rg`/`ag` whose lone pattern is such an identifier and which carries an explicit `app/**` or `test/**` TS/TSX path. The Bash path favors false negatives: a pipeline, a compound or sequenced command, a command substitution, a redirection, a quoted or multi-word or regex pattern, multiple patterns, or any search not explicitly scoped to app/test source passes through, so legitimate shell work is never blocked. Re-running the identical search passes, for the rare string-literal or comment search that is identifier-shaped. The guard no-ops unless Serena is a registered MCP server and the repo has a `tsconfig.json`, so adopters without Serena are unaffected. +The routing guidance above is language-agnostic: it nudges toward Serena's symbol tools for any language Serena indexes for this project. The enforcement guard is deliberately narrower and stays TypeScript-conservative, so a wrong block on a non-TS search can't happen. A PreToolUse guard (`.claude/hooks/serena-code-search-guard.sh`) catches a bare-identifier symbol search on either search path and points it at Serena's symbol tools. Through the `Grep` tool it blocks a pattern that is a bare identifier (>= 3 chars, no spaces or regex metacharacters) scoped to `app/**` or `test/**` TS/TSX. Through `Bash` it blocks a single `grep`/`rg`/`ag` whose lone pattern is such an identifier and which carries an explicit `app/**` or `test/**` TS/TSX path. The Bash path favors false negatives: a pipeline, a compound or sequenced command, a command substitution, a redirection, a quoted or multi-word or regex pattern, multiple patterns, or any search not explicitly scoped to app/test source passes through, so legitimate shell work is never blocked. Re-running the identical search passes, for the rare string-literal or comment search that is identifier-shaped. The guard no-ops unless Serena is a registered MCP server and the repo has a `tsconfig.json`, so adopters without Serena are unaffected. ## Limits -Cold-start tsserver warm-up. Files outside `tsconfig` `include` invisible. Generated files not indexed. +Cold-start language-server warm-up. Files the language server doesn't index (outside its project config) are invisible. Generated files not indexed. ## Reference diff --git a/CHANGELOG.md b/CHANGELOG.md index c170ea61..fa45aaf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ A release change that requires the adopter to act, run a command or hand-migrate ### Changed +- GAIA's Serena code-search routing guidance is now language-agnostic: the advisory `code-search` rule nudges toward Serena's LSP-backed symbol tools for symbol queries in any language Serena indexes for the project (not only TypeScript, and no longer scoped to `app/`/`test/`), so an adopter who configures another language server gets the same routing. The enforcement guard stays deliberately TypeScript-conservative and tsconfig-gated, since a wrong hard-block on a non-TS search is worse than a miss while the rule only nudges (#533) - `/gaia-debt` drives its fix PR through the standard PR Merge Workflow to completion instead of stopping after `gh pr create` for a human to merge by hand: it confirms intent (open-only or merge, defaulting to merge), then resolves the marker handshake, the maintainer-only CHANGELOG gate, the merge (`--auto` under branch protection, never `--admin`), and the post-merge verify-and-cleanup itself. The `code-review-audit` marker gate is unchanged, the skill drives the merge and never bypasses, fakes, or pre-empts it (#523) - `gaia setup finalize` refuses to stamp per-machine setup complete while the mentorship decision artifact `.gaia/local/mentorship.json` is absent, and that refusal holds even under `--force`, so the completion marker can no longer claim success when the opt-in decision was never persisted. It emits a structured error whose `code` is `mentorship_decision_missing`, and `/gaia-init` Step 12 self-heals on that code by re-applying the safe default and retrying finalize once, so an automated init that dropped the opt-in still completes without human input. The gate keys on file existence only, leaving `/setup-gaia`'s recovery net the owner of upgrading a lingering `enabled:null` decision (#520) - `/gaia-spec`'s closing handoff now prints a single copy-pasteable block: the `/gaia-plan` command and its SPEC argument together, prefaced by a `/clear`-and-paste instruction, instead of a bare argument the user had to prefix with the command by hand (#519) diff --git a/wiki/concepts/Serena Integration.md b/wiki/concepts/Serena Integration.md index 3017a234..5974c4b1 100644 --- a/wiki/concepts/Serena Integration.md +++ b/wiki/concepts/Serena Integration.md @@ -2,7 +2,7 @@ type: concept status: active created: 2026-05-04 -updated: 2026-07-02 +updated: 2026-07-03 tags: [concept, claude, code-search, mcp] --- @@ -36,7 +36,7 @@ See `.claude/rules/code-search.md` for the routing rule. ## Enforcement -The rule alone is path-scoped to `app/**`/`test/**` *edits*, so it's absent from context during exploration, exactly when the grep-vs-Serena decision gets made. A PreToolUse guard (`.claude/hooks/serena-code-search-guard.sh`) closes that gap. It fires at the search call itself on both the `Grep` tool and a single `grep`/`rg`/`ag` issued through `Bash`, and blocks a bare identifier (≥ 3 chars, no spaces or regex metacharacters) scoped to `app/**`/`test/**` TS/TSX, pointing it at `find_symbol` / `find_referencing_symbols` / `get_symbols_overview`. The Bash path stays conservative and favors false negatives: a pipeline, a compound or sequenced command, a command substitution, a redirection, a quoted or regex pattern, multiple patterns, or any grep not carrying an explicit `app/**`/`test/**` TS/TSX path passes through untouched, so ordinary shell work is never blocked. Re-running the identical search passes, for the rare string-literal or comment search that's identifier-shaped. It no-ops unless Serena is a registered MCP server and the repo has a `tsconfig.json`, so adopters without Serena never see it. See [[Claude Hooks]]. +The routing rule is advisory and language-agnostic: it activates on a broad multi-language source glob and prefers Serena's symbol tools for any language Serena indexes for the project, not TypeScript or `app/`/`test/` alone. A rule is still absent from context during pure exploration (no edit in flight), exactly when the grep-vs-Serena decision gets made, so a PreToolUse guard (`.claude/hooks/serena-code-search-guard.sh`) closes that gap. The guard is deliberately narrower than the rule: it stays TypeScript-conservative and tsconfig-gated, so a hard block never lands on a non-TS search. It fires at the search call itself on both the `Grep` tool and a single `grep`/`rg`/`ag` issued through `Bash`, and blocks a bare identifier (≥ 3 chars, no spaces or regex metacharacters) scoped to `app/**`/`test/**` TS/TSX, pointing it at `find_symbol` / `find_referencing_symbols` / `get_symbols_overview`. The Bash path stays conservative and favors false negatives: a pipeline, a compound or sequenced command, a command substitution, a redirection, a quoted or regex pattern, multiple patterns, or any grep not carrying an explicit `app/**`/`test/**` TS/TSX path passes through untouched, so ordinary shell work is never blocked. Re-running the identical search passes, for the rare string-literal or comment search that's identifier-shaped. It no-ops unless Serena is a registered MCP server and the repo has a `tsconfig.json`, so adopters without Serena never see it. The split is deliberate: the advisory rule nudges broadly across languages at zero false-block risk, while the guard blocks only where a wrong block is impossible. See [[Claude Hooks]]. ## Quirks diff --git a/wiki/dependencies/Serena.md b/wiki/dependencies/Serena.md index eda61a46..53cc0f1d 100644 --- a/wiki/dependencies/Serena.md +++ b/wiki/dependencies/Serena.md @@ -11,7 +11,7 @@ tags: [dependency, mcp, code-search] # Serena -LSP-backed MCP server. Gives Claude live, always-fresh access to symbol definitions, references, types, and module structure across the project's TS/TSX files. +LSP-backed MCP server. Gives Claude live, always-fresh access to symbol definitions, references, types, and module structure across the project's source files, in any language the project configures a language server for. ## Pin @@ -28,7 +28,7 @@ The `claude-code` context exposes Serena's LSP-backed symbol tools and its memor ## When to use -Symbol-level queries on TS/TSX: +Symbol-level queries in any language Serena indexes for the project: - Definitions: "where is `X`?" - References: "what calls `Y`?" @@ -36,10 +36,12 @@ Symbol-level queries on TS/TSX: For prose / string / cross-language search, fall back to Read+grep. Routing rule: `.claude/rules/code-search.md`. +The advisory routing rule is language-agnostic: it activates on a broad multi-language source glob and nudges toward Serena's symbol tools for any language Serena indexes, not TypeScript or `app/`/`test/` alone. The enforcement guard (`.claude/hooks/serena-code-search-guard.sh`) is deliberately narrower, TypeScript-conservative and tsconfig-gated, so a hard block never lands on a non-TS search. See [[Serena Integration]] for the guard detail. + ## Limits -- Cold-start cost on first invocation per session (tsserver warm-up). -- Indexes only files reachable from `tsconfig.json`. +- Cold-start cost on first invocation per session (language-server warm-up). +- Indexes only files reachable from the language server's project config (`tsconfig.json` for TypeScript). - Doesn't see gitignored or generated files. See [[Serena Integration]].