Files
codebase-memory-mcp/src/simhash
Martin Vogel d9ea73f9e4 fix(index): make parallel indexing deterministic (byte-identical runs)
Multi-threaded indexing produced a different graph on every run (xfs: node
labels flipping Class/Function/Macro, ~2k edge lines differing across USAGE/
CALLS/IMPORTS/SIMILAR_TO/SEMANTICALLY_RELATED) and lost edges vs repeated
runs. Five root causes, all order- or scheduling-dependence:

1. gbuf QN collisions resolved last-wins in MERGE ORDER: in C a struct, a
   function and a macro can share one name, and the QN scheme does not encode
   entity kind, so whichever entity a worker merged last overwrote the node's
   label/name/lines/props (the flickering node set that fed every pass). Both
   cbm_gbuf_upsert_node and the parallel-merge path now keep the SAME entity's
   refresh semantics but resolve cross-entity collisions by a canonical
   content rule -- lexicographically smallest (label, file_path, start_line,
   name) -- and keep the label/name secondary indexes consistent when the
   survivor changes (the old overwrite left nodes listed under their original
   label, which is how the flicker reached find_by_label consumers).
2. Semantic-edges admission raced per-node max_edges budgets on shared atomic
   counters under dynamic scheduling: scoring stays parallel and pure; pairs
   carry (func index, candidate rank); one sequential pass admits in canonical
   order. funcs[] itself is sorted by qualified name up front (the label-index
   scan order is merge order).
3. Import resolution's symbol-name fallback returned the FIRST same-named node
   in registration order; now the lexicographically-smallest-QN candidate.
4. Similarity entries inherited merge order into LSH chains + per-node cap
   truncation, and pair ownership keyed on run-varying node ids; entries are
   sorted by QN and ownership compares QNs (lsh entries carry the QN).
5. Call-neighbor context (semantic vectors + tokens) truncated MAX_CALLEES
   subsets in edge-array order; neighbor names are sorted first.

Verified: four consecutive multi-threaded kernel-xfs runs produce byte-
identical sorted node AND edge sets (13341/58598, zero diff). The repro guard
repro_parallel_edge_determinism (MT x K mutual equality) is GREEN; a new
deliberately-RED repro_seq_parallel_equivalence tracks the remaining OPEN bug
that the sequential and parallel pipelines systematically disagree (~3459
USAGE / ~1666 WRITES lines on xfs) -- separate code paths, fix deferred.
Suites: pipeline 216, c_lsp 750, rust_lsp 506, py_lsp 63, java 94, kotlin 78,
php 278, registry 54, store_nodes 56, incremental 161, semantic 32, simhash 24
(one test updated: SIMILAR_TO pair direction is now canonical by QN), mcp 140,
subprocess 17 -- zero failures.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-06 19:32:03 +02:00
..