From fc21193e1ddf65a2e0a2443494882d1fcc3bb219 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Mon, 17 Aug 2026 10:53:36 -0700 Subject: [PATCH] fix(preamble): brain-sync block counts the spool queue and resolves MCP project-first MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two resolver halves deferred from earlier wave commits: the queue-depth line counts .brain-queue.d/*.json spool records (plus legacy lines until the drain migrates them), and GBRAIN_MCP_ENTRY_JQ swaps its operands to nearest-ancestor-project-first — matching the empirically verified Claude Code precedence (project-local beats user scope) instead of the backwards user-first assumption. Co-Authored-By: Claude Fable 5 --- .../resolvers/preamble/generate-brain-sync-block.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/scripts/resolvers/preamble/generate-brain-sync-block.ts b/scripts/resolvers/preamble/generate-brain-sync-block.ts index ae1ab5778..1c9080752 100644 --- a/scripts/resolvers/preamble/generate-brain-sync-block.ts +++ b/scripts/resolvers/preamble/generate-brain-sync-block.ts @@ -48,8 +48,13 @@ import { quoteSafePath } from '../types'; * extracts fields from that variable — one jq parse of claude.json per * skill start, and the long expression appears once per rendered SKILL.md. */ +// Project-local scope BEATS user scope — verified empirically against claude +// 2.1.233 with hermetic fixtures ('claude mcp get gbrain' reports Scope: +// Local config when both scopes define the server). The operand order below +// (nearest-ancestor project first, user-scope fallback) mirrors that; the +// pre-wave user-first order mis-resolved whenever the scopes disagreed. const GBRAIN_MCP_ENTRY_JQ = - '.mcpServers.gbrain // ((.projects // {}) | to_entries | map(select((.key as $k | $cwd == $k or ($cwd | startswith($k + "/"))) and ((try .value.mcpServers.gbrain catch null) != null))) | sort_by(.key | length) | last | .value.mcpServers.gbrain) // empty'; + '((.projects // {}) | to_entries | map(select((.key as $k | $cwd == $k or ($cwd | startswith($k + "/"))) and ((try .value.mcpServers.gbrain catch null) != null))) | sort_by(.key | length) | last | .value.mcpServers.gbrain) // .mcpServers.gbrain // empty'; export function generateBrainSyncBlock(ctx: TemplateContext): string { const isBrainHost = ctx.host === 'gbrain' || ctx.host === 'hermes'; @@ -145,7 +150,10 @@ if [ "$_GBRAIN_MCP_MODE" = "remote-http" ]; then echo "ARTIFACTS_SYNC: remote-mode (managed by brain server \${_GBRAIN_HOST:-remote})" elif [ -d "$_GSTACK_HOME/.git" ] && [ "$_BRAIN_SYNC_MODE" != "off" ]; then _BRAIN_QUEUE_DEPTH=0 - [ -f "$_GSTACK_HOME/.brain-queue.jsonl" ] && _BRAIN_QUEUE_DEPTH=$(wc -l < "$_GSTACK_HOME/.brain-queue.jsonl" | tr -d ' ') + # Spool-dir queue (one file per record); legacy .brain-queue.jsonl lines are + # counted too until the drain migrates them. + [ -d "$_GSTACK_HOME/.brain-queue.d" ] && _BRAIN_QUEUE_DEPTH=$(find "$_GSTACK_HOME/.brain-queue.d" -maxdepth 1 -name '*.json' 2>/dev/null | wc -l | tr -d ' ') + [ -f "$_GSTACK_HOME/.brain-queue.jsonl" ] && _BRAIN_QUEUE_DEPTH=$(( _BRAIN_QUEUE_DEPTH + $(wc -l < "$_GSTACK_HOME/.brain-queue.jsonl" | tr -d ' ') )) _BRAIN_LAST_PUSH="never" [ -f "$_GSTACK_HOME/.brain-last-push" ] && _BRAIN_LAST_PUSH=$(cat "$_GSTACK_HOME/.brain-last-push" 2>/dev/null || echo never) echo "ARTIFACTS_SYNC: mode=$_BRAIN_SYNC_MODE | last_push=$_BRAIN_LAST_PUSH | queue=$_BRAIN_QUEUE_DEPTH"