Formal models and scripts: study-hnsw-concurrent-merge
Tools: TLA+/TLC, Python
These are the working models and scripts this part of the hunt used. Some encode the code as it is (a counterexample is the expected result), others a fixed or correct variant; read the header comment of each file. Paths inside them were replaced by placeholders such as $LUCENE (a Lucene checkout) and $WORK.
Findings
- HNSW merge-time graph reuse can leave the entry node with no neighbours, dropping kNN recall to zero (finding LFV-005; repro · finding page)
- Concurrent HNSW build retries a lost entry-node promotion with the wrong query vector (finding LFV-061; repro · finding page)
- HNSW addConnections descends from the worst upper-level candidate instead of the best (finding LFV-068; repro · finding page)
Files
model/C1.cfgmodel/C1b.cfgmodel/C1fix.cfgmodel/C2bug.cfgmodel/C2fix.cfgmodel/C2reach.cfgmodel/C2reachSeq.cfgmodel/C2split3.cfgmodel/C3fix.cfgmodel/C3split.cfgmodel/C3w3bug.cfgmodel/C3w3fix.cfgmodel/C4bug.cfgmodel/C4fix.cfgmodel/C6bug.cfgmodel/C6fix.cfgmodel/C6w3fix.cfgmodel/HnswConc.tlamodel/MC.tlamodel/MC_S1.tlamodel/MC_S2.tlamodel/MC_S3.tlamodel/R1.cfgmodel/R2.cfgmodel/R3.cfgmodel/R5.cfgmodel/R5bug.cfgmodel/R5split.cfgmodel/R6w3.cfgmodel/S1_conc.cfgmodel/S2_conc.cfgmodel/S3_conc.cfgscripts/mkcfg.pyscripts/serial.pyscripts/trace.pysmt/hnswlock_index.py
How to run
- TLA+ with TLC:
java -cp tla2tools.jar tlc2.TLC -config <Model>.cfg <Model>.tla(a counterexample trace is the finding when the model encodes the current code). - Python:
python3 <file>.py; scripts that importz3need thez3-solverpackage.
Snapshot of 2026-11-03. AI-assisted; not yet triaged by a human Lucene committer. Feedback: open an issue in lucene-ai-bug-hunt.