GitNexus/gitnexus/test
Copilot 1df79c2eab
fix: content-hash staleness detection for embeddings and vector index creation on zero-node path (#831)
* Initial plan

* fix: stale vectors preserved on content edits and vector index missing after zero-node run

Issue 1: Add contentHash to EMBEDDING_SCHEMA and embedding pipeline.
- contentHash column persisted per CodeEmbedding row
- POST /api/embed queries nodeId+contentHash, compares per-node hash
- Stale rows (hash mismatch) are DELETE'd before re-embedding
- Legacy DBs without contentHash treated as stale (full re-embed)
- loadCachedEmbeddings and run-analyze cache restore include contentHash

Issue 2: createVectorIndex called unconditionally before zero-node early return.

Regression tests:
- contentHashForNode determinism and content-change detection
- EMBEDDING_SCHEMA includes contentHash STRING column
- Pipeline exports verified

Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/1581c0c0-f359-4376-b47e-62d24a28fd2d

Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com>

* fix: use parameterized query for stale embedding DELETE, revert package-lock.json

Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/1581c0c0-f359-4376-b47e-62d24a28fd2d

Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com>

* fix: address review feedback — config consistency, narrow catches, extract DB logic

Bug #1: Use finalConfig consistently in contentHashForNode (line 224 was
using raw `config` while line 307 used `finalConfig`). Cache precomputed
hashes in filter phase to avoid double computation (Perf #5).

Bug #2: Narrow catch in loadCachedEmbeddings to only fall back on
column/table-missing errors. Rethrow transient/connection errors.

Bug #3: Log non-trivial DELETE failures instead of silently swallowing.

Arch Violation #3: Extract fetchExistingEmbeddingHashes from api.ts into
lbug-adapter.ts. Server layer now calls a single adapter function instead
of re-implementing the DB query logic with nested try-catch.

Tests: Add config consistency test, note that fetchExistingEmbeddingHashes
tests require native module (run in CI).

Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/b8c4f6b0-4095-4507-a15d-d8469793efac

Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com>

* fix: narrow Column error match to 'contentHash' in lbug-adapter fallback checks

Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/b8c4f6b0-4095-4507-a15d-d8469793efac

Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com>

* fix: address production-readiness review — eliminate competing state, use schema constants, hard-fail on stale DELETE, add incremental filter tests

Gap A / Arch Violation 1: Remove duplicate vectorExtensionLoaded flag from
embedding-pipeline.ts — delegate to lbug-adapter's loadVectorExtension()
which owns the VECTOR extension lifecycle and resets on DB reconnect.

Arch Violation 2: Replace all hardcoded 'CodeEmbedding' and
'code_embedding_idx' strings in embedding-pipeline.ts and run-analyze.ts
with EMBEDDING_TABLE_NAME, EMBEDDING_INDEX_NAME, and CREATE_VECTOR_INDEX_QUERY
imported from schema.ts. Add EMBEDDING_INDEX_NAME export to schema.ts.

Gap B: Make DELETE failure for stale vectors a hard throw (not just a
warning). Continuing after failed DELETE risks Kuzu vector-index corruption
since the constraint requires DELETE-before-INSERT for vector-indexed
properties. "not found" / "does not exist" errors are still safe to ignore.

STALE_HASH_SENTINEL: Define a named constant in embedding types.ts for the
empty-string sentinel convention. Used consistently in lbug-adapter.ts and
run-analyze.ts so the invariant is self-documenting.

Tests: Add comprehensive unit tests for the incremental filter logic with
mocked embedder:
- New node → embedded
- Unchanged node (hash matches) → skipped
- Stale node (hash mismatch) → DELETE + re-embed
- STALE_HASH_SENTINEL → treated as stale
- Zero nodes after filter → createVectorIndex still called
- DELETE failure with non-trivial error → throws

Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/b21edee7-c9c5-4742-947b-d0def4fb26aa

Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com>

* fix: tighten error classification — extract isMissingColumnOrTableError helper, remove broad pattern matching

- Extract isMissingColumnOrTableError() helper in lbug-adapter for
  consistent schema-error detection (replaces duplicate inline checks)
- Tighten 'contentHash' match: now requires 'property' AND 'contentHash'
  (Kuzu-specific pattern) instead of broad 'contentHash' substring
- Tighten DELETE error check: only ignore 'does not exist' (Kuzu's actual
  message), not broad 'not found' which could mask connection errors
- Fix test node ID/name/filePath consistency

Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/b21edee7-c9c5-4742-947b-d0def4fb26aa

Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com>

* fix: CI failures and final review — move STALE_HASH_SENTINEL to schema, tighten error matching, fix test mocking, format

- Move STALE_HASH_SENTINEL from embeddings/types.ts to lbug/schema.ts
  (fixes inverted layer dependency: lbug should not import from embeddings)
- Tighten isMissingColumnOrTableError: replace broad msg.includes('not found')
  with /(table|column|property).*not found/i regex to avoid matching transient errors
- Add vi.resetModules() in test beforeEach for explicit module isolation
  (fixes vi.doMock not intercepting loadVectorExtension in CI)
- Skip precomputedHashes.set() on unchanged (return false) path
- Run prettier on all 5 files flagged by CI format check

Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/e20311fd-4361-47b4-a137-9adc3e533b35

* fix: address remaining review nits — rename precomputedHashes, generalize error matcher, revert package-lock

- Rename precomputedHashes → computedStaleHashes (hashes are computed
  on-demand during filter, only cached for stale nodes being re-embedded)
- Remove contentHash-specific clause from isMissingColumnOrTableError —
  the regex /(table|column|property).*not found/i already covers it
- Revert package-lock.json ssh→https protocol change

Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/e20311fd-4361-47b4-a137-9adc3e533b35

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com>
2026-04-15 11:20:48 +01:00
..
fixtures fix: resolve C/C++ cross-file calls through transitive #include chains (#816) 2026-04-14 09:39:17 +01:00
helpers Fix security issues and critical bugs found in code review (#709) 2026-04-10 05:20:29 +01:00
integration fix: resolve C/C++ cross-file calls through transitive #include chains (#816) 2026-04-14 09:39:17 +01:00
unit fix: content-hash staleness detection for embeddings and vector index creation on zero-node path (#831) 2026-04-15 11:20:48 +01:00
utils ci: add macOS to cross-platform test matrix (#208) 2026-03-07 10:38:32 +00:00
global-setup.ts feat: upgrade @ladybugdb/core to 0.15.2 and remove segfault workarounds (#374) 2026-03-19 08:25:43 +00:00
vitest.d.ts refactor: migrate from KuzuDB to LadybugDB v0.15 (#275) 2026-03-15 15:53:01 +00:00