superlocalmemory 3.4.59 → 3.4.60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,39 @@ All notable changes to SuperLocalMemory V3 will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [3.4.60] - 2026-05-31 — Daemon OpenMP Crash Hotfix
9
+
10
+ **Hotfix for v3.4.59.** Forces `OMP_NUM_THREADS=1` and `KMP_DUPLICATE_LIB_OK=TRUE`
11
+ in the daemon subprocess environment BEFORE Python imports any C extensions that
12
+ bundle their own libomp.dylib (torch, scikit-learn, lightgbm).
13
+
14
+ ### Root Cause
15
+ Setting these env vars in `superlocalmemory/__init__.py` (v3.4.58 fix) was too
16
+ late on Apple Silicon (M5 Pro). By the time `import superlocalmemory` runs, the
17
+ parent process has often already loaded one of the OpenMP-using extensions, and
18
+ that libomp's thread pool is initialized. When lightgbm later forks its worker
19
+ pool from `LGBM_DatasetCreateFromMat`, the parent's libomp thread structs are
20
+ incompatible with lightgbm's libomp → SIGSEGV at
21
+ `__kmp_suspend_initialize_thread` reading address `0x580`.
22
+
23
+ ### Fix
24
+ `cli/daemon.py:_start_daemon_subprocess()` now copies `os.environ`, sets
25
+ `OMP_NUM_THREADS=1` + `KMP_DUPLICATE_LIB_OK=TRUE`, and passes it via the
26
+ `env=` kwarg to `subprocess.Popen`. The daemon Python interpreter starts
27
+ with these vars already in its environment, so C extension imports see the
28
+ correct values during their `_init` constructors.
29
+
30
+ ### Why 1 thread and not 2
31
+ v3.4.58 set `OMP_NUM_THREADS=2` as a compromise. On M5 Pro the parallel-fork
32
+ race still triggered at 2. SLM's actual ML workloads (ranker retrain, dedup)
33
+ operate on datasets of 50–5,000 rows where 1-thread serial OpenMP is within
34
+ ~10% of multi-threaded but eliminates the crash class entirely.
35
+
36
+ ### Changed
37
+ - `cli/daemon.py`: `_start_daemon_subprocess()` injects `env={OMP_NUM_THREADS=1, KMP_DUPLICATE_LIB_OK=TRUE}` into Popen
38
+
39
+ ---
40
+
8
41
  ## [3.4.59] - 2026-05-31 — Graph Edge Cap + Recall Reliability
9
42
 
10
43
  **Fixes SLM falling into degraded FTS5 mode on every session start**, and stops
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "superlocalmemory",
3
- "version": "3.4.59",
3
+ "version": "3.4.60",
4
4
  "description": "Information-geometric agent memory with mathematical guarantees. 4-channel retrieval, Fisher-Rao similarity, zero-LLM mode, EU AI Act compliant. Works with Claude, Cursor, Windsurf, and 17+ AI tools.",
5
5
  "keywords": [
6
6
  "ai-memory",
@@ -88,4 +88,4 @@
88
88
  "dependencies": {
89
89
  "docx": "^9.5.1"
90
90
  }
91
- }
91
+ }
package/pyproject.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "superlocalmemory"
3
- version = "3.4.59"
3
+ version = "3.4.60"
4
4
  description = "Information-geometric agent memory with mathematical guarantees"
5
5
  readme = "README.md"
6
6
  license = {text = "AGPL-3.0-or-later"}
@@ -28,7 +28,7 @@ if "OMP_NUM_THREADS" not in os.environ:
28
28
  os.environ["OMP_NUM_THREADS"] = "2"
29
29
  # ---------------------------------------------------------------------------
30
30
 
31
- __version__ = "3.4.59"
31
+ __version__ = "3.4.60"
32
32
 
33
33
  _REQUIRED_VERSIONS = {
34
34
  "sentence_transformers": "5.3.0",
@@ -171,6 +171,17 @@ def _start_daemon_subprocess() -> bool:
171
171
  else:
172
172
  kwargs["start_new_session"] = True
173
173
 
174
+ # v3.4.60: Force OMP_NUM_THREADS=1 in daemon env BEFORE Python imports
175
+ # numpy/torch/lightgbm. Setting it in __init__.py is too late on M5 Pro —
176
+ # by the time superlocalmemory.__init__ runs, libomp has already been
177
+ # initialized by an earlier import, causing the SIGSEGV at
178
+ # __kmp_suspend_initialize_thread when lightgbm forks its worker pool.
179
+ # Forcing serial OpenMP eliminates the parallel barrier race entirely.
180
+ daemon_env = os.environ.copy()
181
+ daemon_env["OMP_NUM_THREADS"] = "1"
182
+ daemon_env["KMP_DUPLICATE_LIB_OK"] = "TRUE"
183
+ kwargs["env"] = daemon_env
184
+
174
185
  with open(log_file, "a") as lf:
175
186
  proc = subprocess.Popen(cmd, stdout=lf, stderr=lf, **kwargs)
176
187
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: superlocalmemory
3
- Version: 3.4.59
3
+ Version: 3.4.60
4
4
  Summary: Information-geometric agent memory with mathematical guarantees
5
5
  Author-email: Varun Pratap Bhardwaj <admin@superlocalmemory.com>
6
6
  License: AGPL-3.0-or-later