Skip to content

hook-augment 0.11.0: SessionStart/PreToolUse exit 0 with empty stdout on a ready index #2441

Open

Description

@rnovik

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_path equal to the payload cwd
  • Tested with CBM_CACHE_DIR set 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

  1. Which conditions make hook-augment produce output for SessionStart and PreToolUse, and is there a debug switch that explains an empty result?
  2. Does it need a running MCP server or daemon, or a registered session, beyond a ready index?

Activity

  1. added
    bugSomething isn't working
    priority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.
    on Oct 1, 2026
  2. DeusData commented on Oct 1, 2026

    @DeusData
    Owner

    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.

  3. DeusData commented on Oct 1, 2026

    @DeusData
    Owner

    Thank you again for the detailed measurements. I checked the corresponding v0.11.0 code too: changing CBM_HOOK_DEADLINE_MS changes 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 ms and pid would help. Otherwise, “unknown” is fine—there is no need to rerun anything just for this question. We’re keeping the diagnostics investigation open.

  4. david-eve-za commented on Oct 3, 2026

    @david-eve-za

    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), build 0.11.0 (548b53129e1b...), 2 committed clients, default cache dir (no CBM_CACHE_DIR override)
    • 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
    • A breadcrumb for each such run in ~/.cache/codebase-memory-mcp/logs/hook-augment-timeouts.log:
      hook-augment: deadline_exceeded ms=2000 pid=29518
      
    • Same payload with CBM_HOOK_DEADLINE_MS=10000 → full additionalContext (4 graph symbols formatted as expected), measured 2.43–2.45 s user CPU at ~99%, ~2.5 s wall
    • SessionStart behaves identically: empty at the default deadline; the full tier-routing note with the raised deadline (2.44 s user CPU)

    Differential 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-augment process was observed sitting in R state 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_MS would 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.

  5. added a commit that references this issue on Oct 9, 2026
  6. DeusData commented on Oct 9, 2026

    @DeusData
    Owner

    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-augment paid 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-augment with a SessionStart payload, 9 interleaved runs, medians:

    before after
    hook-augment wall 1.448 s 0.376 s
    hook-augment user CPU 1.162 s 0.097 s
    CBM_HOOK_DEADLINE_MS=1000 exit 0, empty stdout full answer in 0.37 s

    When the next release is out, could you rerun your PreToolUse repro without the CBM_HOOK_DEADLINE_MS override? 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.

  7. added
    awaiting-reporterWaiting on the reporter for info/repro; stale bot will warn then close
    on Oct 19, 2026
  8. DeusData commented on Oct 19, 2026

    @DeusData
    Owner

    Thank you again for the measurements. Following up on the October 9 retest request: if you have tested a newer build without the deadline override, please share whether PreToolUse now emits context and the version used. If you have not had time, that is fine; I have no new result to add beyond the fix and measurements already documented above.

  9. github-actions commented on Oct 20, 2026

    @github-actions

    Thanks for the report! To move this forward we need a bit more so we can reproduce it ourselves:

    • the codebase-memory-mcp --version you're on
    • the exact steps or command you ran
    • a public repo (or a small dummy snippet) that shows the problem — please don't paste proprietary code

    Once that's here we'll pick it straight back up. Heads-up: issues left awaiting-reporter are automatically closed after a few weeks of silence, but a comment reopens the door anytime.

  10. ellugia commented on Oct 20, 2026

    @ellugia

    Adding Windows measurements on v0.12.1 in response to the request for results from newer builds. The symptom overlaps with this issue, but we have not established that the Windows and macOS cases share the same cause.

    Environment

    • Windows x64, 25H2, build 26200.9711.
    • Codex 0.163.0-alpha.10.2.
    • Official CBM v0.12.1 Windows amd64 executable, SHA-256: 39f6a789cd858d7428561ac5afaefb9a47b018dcba0ad6fa41ae71a45e0ed656.
    • Clean Windows and Codex installations, confirmed by the machine owner; installation history was not independently audited.
    • Existing daemon active since the previous evening. Its PID and creation time remained unchanged before and after testing, and its original process handle was checked around every normal direct invocation.
    • No installation, configuration changes, daemon restarts, or explicit reindexing during the measured batch.

    Repeated results: 80 trials

    Directory A was unindexed. Directory B was an existing indexed fixture containing one Python file, with 18 graph nodes and 18 edges.

    Experiment Directory Context received No context Total
    Direct calls, no debugger A 28 2 30
    Direct calls, no debugger B 30 0 30
    Real Codex SessionStart A 4 1 5
    Real Codex SessionStart B 4 1 5
    Separate instrumented calls A 9 1 10

    The 60 normal direct calls were sequential and alternated directories. All exited 0. The two empty responses also had empty stderr and took 622.19 ms and 609.38 ms end-to-end; successful calls typically took about 329 ms.

    For the ten real Codex trials, each used a fresh ephemeral thread and one minimal turn requesting only OK, without tools. Results came from the CBM handler's actual hook/completed events—not from asking the model whether it received context. Both failures had status: completed and entries: [], with durations of 906 ms and 912 ms. Other configured hooks, including Ponytail, remained enabled in these host-integration trials.

    Separate Windows timer observation

    In ten additional calls, Windows debug APIs observed the installed binary scheduling CreateTimerQueueTimer with a 300 ms due time. In one run, its callback executed and the process subsequently exited 0 with zero stdout bytes and empty stderr. The other nine returned context without reaching that callback.

    Only temporary process-memory breakpoints were used; the executable on disk and timer value were unchanged. Debugging can affect timing, so these observations are separate from the normal trials and do not establish their failure frequency or explain every empty response.

    Important difference from the macOS investigation

    In the v0.12.1 source:

    • Linux/macOS use a 2000 ms default configurable through CBM_HOOK_DEADLINE_MS.
    • Windows uses a fixed 300 ms timer whose callback calls ExitProcess(0U); that environment setting does not configure it.
    • The Windows timer is armed after the authenticated daemon connection in src/main.c.

    Therefore, we are not attributing our result to executable hashing, as investigated in the macOS comments or #2683. We observed a separate Windows timeout path that can silently discard context.

    Reproduction

    Repeatedly invoke the installed executable as codebase-memory-mcp.exe hook-augment, sending this JSON through stdin and closing stdin:

    {"session_id":"repeat-diagnostic","cwd":"C:/absolute/existing/directory","hook_event_name":"SessionStart","source":"startup"}

    Keep the existing daemon active and alternate an unindexed directory with an indexed fixture for 30 rounds. Our fixture contained:

    def add(a, b):
        return a + b
    
    def total(values):
        result = 0
        for value in values:
            result = add(result, value)
        return result

    Expected: JSON containing hookSpecificOutput.additionalContext, including the “no indexed graph project matched” guidance for an unindexed root. Observed: intermittent empty output despite an active daemon.

    This is one machine and a small sample, with natural load and caches uncontrolled. No resource trajectory was captured, and the operation consuming the internal budget was not profiled. Sanitized per-trial measurements and a standalone reproduction script can be provided.

    Would you prefer to track this Windows-specific deadline here, or as a separate linked issue?

    Prepared with Codex under human supervision; Codex assisted with investigation, testing and drafting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    awaiting-reporterWaiting on the reporter for info/repro; stale bot will warn then closebugSomething isn't workingeditor/integrationEditor compatibility and CLI integrationpriority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.stability/performanceServer crashes, OOM, hangs, high CPU/memory

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions