Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
25664ff
HNSW native traversal plane: design doc + Rust prototype (mmap fixed-…
kriszyp Aug 31, 2026
18a0150
hnsw-plane: zero-copy search, AVX2 kernels, optimizeRouting-parity in…
kriszyp Aug 31, 2026
c69fdc8
bench: reuse existing plane file for ef sweeps; parameterize layer0 cap
kriszyp Aug 31, 2026
b83b7e6
graph: persist upper-layer adjacency via sidecar file
kriszyp Aug 31, 2026
815aa13
design: cap-128 for the int8 plane — measured, not assumed
kriszyp Aug 31, 2026
94c7c6f
hnsw-plane: NAPI surface, bitset filtering, page-grouped layout, conc…
kriszyp Aug 31, 2026
051d9aa
hnsw-plane: pipelined TSFN predicate filtering
kriszyp Aug 31, 2026
4afa9e8
hnsw-plane: in-file upper-layer region (format v2)
kriszyp Aug 31, 2026
bc21630
design: record format-v2 1M regression check (recall/visits identical)
kriszyp Aug 31, 2026
0d80864
hnsw-plane: raw mirroring surface for dual-write phase 1
kriszyp Aug 31, 2026
fe7d539
hnsw-plane: upper-entry freelist + coverage-aware reverse-edge pruning
kriszyp Aug 31, 2026
9a9bca8
design: coverage-prune + concurrency measurements (0.999 recall, 6.3K…
kriszyp Aug 31, 2026
040d01f
HNSW native plane phase 1: dual-write mirroring + opt-in native searc…
kriszyp Aug 31, 2026
efd556a
Review round 1: watermark-gated plane readiness, sync-iteration guard…
kriszyp Aug 31, 2026
98f9574
Review round 2: predicate-throw containment, exact filtered visit bud…
kriszyp Aug 31, 2026
26a0cfa
Review round 2b: query-dims safety guard, creation-dims from the grap…
kriszyp Aug 31, 2026
35f0dc9
Review round 3: contain synchronous NAPI throws; promise-shaped itera…
kriszyp Aug 31, 2026
730c871
Review round 3b: layer-0 cap derived from M, durable initial mirror, …
kriszyp Aug 31, 2026
f05a95f
Review round 4: flush graph before watermark; refuse over-ceiling M i…
kriszyp Aug 31, 2026
0d112b5
Review round 5: delete the plane file when the flag is disabled
kriszyp Aug 31, 2026
9b40adb
design: record reservation (sparse-reserve) and repo-split (HarperFas…
kriszyp Aug 31, 2026
41feb1e
hnsw-plane: Apache-2.0 license (house license, matches HarperFast/hnsw)
kriszyp Aug 31, 2026
e2765e1
hnsw-plane: fix review blockers — crash-window scrub, bounds, entry r…
kriszyp Aug 31, 2026
2cec9e2
hnsw-plane + integration: fix cross-model review majors
kriszyp Aug 31, 2026
78d62ce
design: record phase-1 accepted limitations from review round 1
kriszyp Aug 31, 2026
7a5564f
hnsw-plane + integration: round-2 review fixes — lazy seqlock takeove…
kriszyp Aug 31, 2026
663c767
hnsw-plane integration: keep single-chunk builds synchronous
kriszyp Aug 31, 2026
5cd23bb
hnsw-plane integration: current the plane handle before the builder's…
kriszyp Aug 31, 2026
8f9ebe7
hnsw-plane: owner-identity locks (round-3 blocker) + remaining round-…
kriszyp Aug 31, 2026
5b85fe5
hnsw-plane: registry-based owner liveness (round-4 blocker) + remaini…
kriszyp Sep 1, 2026
275690d
hnsw-plane: bounded writer wedge (round-5 blocker) — unreclaimable lo…
kriszyp Sep 1, 2026
b8dd488
hnsw-plane: round-6 residuals — wedge timer resets on owner churn, cl…
kriszyp Sep 1, 2026
2d2755a
hnsw-plane: round-7 refinements — epoch identity, salted acquisitions…
kriszyp Sep 1, 2026
acfae8e
hnsw-plane: unique per-thread salt streams; guard file-sourced upper …
kriszyp Sep 1, 2026
74efde7
hnsw-plane: tombstoned virgin slots initialize upper_idx to NO_UPPER
kriszyp Sep 1, 2026
f73a1b5
hnsw-plane: takeover sanitizer also resets the slot's upper index
kriszyp Sep 1, 2026
88fe0c7
hnsw-plane: prettier reflow for the two files Format Check flagged
kriszyp Sep 1, 2026
07de4a4
hnsw-plane: drop a dead bounds check, repair smoke.mjs, refresh Cargo…
kriszyp Sep 1, 2026
e670636
hnsw-plane: stop the dual-write path guessing and inheriting upper en…
kriszyp Sep 1, 2026
8d967c3
hnsw-plane: free a fresh upper entry when publishing the slot wedges
kriszyp Sep 1, 2026
b16362c
hnsw-plane: free the backfill scan's upper entry when its slot lock w…
kriszyp Sep 1, 2026
365d7e2
hnsw-plane: bound the test lock handshakes and assert their write res…
kriszyp Sep 1, 2026
e2d76de
hnsw-plane: make the test holders prove they took the lock
kriszyp Sep 1, 2026
52e5fd5
hnsw-plane: restore MADV_RANDOM (dropped by a parallel-worktree repla…
kriszyp Sep 1, 2026
bab065a
hnsw-plane: close the five open review threads on #2430
kriszyp Sep 1, 2026
b434509
hnsw-plane: entry-point ordering and hint quality from the review round
kriszyp Sep 1, 2026
9db1218
hnsw-plane: durable plane invalidation and a repair that cannot lose
kriszyp Sep 1, 2026
b891214
hnsw-plane: probe the whole id range for a repair candidate
kriszyp Sep 1, 2026
faf1f99
hnsw-plane: rotate the repair probe so it cannot skip a residue class
kriszyp Sep 1, 2026
1a86e55
hnsw-plane: make the repair-probe rotation per plane
kriszyp Sep 1, 2026
70a4fe6
hnsw-plane: ceil the repair-probe stride so no low prefix is unreachable
kriszyp Sep 1, 2026
e0f1ca3
hnsw-plane: return a predicated search on its last verdict, not 50 ms…
kriszyp Sep 1, 2026
2ea14fa
hnsw-plane: take the best of several queries in the drain latency test
kriszyp Sep 1, 2026
27eda01
hnsw-plane: three defects from the recorded review backlog
kriszyp Sep 1, 2026
c0d3299
hnsw-plane: state the contended merge's victim as arbitrary, not fart…
kriszyp Sep 1, 2026
ad198eb
hnsw-plane: let the bench's build loop fail loudly on a rejected insert
kriszyp Sep 1, 2026
a55adf0
chore: rebase native HNSW plane onto main
kriszyp Sep 1, 2026
a0f735d
style: format query array scoping test
kriszyp Sep 1, 2026
e151875
Merge origin/main into native HNSW plane
kriszyp Sep 4, 2026
0028bb3
Consume the native HNSW plane as @harperfast/hnsw 0.2.1 instead of an…
kriszyp Sep 4, 2026
87e0fd7
Address the pre-push review: strict build in the plane CI job, mispla…
kriszyp Sep 4, 2026
df1b483
Merge remote-tracking branch 'origin/main' into kris/hnsw-native-plane
kriszyp Sep 8, 2026
17b8a34
Make native HNSW index file-primary
kriszyp Sep 8, 2026
bfab525
Harden native HNSW recovery
kriszyp Sep 8, 2026
e7adb5d
Document the file-primary requirements and non-guarantees
kriszyp Sep 8, 2026
4ce6259
Address the pre-push review of the file-primary derived index
kriszyp Sep 9, 2026
91b7402
Prove emptiness before answering a file-primary vector query with no …
kriszyp Sep 9, 2026
5514c0b
Schedule the repair a lost native file needs, and close the audit-gua…
kriszyp Sep 9, 2026
1eac171
Record the shared-readiness gap behind both cross-worker rebuild resi…
kriszyp Sep 9, 2026
4a38085
Correct the recurrence claim in the shared-readiness note
kriszyp Sep 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,47 @@ jobs:
- name: Run unit tests
timeout-minutes: 30
run: npm run test:unit:windows

# The vectorIndexPlane suite self-skips when the optional native package is absent, so the
# load probe below is what keeps that skip from reading as a green run. The crate's own
# tests belong to HarperFast/hnsw's CI, not here: this job runs the published prebuild, so
# testing the crate source would grade something other than the binary under test.
hnsw-plane:
name: HNSW native plane (Node.js v24)
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0

- name: Setup Node.js 24
uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
with:
node-version: 24
package-manager-cache: false

- name: Install dependencies
run: npm install --ignore-scripts

# strict here, unlike the other jobs: the plane suite runs against dist/, so a tolerated
# build failure would grade a stale dist and still report green
- name: Build
run: npm run build

- name: Verify the published native binding loads
run: node -e "if (typeof require('@harperfast/hnsw').Plane?.open !== 'function') throw new Error('@harperfast/hnsw loaded without a Plane constructor');"

- name: Setup Harper
env:
DEFAULTS_MODE: 'dev'
HDB_ADMIN_USERNAME: 'admin'
HDB_ADMIN_PASSWORD: 'password'
ROOTPATH: '/tmp/hdb'
NODE_HOSTNAME: 'localhost'
LOGGING_LEVEL: 'info'
run: node --enable-source-maps ./dist/bin/harper.js install

- name: File-primary native plane tests
env:
HNSW_NATIVE_REBUILD_BENCHMARK: '1'
run: npx mocha unitTests/resources/vectorIndexPlane.test.js
12 changes: 12 additions & 0 deletions dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,3 +243,15 @@ This is the inverse of the entries below — a dependency we take deliberate ste
- Security: Microsoft-maintained TypeScript compiler, same publisher/package as the 5.x devDependency.
- Overlap: Complements, does not replace, the `typescript` devDependency — TypeScript 7.0 ships no compiler API yet (planned for 7.1), so `@typescript-eslint/parser` still needs `typescript` 5.x. The 5.x and 7.x versions never coexist in `node_modules` at once: 5.x is the installed devDependency, 7.x is fetched on-demand by `npx` purely for `typecheck:fast`.
- Eventual removal: Once TypeScript 7 stabilizes as the primary `typescript` devDependency (post-7.1's compiler API), this becomes redundant and `typecheck:fast` can be dropped.

## @harperfast/hnsw (optional dependency)

- Need for usage: Supplies the file-primary memory-mapped HNSW index used only by indexes that opt in with `nativePlane: true`. Harper keeps primary-key mappings and replay cursors in RocksDB; graph nodes and adjacency exist only in the native file.
- Size/memory cost: The JS/package metadata is about 250 KB unpacked plus one platform-specific native binary. Runtime mapped-file size is approximately 1,344 bytes per 768-dimensional int8 node at layer-0 cap 128; mappings are shared by the OS page cache across workers.
- Security: First-party Apache-2.0 Harper package. It runs native code in-process, so Harper exact-pins the package and its own manifest exact-pins every platform prebuild to the same version. The dedicated CI job loads the registry prebuild and tests Harper against it.
- Environment interaction: Lazily loaded only when an eligible index enables `nativePlane`; it creates a memory-mapped `.hnsw` derived-index file next to the index store and may create a `.stale` invalidation sidecar. It does not modify globals or install polyfills.
- Overlap: None for an opted-in index. Ordinary HNSW indexes continue to use the JS/RocksDB graph; `nativePlane` indexes use native insert, mutation, and search through the shared post-commit derived-index runtime.
- Transitive dependencies: Only exact-version, platform-specific optional prebuild packages; no JS runtime dependency tree.
- Binary compilation: Supported Linux glibc x64/arm64, macOS arm64, and Windows x64 targets use prebuilds. Other targets attempt a Rust source build. Because the root package is optional Harper still installs if that build fails, but opted-in indexes remain unavailable until the module is present.
- Can be deferred: Yes for ordinary HNSW indexes. The adapter loads lazily; an opted-in index returns 503 and retries rebuild when the native module is unavailable.
- Eventual removal: Disable `nativePlane`, allow the schema reindex to rebuild the ordinary JS/CF graph, then remove the optional dependency and adapter integration.
Loading
Loading