35 Commits
Author SHA1 Message Date
Martin Vogel da7e77580f Fix Windows build: guard POSIX-only tests with #ifndef _WIN32
Path containment tests use realpath() and mkdir(path, mode) which are
not available on Windows. Shell-free exec tests already guarded.
2026-03-21 23:19:50 +01:00
Martin Vogel 0888726073 Add security defense tests + eliminate system() command injection
TDD: 31 security tests covering shell injection prevention, SQLite
authorizer (ATTACH/DETACH blocked), SQL injection via Cypher, path
containment, and shell-free subprocess execution.

- Add cbm_exec_no_shell() in compat_fs: fork+execvp (POSIX), _spawnvp
  (Windows) — executes commands without shell interpretation
- Replace system() with cbm_exec_no_shell() for unzip extraction and
  version verification in update command — eliminates CodeQL
  command-line-injection alerts
- CodeQL: switch to build-mode manual for 100% source file coverage
- CodeQL gate: fix race condition between scan completion and alert API
  propagation (60s settle + double-check polling)
- Dismiss TOCTOU in pass_envscan.c (benign read-only directory walk)
2026-03-21 23:02:34 +01:00
Martin Vogel aa2b60be7d Fix 29 CodeQL alerts: command injection, snprintf overflow, TOCTOU races
- Command injection (CRITICAL): validate shell args before system() in
  update command's unzip and version-check calls
- TOCTOU cli.c: use open(O_CREAT, 0755) + fdopen() to set permissions
  atomically instead of fopen() + chmod() after close
- TOCTOU pass_envscan.c: open file first, then fstat() on fd to check
  size, eliminating stat-then-open race window
- Overflowing snprintf (11 locations): clamp offset after each append
  to prevent unsigned underflow on truncation in cypher.c, store.c,
  http_server.c, test_c_lsp.c
- Add CBM_SNPRINTF_APPEND macro in str_util.h for future safe appends
- CodeQL: remove pull_request trigger (only scan push to main)
- CodeQL gate: increase timeout from 30 to 45 minutes
- Add fuzz testing script (random JSON-RPC + Cypher mutations)
- 12 Scorecard governance alerts dismissed (not code vulnerabilities)
2026-03-21 22:18:31 +01:00
Martin Vogel 2e21a0133b Release security hardening: VirusTotal + attestations + cosign + SBOM + OpenSSF + SECURITY.md
Release pipeline (step 5 + 6) now includes:
- SLSA build provenance attestations for all binaries
- Sigstore cosign keyless signing (.bundle files)
- SBOM (CycloneDX) with all vendored dependencies
- VirusTotal scan of all binaries (70+ engines)
- OpenSSF Scorecard (repo security health score)
- All results appended to release notes automatically

Also:
- SECURITY.md: vulnerability reporting + security measures
- Removed DLL API strings from test binary (issue #89)
2026-03-21 14:34:22 +01:00
Martin Vogel 281a7608d5 Remove DLL resolve tracking (Windows Defender false positive)
The DLL resolve feature (f92fd66) contained literal strings
GetProcAddress, dlsym, LoadLibrary that triggered Windows Defender
Wacatac.B!ml heuristic detection on the v0.5.4 binary. These are
the exact API names malware uses for dynamic API resolution.

Removed the feature entirely — it served a niche use case (C/C++
projects with dynamic DLL loading) and the false positive blocks
all Windows users from using the tool.

Fixes #89.
2026-03-21 13:47:10 +01:00
Martin Vogel e09f27130e Fix Windows bulk test + dual MCP config location + CONTRIBUTING.md
- Bulk test: use cbm_tmpdir() instead of hardcoded /tmp/ (fixes
  Windows/MSYS2 where /tmp/ doesn't resolve for SQLite)
- Install: write MCP config to both ~/.claude/.mcp.json (Claude Code
  <=2.1.x) and ~/.claude.json (Claude Code >=2.1.80). Fixes #69.
- Uninstall: remove from both locations
- CONTRIBUTING.md: rewrite for pure C project (was still describing Go,
  causing contributors to submit Go PRs)
- Fix clang-format in mcp.c protocol version negotiation (PR #79 merge)
2026-03-20 20:32:38 +01:00
Martin Vogel 92275ffa95 Merge PR #79: Fix VS Code compatibility (schema, install, protocol negotiation) 2026-03-20 19:52:59 +01:00
Martin Vogel b5b9c6bf78 Merge PR #72: keep WAL journal mode during bulk write 2026-03-20 19:29:40 +01:00
f92fd666b5 Port FastAPI Depends() + DLL resolve edge tracking (PR #66)
- FastAPI Depends(func_ref): scans Python function signatures for
  Depends() patterns and creates CALLS edges to the dependency function.
  Without this, auth/DI functions appear as dead code (in_degree=0).
- DLL resolve: scans C/C++ source for GetProcAddress/dlsym/Resolve
  patterns and creates CALLS edges to synthetic stub nodes, enabling
  call graph tracking across DLL boundaries.
- Extension scoping (#28) was already ported in 6a2b1f5.
- SQL size guard (#62) not needed: our C workers use 8MB stacks.

Tests: 3 new (httplink_laravel_path_filter, pipeline_fastapi_depends_edges,
pipeline_dll_resolve_edges). Total: 2041.

Co-Authored-By: kingchenc <kingchenc@users.noreply.github.com>
Co-Authored-By: mariomeyer <mariomeyer@users.noreply.github.com>
2026-03-20 19:19:12 +01:00
Bing Ho 83619f8d41 Bump MCP protocol version with proper negotiation
Support protocol versions 2025-11-25, 2025-06-18, 2025-03-26, and
2024-11-05. The server now reads the client's requested version and
echoes it if supported, falling back to its latest otherwise. This
fixes the "unsupported protocol" warning in VS Code 1.112+ while
remaining backward-compatible with older clients.
2026-03-20 10:42:52 -05:00
Martin VogelandJay Sync c66d88745d Fix Swift call extraction: 0 CALLS edges (#43)
Swift tree-sitter grammar uses positional children (not named fields) for
call_expression, so extract_callee_name() returned NULL for every call.

- extract_calls.c: Swift-specific callee extraction via first named child
  for call_expression and constructor_expression nodes
- lang_specs.c: add constructor_expression to swift_call_types
- 4 new C tests: simple calls, method calls, constructors, chained calls

Co-Authored-By: Jay Sync <63868998+jay-sync@users.noreply.github.com>
2026-03-20 14:46:46 +01:00
Bing Ho 89970f2b3e Fix ingest_traces array schema missing items property
VS Code 1.112+ validates that all MCP tool array-type parameters
include an "items" definition (microsoft/vscode#248810). The
ingest_traces tool's "traces" parameter was missing this, causing
startup failures.
2026-03-20 08:31:06 -05:00
Martin Vogel f6b9b39c60 Fix snippet tests: align with simplified get_code_snippet handler
The snippet handler now uses exact QN + suffix matching only (no fuzzy/auto-resolve).
Updated 3 tests to match: fuzzy_suggestions, fuzzy_last_segment, auto_resolve_enabled.
2026-03-20 13:45:17 +01:00
Martin Vogel d6a5f8984e Add incremental reindex + ADR hints in index/schema/adr responses
Incremental pipeline (pipeline_incremental.c):
- Disk-based delta re-indexing: classifies files by mtime+size vs stored
  hashes, deletes changed nodes (edges cascade), re-parses only changed
  files, merges into existing DB via cbm_gbuf_merge_into_store
- pipeline.c auto-routes: existing DB with hashes -> incremental, else full
- Full pipeline persists file hashes after dump for next incremental run
- No-op when nothing changed (watcher polls every 5-60s, 99% skip)
- 4 tests: noop, changed file, deleted file, new file added

ADR hints (ported from Go):
- index_repository: adr_present + adr_hint when no ADR exists
- get_graph_schema: adr_present + adr_hint per project
- manage_adr GET: adr_hint with creation instructions when no ADR
2026-03-20 13:15:01 +01:00
Shane McCarronandClaude Sonnet 4.6 a0e809d425 fix(store): address QA round 2 findings
- Validate child exit status (WIFEXITED + WEXITSTATUS) after waitpid so
  the test fails fast if the child couldn't open the store, rather than
  passing vacuously due to the "crashed" row never being written

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 18:17:55 -05:00
Shane McCarronandClaude Sonnet 4.6 675fdf341e fix(store): address QA round 1 findings
- Wrap bulk_crash_recovery test and its POSIX includes with #ifndef _WIN32
  guards to fix compilation failure on Windows (fork/waitpid unavailable)
- Add negative assertion that the uncommitted "crashed" row is absent
  after crash recovery, completing the test's correctness verification

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 18:07:17 -05:00
Shane McCarronandClaude Sonnet 4.6 8dd490b47c fix(store): keep WAL journal mode during bulk write to prevent DB corruption on crash
cbm_store_begin_bulk() was switching the SQLite journal mode from WAL to
MEMORY for write throughput.  If the process crashed mid-bulk-write the
in-memory rollback journal was lost, leaving the database file in a
partially-written, unrecoverable state.

WAL mode is inherently crash-safe: uncommitted WAL entries are discarded
on the next open.  The performance benefit of bulk mode is preserved via
synchronous=OFF and an enlarged cache_size, both of which are safe under
WAL.

Remove the PRAGMA journal_mode = MEMORY from cbm_store_begin_bulk and
the matching PRAGMA journal_mode = WAL from cbm_store_end_bulk.  Update
the header comments to reflect the new invariant.

Add tests/test_store_bulk.c with three tests:
- bulk_pragma_wal_invariant: asserts journal_mode remains "wal" after
  cbm_store_begin_bulk via an independent read-only connection
- bulk_pragma_end_wal_invariant: asserts journal_mode remains "wal" after
  cbm_store_end_bulk
- bulk_crash_recovery: forks a child that enters bulk mode, opens an
  explicit transaction, writes data, then calls _exit() without committing;
  the parent verifies the database opens cleanly and baseline data survives

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 17:21:48 -05:00
Martin Vogel 7629940dca Restore session auto-detect + auto-index + config CLI from Go
- Config store: persistent SQLite key-value in _config.db (get/set/delete/bool/int)
- Config CLI: codebase-memory-mcp config list|get|set|reset
  Keys: auto_index (default false), auto_index_limit (default 50000)
- Session detection: detect project root from CWD on MCP initialize
- Auto-index: if auto_index=true and project not yet indexed, background pipeline
- Watcher hookup: after index completes, register project for ongoing git polling
- 6 new config store tests (open/close, get/set, bool, int, delete, persistence)

Enable auto-indexing:
  codebase-memory-mcp config set auto_index true
2026-03-19 20:13:17 +01:00
442cb958f0 Add KiloCode support, fix Zed JSONC parsing (#24, #53)
- KiloCode: detect globalStorage dir, upsert mcp_settings.json, install
  global rules at ~/.kilocode/rules/codebase-memory-mcp.md
- Zed: parse JSONC (comments + trailing commas) in existing settings.json
  — fixes "Invalid JSON" error on install with existing Zed config
- 2 new tests: KiloCode detection, Zed JSONC settings parsing
- Now supports 8 agents: Claude Code, Codex, Gemini, Zed, OpenCode,
  Antigravity, Aider, KiloCode

Co-Authored-By: David34920 <179368816+David34920@users.noreply.github.com>
Co-Authored-By: Paul Cohen <200370+sonicviz@users.noreply.github.com>
Co-Authored-By: Chitral Verma <11135032+chitralverma@users.noreply.github.com>
Co-Authored-By: Noel Kurian <1851449+noelkurian@users.noreply.github.com>
Co-Authored-By: José Almeida <57680069+zeval@users.noreply.github.com>
Co-Authored-By: Vasani Harshil <147682127+harshil480@users.noreply.github.com>
2026-03-19 18:56:16 +01:00
Martin Vogel 159378ad8e Multi-agent install: auto-detect 7 coding agents, upsert configs + hooks + instructions
- Detect Claude Code, Codex CLI, Gemini CLI, Zed, OpenCode, Antigravity, Aider
- Per-agent MCP config upsert: Codex TOML, OpenCode JSON, Antigravity JSON
- Instruction file upsert with marker-based sections (no duplicates on re-install)
- Claude Code PreToolUse hook (Grep|Glob|Read -> MCP reminder)
- Gemini CLI BeforeTool hook (grep_search|read_file -> MCP reminder)
- Fix Zed MCP config: args:[""] instead of broken source:"custom" (#24)
- Rewrite skill descriptions to directive pattern (100% auto-activation)
- Keyword-rich MCP tool descriptions for Tool Search discovery
- 35 new tests (agent detection, config upsert, instructions, hooks)
- All platforms green: macOS 2022, Linux 2004+18skip, Windows cross-compile OK
2026-03-19 16:08:43 +01:00
Martin Vogel 0d7a9a891b Fix Windows UI config tests: replace system("mkdir -p") with cbm_mkdir_p()
Two UI config tests (config_corrupt_file, config_missing_fields) used
Unix-only system("mkdir -p") to create test directories. On Windows this
fails with "The syntax of the command is incorrect." — replaced with the
portable cbm_mkdir_p() function already in compat_fs.h.
2026-03-19 03:48:10 +01:00
Martin Vogel 3abc5cdf02 Fix flaky parallelism test, skip 4 remaining Windows compat issues
- parallel_for_actually_parallel: skip on single-core CI runners
  instead of failing (assertion requires >= 2 concurrent threads)
- Fix mkdir -p → portable mkdir in test_ui.c config tests
- Skip store_dump_to_file and cli_find_cli_on_path on Windows
  (temp file path handling and PATH search need porting)
2026-03-19 03:34:36 +01:00
Martin Vogel 90577d45b0 Skip 12 discover tests on Windows (use Unix shell commands)
Discover integration tests use system("rm -rf && mkdir -p && echo >")
which are Unix shell commands. These tests are properly skipped on
Windows with SKIP_UNIX_SHELL macro. The remaining 4 Windows test
failures (store_dump, cli_find, ui_config x2) need individual fixes.

TODO: Port discover test helpers to use C file operations.
2026-03-19 03:19:06 +01:00
Martin Vogel 18c23d438f Fix 12 more Windows test failures: mkstemp, temp paths, TRE config
- cbm_mkstemp: Windows implementation using _mktemp + _open
- cbm_tmpdir(): portable temp directory function (replaces /tmp/)
- Fix hardcoded /tmp/ paths in test_language, test_gitignore,
  test_store_search, test_sqlite_writer
- Enlarge remaining small path buffers for Windows %TEMP% paths
2026-03-19 02:58:03 +01:00
Martin Vogel d6ec954b9c Fix cbm_mkdtemp: enlarge all test buffers to 256 bytes
The /tmp/ → %TEMP%\ translation produces longer paths (~50 chars)
than the original templates (~25 chars). Changed all 68 test
declarations from char tmpdir[] = "..." (sized to literal) to
char tmpdir[256] with snprintf initialization.
2026-03-19 02:38:02 +01:00
Martin Vogel fdb83f83f7 Fix Windows test compilation: mkdtemp, mkdir, setenv, pipe compat
- cbm_mkdtemp: _mktemp + _mkdir on Windows
- cbm_setenv/cbm_unsetenv: _putenv_s on Windows
- cbm_pipe: _pipe on Windows
- Replace bare POSIX calls in 12 test files with compat wrappers
- All test files now include compat.h
2026-03-18 19:19:42 +01:00
Martin Vogel 85fc74fc31 Full Windows portability: proper implementations, not stubs
- handle_processes: GetProcessMemoryInfo + GetProcessTimes (Windows),
  getrusage (POSIX) — real process metrics on both platforms
- handle_process_kill: TerminateProcess via OpenProcess (Windows),
  kill(SIGTERM) (POSIX)
- index_thread_fn: CreateProcess + WaitForSingleObject (Windows),
  fork+exec+waitpid (POSIX)
- cbm_clock_gettime: QueryPerformanceCounter (Windows) — replaces
  all bare clock_gettime calls across 6 files
- cbm_nanosleep, cbm_strcasestr, cbm_mkdir: compat shims
- CBM_TLS: _Thread_local (C11 standard, works on all compilers)
- Replace bare strndup with cbm_strndup, guard POSIX headers
- Add mingw-w64 cross-compile to Docker test infrastructure
2026-03-18 18:47:43 +01:00
Martin Vogel a1d849aaaa Fix all memory leaks, vendor sqlite3, add Docker test infrastructure
Leak fixes (13 sources, 1.4MB → 0 bytes):
- Cypher: free col_names after rb_set_columns, free rejected inline
  prop nodes, store WITH aliases in qualified_name for auto-cleanup
- Store: add cbm_project_free_fields, fix find_node_ids_by_qns leak
- Graph buffer: free strdup'd hash keys during delete operations
- SQL scanner: free old start_tag before reassignment in deserialize

Platform independence:
- Vendor sqlite3 amalgamation (3.49.1) — eliminates system libsqlite3
  dependency, enables full ASan/LeakSanitizer instrumentation
- Add -I for vendored tree-sitter unicode headers — eliminates hidden
  dependency on system libicu-dev
- Add test-infrastructure/ with Docker Compose for local GCC+ASan
  testing that mirrors CI exactly
2026-03-18 16:28:27 +01:00
Martin Vogel bc66541765 Remove unused system_info fields: cache, free_ram, efficiency_cores
These 5 fields were detected on 3 platforms but never consumed by any
production code. The L2 cache sysfs fallback added in the previous
commit existed solely to fix a test for a value nobody reads.

Removes ~120 lines of platform-specific detection (Mach VM stats,
/proc/meminfo parsing, sysfs cache scan) and 3 dead tests.
2026-03-18 14:51:29 +01:00
Martin Vogel c9ec1d1eb4 Fix Ubuntu CI: stack-use-after-return, L2 cache detection, memory leaks
- Arena-allocate pair_field_types in cpp_stdlib_data.c (was stack array
  escaping scope via registry pointer — caught by GCC ASan)
- Add sysfs fallback for L2 cache on Linux ARM (sysconf returns 0)
- Expose cbm_node_free_fields() and fix 12+ leak sites in tests where
  find_node_by_id/qn results were never freed (caught by LeakSanitizer)
2026-03-18 14:23:46 +01:00
Martin Vogel ef512c3508 Remove macOS-internal headers inserted by clang-tidy (breaks Linux/GCC) 2026-03-18 01:52:05 +01:00
Martin Vogel 05a6516597 Fix httplink_linker_route_nodes: remove store dep, test pure route extraction 2026-03-18 01:12:27 +01:00
Martin Vogel 18fa9979ee Replace vmem with mimalloc global allocator, add extraction-phase prescan, fix __init__.py QN collision
Memory management:
- Vendor mimalloc v2.1.9 as global allocator (MI_OVERRIDE=1 in prod)
- New mem.h/mem.c: RSS-based budget tracking via mi_process_info()
- Remove vmem.c/vmem.h (mmap-based budget tracking)
- Remove slab tier2 bump allocator (~300 LOC); >64B goes to mimalloc
- Slab tier1 pages from malloc (= mimalloc) instead of vmem
- Arena blocks from malloc instead of vmem
- Budget raised from 35% to 50% RAM (no more untracked C++ heap)

Extraction-phase prescan (eliminates disk re-reads):
- HTTP call sites: keyword check + URL extraction during extraction
- HTTP routes: decorator + source-based extraction during extraction
- Config file refs: regex scan during extraction
- httplinks: 41.8s → 13ms on Linux kernel (3,212x faster)
- configlink: 41.4s → 0.8s on Linux kernel (54x faster)
- Linux kernel fast-mode total: 2m38s → 1m18s

Bug fixes:
- __init__.py Module QN no longer collides with Folder QN
- index.ts same fix for JS/TS packages
- 13 regression tests for QN collision at FQN + extraction layers
- search_graph/search_code default limit raised from 10 to 500k
- Resolve all clang-tidy, cppcheck, and clang-format warnings

Repo cleanup:
- tree-sitter-form, tree-sitter-magma moved to tools/
- .gitignore: build/, node_modules/, graph-ui/dist/, TEST_PLAN.md
2026-03-17 22:05:57 +01:00
Martin Vogel 0d216c7936 Resolve all clang-tidy, cppcheck, and clang-format warnings across 94 files
Enforce WarningsAsErrors: '*' with zero suppressions of entire check categories.
All non-FP warnings fixed at source; true false positives get per-instance NOLINT
with reasoning. Fixes include: braces around statements (1679), isolate declarations
(75), explicit casts for multilevel pointer conversions, missing includes, function
parameter documentation via NOLINT, and proper NOLINTBEGIN/NOLINTEND nesting.
2026-03-15 22:37:34 +01:00
Martin Vogel 94a9a92f83 Add C-native pipeline with blocking clang-tidy, cppcheck, clang-format linting
Complete C implementation of the indexing pipeline (src/), parallel worker
pool, graph buffer with merge support, SQLite writer, and 1893-test suite.

Linter setup: zero warnings from clang-tidy (all checks enabled, no NOLINT
suppressions), cppcheck, and clang-format. All issues fixed at source —
proper headers for external linkage, GROW_ARRAY macro restructured to
eliminate type parameter, null-deref paths guarded, named intermediates
for suspicious-argument checks.
2026-03-15 19:26:12 +01:00