Architecture change to prevent concurrent write corruption:
Indexing (new project): cbm_write_db writes project.db directly
Reindexing (existing): delete project.db, then index as new
Incremental: upsert changes into existing project.db (unchanged)
Root cause: rename(project.db.tmp, project.db) while watcher/MCP
had the old file open via SQLite caused WAL corruption — stale
connections wrote to deleted inodes.
Changes:
- cbm_gbuf_dump_to_sqlite: write to final path, no .tmp + rename
- pipeline.c: if DB exists but not eligible for incremental, delete
it before proceeding with full index (reindex = delete + index)
- Pipeline lock (atomic spinlock) serializes concurrent runs:
MCP/autoindex block, watcher skips if busy
- delete_project acquires pipeline lock before unlinking
- BEGIN IMMEDIATE for all write transactions (respects busy_timeout)
- cbm_store_check_integrity: detects corrupt DBs (>5 project rows
or invalid root_path), auto-deletes with ERROR log
- cbm_store_get_db accessor for test corruption simulation
Tests: 5 integrity tests + 4 concurrency lock tests
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
- CBM_TLS: use _Thread_local (C11 standard) instead of __declspec(thread)
which only works on MSVC, not MinGW GCC
- Replace bare strndup() with cbm_strndup() in 6 files (strndup is POSIX,
not available on Windows)
- Guard sys/wait.h with #ifndef _WIN32 in http_server.c
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.
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.