Skip to content

fix(mcp): address Codex P1/P2 review issues in deferred scan#349

Merged
justrach merged 2 commits into
release/0.2.579from
issue-346-failing-test
Apr 30, 2026
Merged

fix(mcp): address Codex P1/P2 review issues in deferred scan#349
justrach merged 2 commits into
release/0.2.579from
issue-346-failing-test

Conversation

@justrach

Copy link
Copy Markdown
Owner

Summary

Addresses all three Codex code-review issues flagged on PR #348 before merging release/0.2.579main.

P1 #1 — Reset triggered when triggerFn fails silently

  • triggerScanFromRoots now resets triggered=false if getDataDir fails
  • Prevents the silent deadlock where the first roots/list response causes a failed trigger that can never be retried

P1 #2 — Joinable scan and watcher threads (was use-after-free)

  • DeferredScan now has scan_thread: ?std.Thread = null and resolved_root: []const u8 = ""
  • triggerScanFromRoots stores the scanBg handle in ctx.scan_thread instead of detaching it
  • watcherDeferredLoop now runs watcher.incrementalLoop directly after scan_done fires — removing the second detached thread spawn
  • Main shutdown sequence joins deferred.scan_thread before returning, eliminating the use-after-free of store/explorer

P2 — codedb . mcp treated as deferred (regression)

  • Added root_is_explicit: bool flag in main.zig; set when the user passes an explicit path argument
  • mcp_deferred_root check now gates on !root_is_explicitcodedb . mcp scans immediately as expected

Test plan

  • zig build test — all unit tests pass
  • python3 scripts/e2e_mcp_test.py17/17 pass (S1 deferred/roots, S2 explicit-root, S3 no-roots-client)

Generated with Devin

justrach and others added 2 commits April 30, 2026 11:05
Covers three scenarios before any MCP merge:
1. issue-346 regression: spawn from cwd=/, roots handshake, tools verify
2. Normal mode: explicit positional root, immediate scan, no roots needed
3. No-roots client: spawn from /, stays alive gracefully with 0 files

All 17 tests pass. Documented in AGENTS.md as pre-merge verification step.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
P1 #1 (triggered reset): reset triggered=false in triggerScanFromRoots
when getDataDir fails, so next valid roots/list response can retry instead
of silently never scanning.

P1 #2 (joinable scan thread): store the spawned scanBg thread in
DeferredScan.scan_thread; join it during shutdown instead of detaching.
This eliminates the use-after-free where the background scan thread
could touch store/explorer after mainImpl returns.

Also fix the deferred watcher: replace watcherDeferredLoop (which only
waited for scan_done) to run watcher.incrementalLoop directly after
scan completes, removing the second detached thread spawn from
triggerScanFromRoots. Both the scan thread and the watcher thread
are now fully joinable.

P2 (explicit root): DeferredScan.resolved_root captures the abs_root
accepted from roots/list so watcherDeferredLoop can pass it to
incrementalLoop without any extra allocation.

All 17 E2E tests pass. zig build test passes.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@justrach justrach merged commit d8625ee into release/0.2.579 Apr 30, 2026
1 check passed
@github-actions

Copy link
Copy Markdown

Benchmark Regression Report

Thresholds: 10.00% and 50,000 ns absolute delta

NOISE means the percentage threshold was exceeded, but the absolute delta was too small to fail CI.

Tool Base (ns) Head (ns) Delta Abs Delta (ns) Status
codedb_bundle 555797 580090 +4.37% +24293 OK
codedb_changes 60674 60827 +0.25% +153 OK
codedb_deps 10635 9999 -5.98% -636 OK
codedb_edit 6072 6112 +0.66% +40 OK
codedb_find 70298 71296 +1.42% +998 OK
codedb_hot 115229 112024 -2.78% -3205 OK
codedb_outline 319795 309997 -3.06% -9798 OK
codedb_read 106673 101696 -4.67% -4977 OK
codedb_search 190986 180596 -5.44% -10390 OK
codedb_snapshot 279015 275067 -1.41% -3948 OK
codedb_status 104426 101693 -2.62% -2733 OK
codedb_symbol 65912 63967 -2.95% -1945 OK
codedb_tree 79114 74792 -5.46% -4322 OK
codedb_word 82088 76328 -7.02% -5760 OK

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8f9f401b54

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/main.zig
std.process.exit(1);
};
const mcp_deferred_root = std.mem.eql(u8, cmd, "mcp") and std.mem.eql(u8, root, ".");
const mcp_deferred_root = std.mem.eql(u8, cmd, "mcp") and std.mem.eql(u8, root, ".") and !root_is_explicit;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve deferred scan for ${workspaceFolder} fallback

Adding !root_is_explicit to the deferred-root gate makes codedb "${workspaceFolder}" mcp run immediate indexing after the fallback rewrites the literal placeholder to ".", instead of waiting for roots/list. In clients that do not expand ${workspaceFolder} and spawn from / (the issue-346 context), this now resolves to /, fails isIndexableRoot, and exits before MCP roots negotiation can recover the real project path.

Useful? React with 👍 / 👎.

@justrach justrach deleted the issue-346-failing-test branch May 21, 2026 06:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant