fix: read project-scoped MCP registrations in gbrain detection (#2499)

Claude Code registers MCP servers at two scopes in ~/.claude.json: user
scope (.mcpServers) and project scope (.projects["/abs/path"].mcpServers
— what `claude mcp add` WITHOUT --scope user writes). Every gbrain
detection site read only user scope, so a correctly configured
project-scoped brain was invisible: brain-aware blocks suppressed,
remote-mode artifacts sync never recognised, and detectEndpointHash fell
through to the 'local' literal — two different project-scoped brains
hashed identically, so switching between them never invalidated the
cache, the exact scenario the function's docstring says it exists to
catch. Nothing errored; the features just quietly were not there.

Two sites fixed:

- scripts/resolvers/preamble/generate-brain-sync-block.ts: the shared
  detection block (rendered into every tier-2+ SKILL.md) now resolves the
  gbrain entry ONCE into _GBRAIN_MCP_ENTRY — user scope first, then the
  nearest-ancestor project entry for $PWD that actually carries a gbrain
  server (longest matching key with a path-boundary check: /a/repo never
  matches /a/repo2; a nested project WITHOUT gbrain doesn't shadow its
  parent's registration). _GBRAIN_MCP_TYPE and _GBRAIN_HOST extract from
  the resolved entry, so claude.json is parsed once per skill start. All
  SKILL.md files regenerated in this commit; the ship golden fixtures and
  three carve-guard skeleton caps (plan-eng-review, plan-devex-review,
  office-hours; ~1.5KB rendered growth per skill) are refreshed with
  measured values.
- bin/gstack-brain-cache detectEndpointHash: same resolution order in TS
  (user scope, else nearest-ancestor project entry by cwd, both path
  separators for Windows keys).

Tests: rendered-output tests in test/gen-skill-docs.test.ts pin the
regenerated block (static markers + a FUNCTIONAL run of the exact
rendered lines against a fixture ~/.claude.json with only a
project-scoped registration, plus an outside-cwd discriminator);
detectEndpointHash unit tests in test/brain-cache-roundtrip.test.ts cover
project-scope resolve, path-boundary, nearest-ancestor distinct hashes,
and user-scope precedence.

Root-cause analysis by @samporter-31 in #2499.

Fixes #2499

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-08-16 10:02:31 -07:00
co-authored by Claude Fable 5
parent 5854d122d3
commit acc354fcfa
57 changed files with 532 additions and 165 deletions
+9 -3
View File
@@ -181,7 +181,9 @@ export const CARVE_GUARDS: Record<string, CarveGuard> = {
// v1.65 merge: provisional larger-of-both-waves budget; re-measured below.
// Fork port wave 2 (#703): the repo-doc-preference block in the design
// check grew every plan-review skeleton ~0.7KB. Measured values noted.
maxSkeletonBytes: 70_000, // measured 68,780
// #2499 project-scope MCP jq in the brain-sync block grew every tier-2+
// skeleton ~1.5KB (entry resolution emitted once per SKILL.md).
maxSkeletonBytes: 70_500, // measured 70,318
minUnionBytes: 70_000,
mustContain: ['Architecture', 'Code Quality', 'Test', 'Performance'],
// Cross-cutting preamble growth (v1.57.2.0 AUQ-failure prose fallback + the
@@ -236,7 +238,9 @@ export const CARVE_GUARDS: Record<string, CarveGuard> = {
// v1.2.0 activation lift: first-run-guidance section in the shared preamble.
// Fork port wave 2 (#703): the repo-doc-preference block in the design
// check grew every plan-review skeleton ~0.7KB. Measured values noted.
maxSkeletonBytes: 82_000, // measured 80,493
// #2499 project-scope MCP jq in the brain-sync block grew every tier-2+
// skeleton ~1.5KB (entry resolution emitted once per SKILL.md).
maxSkeletonBytes: 82_500, // measured 82,031
minUnionBytes: 70_000,
mustContain: ['developer experience', 'Getting Started'],
// Default-on Codex outside-voice (codexPreflight block + CODEX_MODE branch
@@ -264,7 +268,9 @@ export const CARVE_GUARDS: Record<string, CarveGuard> = {
// (judgment must be visible before the workflow directs the user to a
// vendor site), plus the #703 dual-write + repo-doc-preference block and
// the #538 opt-out + D1 evidence directive — ratio 1.104 measured.
maxSkeletonBytes: 101_000,
// #2499 project-scope MCP jq in the brain-sync block grew every tier-2+
// skeleton ~1.5KB (entry resolution emitted once per SKILL.md).
maxSkeletonBytes: 101_500, // measured 101,314
minUnionBytes: 70_000,
mustContain: ['design doc', 'problem statement'],
maxSizeRatio: 1.12,