You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Directory filter bypass — search(directory=...) used startswith() which matched /project_evil when filtering for /project. Now uses Path.is_relative_to().
Special files passed to formatter — _format_file now rejects char devices, pipes, and /proc entries via stat.S_ISREG before spawning subprocess.
Startup crash on init failure — UnboundLocalError when SemanticCache() or warmup() raised during lifespan. cache is now initialized to None with proper guards.
Negative offset/limit silently wrapping — read tool now validates offset >= 1 and limit >= 1; max_size clamped to prevent unbounded reads.
executescript breaking transactions — clear() used executescript which auto-commits, defeating the connection pool's transaction management. Replaced with separate execute() calls.
O(N) eviction loading all metadata — Eviction now uses ORDER BY json_extract(...) LIMIT ? in SQL instead of loading all rows + JSON parsing in Python.
LRU cache memory bloat — Content hash cache now bypasses @lru_cache for files > 64KB, bounding worst-case retention to ~128MB instead of ~20GB.
k=0 / k<0 passing search guards — min(k, MAX) now wrapped with max(1, ...) for both search and similar.
compare_files crash on missing/binary files — Now validates file existence and catches UnicodeDecodeError with clean error messages.
assert used for control flow — Three assert statements in write.py replaced with TypeError raises (assertions are stripped by -O).
Symlink traversal in glob — glob_with_cache_status now skips symlinks that resolve outside the base directory.
SEMANTIC_CACHE_DIR env var not resolved — Now calls .expanduser().resolve() on the override path.
Operator precedence ambiguity — Added explicit parentheses in _summarize.py for or/and expression.
Redundant ORDER BY in find_similar — Removed wasted sort; similarity search already ranks results.
Double chunking pass in put() — Removed chunk counting loop that duplicated work done by storage layer.
Performance
Vectorized hamming distance — hamming_distance_batch now uses np.unpackbits on uint8 view of XOR results instead of Python-level popcount loops. Scalar hamming_distance uses Kernighan's bit-counting algorithm.
Vectorized SimHash bit packing — compute_simhash replaces Python loop with np.uint64 power-of-two dot product. compute_simhash_batch uses pre-allocated matrix instead of np.vstack.
O(N) top-K selection — np.argpartition replaces np.argsort in similarity ranking (2 call sites), reducing top-K from O(N log N) to O(N).
O(N) pruning threshold — np.partition replaces np.percentile for dimension pruning cutoff in cosine similarity.
Buffer protocol blob deserialization — Single b"".join() + np.frombuffer reshape replaces per-row struct.unpack loop in batch cosine similarity.
Pre-allocated matrices — np.empty + fill replaces np.vstack with list comprehension in 3 hot paths (LSH batch, cosine batch ×2).
Changed
Stdout redirect uses contextlib.redirect_stdout — Replaces manual sys.stdout swap for thread-safety and re-entrancy.
Explicit stderr logging handler — logging.StreamHandler(sys.stderr) instead of basicConfig() to guard against third-party reconfiguration.
Type annotations tightened: dict[str, Any] → dict[str, bool | int] in get_hash_stats, -> list → -> list[float] in cosine_similarity_batch, params: list → params: list[str] in find_similar.
README: added uvx vs uv tool install explanation, cross-platform cache paths, SEMANTIC_CACHE_DIR env var.