Repository navigation
hook-augment 0.11.0: SessionStart/PreToolUse exit 0 with empty stdout on a ready index #2441
Description
hook-augment 0.11.0: SessionStart and PreToolUse exit 0 with empty stdout on a ready index
Summary
codebase-memory-mcp hook-augment (0.11.0, macOS arm64) reads a Claude Code hook payload on stdin and exits 0 after ~2 s, but writes nothing to stdout or stderr for SessionStart, PreToolUse Grep and PreToolUse Glob. The project for cwd is indexed and ready. No additional context reaches the agent.
Environment
- codebase-memory-mcp 0.11.0 (official release binary, unpatched), macOS 26 arm64, Node 26.10.0
- Project: 12 969 nodes, 50 929 edges,
status: ready,root_pathequal to the payloadcwd - Tested with
CBM_CACHE_DIRset to the project cache and unset (default cache). Both give the same result.
Reproduction
repro.sh <indexed repo root> [cache dir] uses only the installed binary:
printf '{"session_id":"repro","transcript_path":"/tmp/t.jsonl","hook_event_name":"SessionStart","source":"startup","cwd":"<repo>"}' \
| codebase-memory-mcp hook-augment; echo "exit=$?"
printf '{"session_id":"repro","transcript_path":"/tmp/t.jsonl","hook_event_name":"PreToolUse","cwd":"<repo>","tool_name":"Grep","tool_input":{"pattern":"main"}}' \
| codebase-memory-mcp hook-augment; echo "exit=$?"Observed
--- SessionStart (deadline=default): exit=0 elapsed=1926ms stdout_bytes=0 stderr_bytes=0
--- PreToolUse Grep (deadline=default): exit=0 elapsed=1954ms stdout_bytes=0 stderr_bytes=0
--- PreToolUse Glob (deadline=default): exit=0 elapsed=1960ms stdout_bytes=0 stderr_bytes=0
--- SessionStart (deadline=30000): exit=0 elapsed=2022ms stdout_bytes=0 stderr_bytes=0
--- PreToolUse Grep (deadline=30000): exit=0 elapsed=1978ms stdout_bytes=0 stderr_bytes=0
--- PreToolUse Glob (deadline=30000): exit=0 elapsed=2018ms stdout_bytes=0 stderr_bytes=0
--- timeout log <CBM_CACHE_DIR>/hook-augment-timeouts.log: (absent)
Raising CBM_HOOK_DEADLINE_MS to 30 000 changes nothing, and no deadline_exceeded line is logged, so this is not the hook deadline.
Expected
A JSON object on stdout such as {"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"…"}}, the shape the installer's own fallback hooks emit. If the hook deliberately declines, a diagnostic on stderr or a documented reason, not a silent exit 0.
Questions
- Which conditions make
hook-augmentproduce output for SessionStart and PreToolUse, and is there a debug switch that explains an empty result? - Does it need a running MCP server or daemon, or a registered session, beyond a ready index?
Activity
DeusData commentedon Oct 1, 2026
Thank you for the detailed timing comparison and the explicit questions. One relevant distinction on current main is that hook clients connect to an existing daemon and return success even when that connection or augmentation fails; a ready on-disk index alone is not the whole prerequisite. Also, the timeout breadcrumb is under HOME/.cache/codebase-memory-mcp/logs in the current hook code, rather than necessarily under CBM_CACHE_DIR; #2448 proposes correcting that location. These source facts help narrow the investigation, but they do not yet explain your exact 0.11.0 run or establish that the deadline caused it. Keeping this as a hook/diagnostics bug for investigation, not closing it as expected behavior.
DeusData commentedon Oct 1, 2026
Thank you again for the detailed measurements. I checked the corresponding v0.11.0 code too: changing
CBM_HOOK_DEADLINE_MSchanges the overall process alarm, while the separate augmentation-request timeout remains 1500 ms. The timings alone therefore cannot identify which stage returned silently.For the runs you already reported, was a codebase-memory MCP session connected, or an explicitly started daemon running? If you know, was it using the same build and cache directory as the hook?
If you already have a timeout-log entry attributable to one of those SessionStart runs, the single line containing
msandpidwould help. Otherwise, “unknown” is fine—there is no need to rerun anything just for this question. We’re keeping the diagnostics investigation open.david-eve-za commentedon Oct 3, 2026
Independent confirmation on the 0.11.0 release build (macOS, arm64), with a measurement that may help narrow this: our empty stdout is the in-process deadline firing — the fixed per-invocation CPU cost exceeds the 2000 ms default.
Repro (daemon active, matching build, ready index):
codebase-memory-mcp daemon status→active (session-managed), build0.11.0 (548b53129e1b...), 2 committed clients, default cache dir (noCBM_CACHE_DIRoverride)printf '%s' '{"hook_event_name":"PreToolUse","tool_name":"Grep","tool_input":{"pattern":"FileProcessingController"},"cwd":"<indexed-project-root>"}' | codebase-memory-mcp hook-augment→ exit 0, no stdout~/.cache/codebase-memory-mcp/logs/hook-augment-timeouts.log:CBM_HOOK_DEADLINE_MS=10000→ fulladditionalContext(4 graph symbols formatted as expected), measured 2.43–2.45 s user CPU at ~99%, ~2.5 s wallDifferential that isolates the cost:
printf '%s' '{"project":"...","name_pattern":".*FileProcessingController.*","limit":5,"format":"json"}' | codebase-memory-mcp cli search_graph(in-process, daemon-free, same DB) returns the hits, but costs the same ~2.44 s user CPU / ~2.75 s wall. So on this machine the ~2.4 s is binary startup work (the executable-identity hashing plus load), not daemon latency — and it alone blows the 2000 ms budget before any query runs.Answers to the questions from your last comments, from this environment: an explicitly started daemon was running the whole time (session-managed, same build as the hook binary, default cache dir); the timeout-log lines quoted above are from those runs. Also FWIW: one
hook-augmentprocess was observed sitting inRstate for ~5 hours (started 13:42 local) before its breadcrumb line appeared — happy to open a separate issue for the hang if useful.Suggestion: raising
HA_DEADLINE_DEFAULT_MSwould make default installs emit on hardware where startup costs ~2.4 s (as would reducing the startup CPU, per #2058). Calibration data point: nothing here emits below ~2.4 s user CPU per invocation.Merge pull request #2575 from DeusData/perf/sha256-hw
DeusData commentedon Oct 9, 2026
Thank you, @david-eve-za, for the CPU measurement, and @rnovik for the original report. The 2.44 s of CPU per invocation was the clue that mattered: it pointed at a fixed startup cost, not at the daemon or the index.
Cause. Every process start computes the SHA-256 of its own executable, which serves as the daemon build identity. With the portable SHA-256 code, that took about 1.2 s of CPU on our Apple arm64 Mac for the ~300 MB binary, and more on slower machines.
hook-augmentpaid that before it could do anything else, so the 2000 ms deadline fired and the hook exited 0 with empty stdout.Fix. #2575, merged to main as e93e438. The hash now runs on the CPU's SHA-256 instructions: ARMv8 SHA2 (present on every Apple silicon Mac) or x86 SHA-NI, with the portable code as the fallback. It also compresses whole blocks straight from the input. Every digest is unchanged.
Measured on an Apple arm64 Mac (macOS 26.6), release builds before and after,
hook-augmentwith a SessionStart payload, 9 interleaved runs, medians:hook-augmentwallhook-augmentuser CPUCBM_HOOK_DEADLINE_MS=1000When the next release is out, could you rerun your PreToolUse repro without the
CBM_HOOK_DEADLINE_MSoverride? If the hook answers at the default deadline, this is solved; if not, the timing you see will tell us what's left. I'll keep the issue open until then.perf(sha256): compress blocks on ARMv8 SHA2 / x86 SHA-NI (DeusData#2441)