Three identical full-mode indexes of the same flask checkout with the same binary produced SEMANTICALLY_RELATED counts of 74 / 59 / 126, with only ~50% of the edge set shared between runs (HANDLES: 214/213/214 = fine; SIMILAR_TO: 18/18/18 byte-stable). On django: 79 vs 58 across runs.
The comment at src/pipeline/pass_semantic_edges.c:74 shows one worker-scheduling dependence was already fixed ("per-node max_edges budget no longer depends on worker scheduling") — but the remaining selection still varies with scheduling order, most plausibly the per-node edge budget consuming LSH candidates in completion order.
Impact assessment: absolute scale is tiny (~0.02% of the graph; advisory edge class), so not release-blocking — but it violates the deterministic-output property the indexer otherwise holds (MT indexing is byte-identical since the kernel-perf work), makes A/B comparisons noisy, and churns incremental artifacts.
Fix direction: make candidate ordering deterministic before applying the per-node budget (sort candidates by (score, qn) instead of arrival order), same recipe as the earlier fix at :74.
Three identical full-mode indexes of the same flask checkout with the same binary produced SEMANTICALLY_RELATED counts of 74 / 59 / 126, with only ~50% of the edge set shared between runs (HANDLES: 214/213/214 = fine; SIMILAR_TO: 18/18/18 byte-stable). On django: 79 vs 58 across runs.
The comment at
src/pipeline/pass_semantic_edges.c:74shows one worker-scheduling dependence was already fixed ("per-node max_edges budget no longer depends on worker scheduling") — but the remaining selection still varies with scheduling order, most plausibly the per-node edge budget consuming LSH candidates in completion order.Impact assessment: absolute scale is tiny (~0.02% of the graph; advisory edge class), so not release-blocking — but it violates the deterministic-output property the indexer otherwise holds (MT indexing is byte-identical since the kernel-perf work), makes A/B comparisons noisy, and churns incremental artifacts.
Fix direction: make candidate ordering deterministic before applying the per-node budget (sort candidates by (score, qn) instead of arrival order), same recipe as the earlier fix at :74.