@soulcraft/cor 3.0.0-rc.1 → 3.0.1

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/README.md CHANGED
@@ -1,328 +1,211 @@
1
- # @soulcraft/cor
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/soulcraftlabs/brainy/main/brainy.png" alt="Cor" width="180">
3
+ </p>
4
+
5
+ <h1 align="center">Cor</h1>
2
6
 
3
7
  <p align="center">
4
- <img src="https://raw.githubusercontent.com/soulcraftlabs/brainy/main/brainy.png" alt="Soulcraft" width="180">
8
+ <b>One engine. Any scale. Your hardware.</b><br>
9
+ The native accelerator for <a href="https://www.npmjs.com/package/@soulcraft/brainy">@soulcraft/brainy</a> — billion-entity vector + graph + metadata<br>
10
+ search on a single machine, with zero code changes and zero configuration.
5
11
  </p>
6
12
 
7
13
  <p align="center">
8
- <a href="https://www.npmjs.com/package/@soulcraft/cor"><img src="https://badge.fury.io/js/%40soulcraft%2Fcor.svg" alt="npm version"></a>
14
+ <a href="https://www.npmjs.com/package/@soulcraft/cor"><img src="https://img.shields.io/npm/v/@soulcraft/cor.svg" alt="npm version"></a>
9
15
  <a href="https://www.npmjs.com/package/@soulcraft/cor"><img src="https://img.shields.io/npm/dm/@soulcraft/cor.svg" alt="npm downloads"></a>
16
+ <a href="https://soulcraft.com/docs"><img src="https://img.shields.io/badge/docs-soulcraft.com-blue.svg" alt="Documentation"></a>
10
17
  <a href="https://soulcraft.com/pricing?focus=cor"><img src="https://img.shields.io/badge/license-commercial-blue.svg" alt="Commercial License"></a>
11
18
  <a href="https://www.typescriptlang.org/"><img src="https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg" alt="TypeScript"></a>
12
19
  </p>
13
20
 
14
21
  <p align="center">
15
- <strong>Native Rust acceleration for <a href="https://www.npmjs.com/package/@soulcraft/brainy">@soulcraft/brainy</a>.</strong>
16
- </p>
17
-
18
- <p align="center">
19
- Adaptive DiskANN to 1 B+ vectors · Triple-intelligence find() (metadata ∩ graph ∩ vector) · Time-travel reads (<code>db.asOf(g)</code>) · Sub-millisecond vector search at 1 M · 13–18× pgvector index latency on the reference host
22
+ <a href="#quick-start">Quick start</a> ·
23
+ <a href="#exact-filters-inside-the-vector-walk">Filter pushdown</a> ·
24
+ <a href="#feature-tour">Features</a> ·
25
+ <a href="#one-box-hundreds-of-brains--or-one-brain-at-billion-scale">Scale</a> ·
26
+ <a href="#measured-not-promised">Benchmarks</a> ·
27
+ <a href="#learn-more">Docs</a>
20
28
  </p>
21
29
 
22
- ```bash
23
- bun add @soulcraft/cor # or: npm install @soulcraft/cor
24
- ```
25
-
26
- **[soulcraft.com/docs](https://soulcraft.com/docs)** · **[Pricing](https://soulcraft.com/pricing?focus=cor)** · **[Benchmarks](https://github.com/soulcraftlabs/cor/blob/main/docs/performance.md)** · **[Comparison](https://github.com/soulcraftlabs/cor/blob/main/docs/comparison.md)**
27
-
28
30
  ---
29
31
 
30
- Brainy handles your knowledge graph. Cor makes it fast and scales it from one workspace to a billion vectors on a single machine.
31
-
32
- When performance matters — at scale, in production, with large embedding models — Cor automatically swaps in compiled Rust implementations for distance calculations, vector index, metadata filtering, graph adjacency, and embeddings. No code changes. No configuration changes. Add the package and it activates.
33
-
34
- **New in cor 3.0** *(measured numbers on bxl9000 — Ryzen 9 7950X3D / 184 GB / NVMe; reproducible from `scripts/verify-*.mjs`)*:
32
+ [Brainy](https://github.com/soulcraftlabs/brainy) is the open-source knowledge database — vectors, relationships, metadata, and full-text in one MIT-licensed engine. Cor swaps compiled Rust in under every hot path. **No code changes. No configuration.** Install it and brainy (≥ 8.0.9) auto-detects it loudly: activation prints `Providers: 10/10 native`, a missing license warns by name, and a broken install makes `init()` throw rather than quietly run slow. **Remove it and everything keeps working** on the same files, at open-source speed. That's the contract in both directions.
35
33
 
36
- - **Triple-intelligence find()** Combines metadata filter + graph hop + vector similarity in a single query. **Substrate-composition p50 ≈ 0.230 ms at 1 M** (per-stage measured; this run is on a synthetic corpus, so end-to-end latency **and** recall are being re-validated on real-manifold data (SIFT) — see [docs/comparison.md](docs/comparison.md) honesty note).
37
- - **Adaptive DiskANN** — 100 % pure-Rust Vamana + PQ. Auto-engages on local storage. **MEASURED: p50 0.85 ms at 1 M** (`mode=auto`).
38
- - **Time-travel reads** (`db.asOf(g)` / `db.with(...)`)Pin a generation, read the brain as it existed at that moment. All three shadow-page substrates (UUID↔int + verb endpoints) participate in the pin lifecycle.
39
- - **Competitive position: 13–18× pgvector index latency** (p50, reference host bxl9000), sub-millisecond p99 at 1 M. Latency, not a blanket "faster" the recall-matched, real-data library A/B is in progress. See **[docs/comparison.md](https://github.com/soulcraftlabs/cor/blob/main/docs/comparison.md)** for methodology + honesty notes.
34
+ | Brainy runs it as | Cor replaces it with | You get |
35
+ |---|---|---|
36
+ | HNSW vector index (in-RAM) | **Adaptive DiskANN** mmap-native, self-tuning, streaming segments | billion-scale ANN on one box; recall@10 **0.96 at 100M** (measured) |
37
+ | `find()` composed in JS | one fused native query: metadata graph vector | exact filters **inside** the vector walk, not after it |
38
+ | JSON field index | LSM postings + columnar sort/aggregate, mmap-durable | cold open serves instantly — restart = warm (measured) |
39
+ | graph adjacency in JS maps | u64 LSM adjacency + native traversal/analytics | whole-graph reads as single cursor walks |
40
+ | JS distance loops | SIMD kernels (f32, SQ8, SQ4-packed) | the hot inner loop in vector search, compiled |
41
+ | WASM embedding model | Candle ML runtime, in-process | batch on-box embeddings — no API fees, no data egress |
42
+ | time-travel reads in JS | generation-pinned reads across all three substrates | `asOf()` at native speed |
40
43
 
41
- Architecture: **[docs/diskann.md](https://github.com/soulcraftlabs/cor/blob/main/docs/diskann.md)** · Time-travel contract: **[docs/snapshot-safety.md](https://github.com/soulcraftlabs/cor/blob/main/docs/snapshot-safety.md)** · Performance budget: **[docs/performance-budget.md](https://github.com/soulcraftlabs/cor/blob/main/docs/performance-budget.md)** · Full verification: **[docs/verification-report.md](https://github.com/soulcraftlabs/cor/blob/main/docs/verification-report.md)** · **Upgrading from 2.x?** **[docs/migration-3.0.md](https://github.com/soulcraftlabs/cor/blob/main/docs/migration-3.0.md)**
42
-
43
- ---
44
-
45
- ## Quick Start
44
+ ## Quick start
46
45
 
47
46
  ```bash
48
- bun add @soulcraft/brainy @soulcraft/cor
47
+ npm install @soulcraft/cor # or: bun add @soulcraft/cor
49
48
  ```
50
49
 
51
50
  ```typescript
52
- import { Brainy, NounType } from '@soulcraft/brainy'
53
-
54
- const brain = new Brainy({
55
- storage: { type: 'filesystem', rootDirectory: './data' },
56
- plugins: ['@soulcraft/cor']
57
- })
58
- await brain.init()
59
- // [brainy] Plugin activated: @soulcraft/cor
60
- // All native providers registered — same API, Rust speed.
61
-
62
- await brain.add({ data: 'Native Rust SIMD acceleration', type: NounType.Concept })
63
- const results = await brain.find({ query: 'fast vector search' })
64
- ```
51
+ import { Brainy, NounType, VerbType } from '@soulcraft/brainy'
65
52
 
66
- ### Activate your license
53
+ const brain = new Brainy({ storage: { type: 'filesystem', path: './data' } })
54
+ await brain.init() // cor auto-detected (brainy ≥ 8.0.9) — look for "Providers: 10/10 native"
67
55
 
68
- Free tier activates automatically — no key needed. For Pro/Enterprise:
69
-
70
- 1. Get your activation code from [soulcraft.com/account](https://soulcraft.com/account)
71
- 2. Run in your project directory:
56
+ const cor = await brain.add({
57
+ data: 'Cor swaps compiled Rust in under every Brainy hot path',
58
+ type: NounType.Concept,
59
+ subtype: 'library',
60
+ metadata: { layer: 'native', year: 2026 },
61
+ })
62
+ const brainy = await brain.add({
63
+ data: 'Brainy is the open-source knowledge database',
64
+ type: NounType.Concept,
65
+ subtype: 'library',
66
+ metadata: { layer: 'engine', year: 2026 },
67
+ })
68
+ await brain.relate({ from: cor, to: brainy, type: VerbType.DependsOn, subtype: 'runtime' })
72
69
 
73
- ```bash
74
- npx @soulcraft/cor activate CX-XXXX-XXXX
70
+ const hits = await brain.find({
71
+ query: 'native acceleration', // vector — what it means
72
+ where: { layer: 'native' }, // metadata — pushed INTO the walk
73
+ connected: { to: brainy }, // graph — what it touches
74
+ }) // one call, three indexes, fused
75
75
  ```
76
76
 
77
- This creates a `.soulcraft.json` in your project — commit it to your repository and it works everywhere (dev, staging, prod, Docker, CI).
77
+ **Activate** (paid tiers; free = just use brainy):
78
78
 
79
- **Other CLI commands:**
80
79
  ```bash
81
- npx cor status # show license info
82
- npx cor deactivate # remove license
83
- npx cor help # all commands
80
+ npx @soulcraft/cor login # browser sign-in, like `gh auth login`
81
+ # or, for servers / CI: export COR_LICENSE_KEY=sc_cor_...
84
82
  ```
85
83
 
86
- License validation runs **locally in Rust** — no network calls at startup. Get a key at **[soulcraft.com/pricing](https://soulcraft.com/pricing?focus=cor)**.
87
-
88
- ---
89
-
90
- ## What Gets Accelerated
91
-
92
- Every provider listed here is a drop-in replacement — Brainy's plugin system wires them in automatically based on your license tier.
93
-
94
- | Subsystem | What Cor Provides |
95
- |-----------|---------------------|
96
- | **Adaptive DiskANN** | 100% pure-Rust Vamana α-pruned graph + Product Quantization. Single-machine billion-vector ANN search; MEASURED p50 0.85 ms at 1 M on bxl9000. Auto-engages on local-storage installs |
97
- | **Triple-intelligence find()** | Composes metadata filter + graph hop + vector ANN in one query. Substrate-composition p50 ≈ 0.230 ms at 1 M (per-stage measured on synthetic; end-to-end SIFT re-validation in progress) |
98
- | **Time-travel reads** | `db.asOf(g)` / `db.with(...)` — pin a generation, read the brain as it existed at that moment. All 3 substrates participate in the pin lifecycle |
99
- | **SIMD distance** | Float32 cosine; SQ8 uint8 cosine (81× faster); SQ4 nibble-packed |
100
- | **Embeddings** | Candle ML runtime — in-process, no Python sidecar, no HTTP roundtrip. CPU and Apple Metal |
101
- | **Batch embeddings** | Single Rust forward pass for bulk import and reindex |
102
- | **Metadata index** | Rust LSM-tree query/mutation engine with CRoaring bitmap posting lists. MEASURED 525 K inserts/sec at 100 M |
103
- | **Graph adjacency** | 4 LSM-trees + verb-endpoints shadow-page store with typed verb tracking |
104
- | **Entity ID mapper** | Mmap'd UUID ↔ u64 with shadow-page snapshot safety; supports 2 B+ entities |
105
- | **Vector quantization** | SQ8 (4× memory), SQ4 (8× memory), Product Quantization (16–32×) |
106
- | **Graph compression** | Delta-varint encoded connection lists |
107
- | **Roaring bitmaps** | CRoaring bindings — binary-compatible with `roaring-wasm` |
108
- | **Msgpack** | Native encode/decode |
109
- | **mmap storage** | Zero-copy SSTable reads via memory-mapped files; shadow-page LSM for snapshot safety |
110
- | **Aggregation engine** | Incremental updates with Rayon parallel rebuild |
111
- | **Compaction** | Pin-aware (respects `min_pinned_generation` for time-travel) + graph-aware BFS ordering for disk locality |
112
-
113
- ### Scale envelope at a glance
114
-
115
- > **MEASURED at 1 M / 10 M / 100 M on bxl9000.** Source files cited in
116
- > `docs/verification-report.md`. 1 B numbers are projected from SIFT1B
117
- > trends + 100 M measured + Subramanya et al. (NeurIPS 2019) algorithm
118
- > latency model.
119
-
120
- | Vectors | RAM | DiskANN p50 | LSM filter p50 | Graph 2-hop p50 | **Composed find() p50** | Source |
121
- |--------:|---:|---:|---:|---:|---:|:---|
122
- | 1 M | 0.5–2 GB | **0.85 ms** | **23.8 µs** | **14.3 µs** | **0.230 ms** | bxl9000, measured |
123
- | 10 M | 1–5 GB | _running_ | **537 µs** | _running_ | _projected_ | bxl9000, partial |
124
- | 100 M | 5–20 GB | _projected_ | **5.85 ms** | _projected_ | _projected_ | bxl9000, LSM only |
125
- | **1 B** | **20–70 GB** | **5–10 ms** (PROJECTED) | _projected_ | _projected_ | _projected_ | SIFT1B reference |
126
-
127
- All numbers are for the search engine itself. End-to-end query latency adds entity hydration; see **[docs/scaling.md](https://github.com/soulcraftlabs/cor/blob/main/docs/scaling.md#operational-ceiling-at-1-b)** for the honest full-stack story.
128
-
129
- **Running many brains per box (per-tenant pools, e.g. one brain per user)?** Cor auto-raises its own soft open-file limit on startup and warns you (with the exact fix) if the OS file/mmap limits would bottleneck a pool before RAM. The hard `ulimit -n` + Linux `vm.max_map_count` must be set by your deployment — copy-paste Docker / Compose / Kubernetes / host config in **[docs/deployment-limits.md](https://github.com/soulcraftlabs/cor/blob/main/docs/deployment-limits.md)**.
130
-
131
- ---
132
-
133
- ## Performance
134
-
135
- All numbers **measured** with `vitest bench` on Linux x64.
136
-
137
- ### Distance Calculations — 384-dimensional vectors (all-MiniLM-L6-v2)
84
+ Keys verify **offline** in Rust — no network call at startup, no license server to run.
138
85
 
139
- | Operation | Throughput | Latency | vs full-precision |
140
- |-----------|----------:|--------:|:-----------------:|
141
- | `cosineDistance` (float32) | 45,965 ops/s | 21.8 μs | baseline |
142
- | `cosineDistanceSq8` (quantized) | 3,715,855 ops/s | 0.27 μs | **81×** |
143
- | `cosineDistanceSq8Batch` (1K vectors) | 2,142 ops/s | 467 μs | **28×** |
144
- | `cosineDistanceBatch` (float32, 1K) | 77 ops/s | 13.0 ms | — |
145
- | `quantizeSq8` (encode 384-dim) | 74,020 ops/s | 13.5 μs | — |
86
+ ## Exact filters inside the vector walk
146
87
 
147
- **Quantize once at index time. Get 81× faster distances at every query.**
88
+ Pure vector databases post-filter — search first, discard non-matches — so selective filters return too few or lower-recall results. Cor computes the exact matching set first (roaring-bitmap intersection), searches only that provably-correct space, and switches to an exact scan when the set is small (recall 1.0).
148
89
 
149
- ### Aggregation Engine
150
-
151
- | Operation | Throughput | Latency |
152
- |-----------|----------:|--------:|
153
- | `incrementalUpdate` (1K entities, 3 metrics) | 809 ops/s | 1.2 ms |
154
- | `rebuildAggregate` (10K entities, 5 groups) | 475 ops/s | 2.1 ms |
155
- | `rebuildAggregate` (100K entities, Rayon) | 66 ops/s | 15.2 ms |
156
- | `queryAggregate` (1K groups, sort + paginate) | 986 ops/s | 1.0 ms |
157
-
158
- ### Serialization
159
-
160
- | Operation | Throughput | Latency |
161
- |-----------|----------:|--------:|
162
- | `msgpackEncode` (1K entities) | 235 ops/s | 4.3 ms |
163
- | `msgpackDecode` (1K entities) | 355 ops/s | 2.8 ms |
164
- | `RoaringBitmap32.serialize` (10K elements) | 361,258 ops/s | 2.8 μs |
165
- | `RoaringBitmap32.deserialize` (10K elements) | 548,714 ops/s | 1.8 μs |
166
- | `encodeConnections` (1K lists) | 913 ops/s | 1.1 ms |
167
- | `decodeConnections` (1K lists) | 1,078 ops/s | 928 μs |
168
-
169
- Full breakdown: **[docs/performance.md](https://github.com/soulcraftlabs/cor/blob/main/docs/performance.md)** · Side-by-side comparison: **[docs/comparison.md](https://github.com/soulcraftlabs/cor/blob/main/docs/comparison.md)**
170
-
171
- ---
90
+ ```typescript
91
+ await brain.find({
92
+ query: 'quarterly revenue anomalies',
93
+ where: { region: 'EMEA', year: 2026 }, // resolved to an exact bitmap FIRST
94
+ })
95
+ // the vector walk only ever visits entities that already match
96
+ // selective filters get MORE accurate, not less
97
+ ```
172
98
 
173
- ## Free Tier vs Pro
174
-
175
- | Feature | Free | Pro / Enterprise |
176
- |---------|:----:|:----------------:|
177
- | mmap-enhanced filesystem storage | ✓ | ✓ |
178
- | **Adaptive DiskANN billion-scale index** | — | ✓ |
179
- | **Triple-intelligence find() composition** | — | ✓ |
180
- | **Time-travel reads (`db.asOf(g)`)** | — | ✓ |
181
- | SIMD distance (float32, SQ8, SQ4) | — | ✓ |
182
- | Vector quantization (SQ8, SQ4, PQ) | — | ✓ |
183
- | Candle ML embeddings (CPU / Metal) | — | ✓ |
184
- | Native metadata index (LSM + CRoaring) | — | ✓ |
185
- | Graph adjacency index (4 LSM-trees + verb endpoints) | — | ✓ |
186
- | Entity ID mapper (mmap UUID ↔ u64) | — | ✓ |
187
- | Snapshot-safe shadow-page LSM stores | — | ✓ |
188
- | CRoaring bitmap bindings | — | ✓ |
189
- | Native msgpack encode/decode | — | ✓ |
190
- | Incremental aggregation engine | — | ✓ |
191
- | Pin-aware + graph-aware compaction | — | ✓ |
192
-
193
- Free tier activates automatically with no key. Pro/Enterprise require a license key — see [soulcraft.com/pricing](https://soulcraft.com/pricing?focus=cor).
99
+ *Cor pushes the exact filter into the vector search; everyone else filters after.*
194
100
 
195
- ---
101
+ ## Feature tour
196
102
 
197
- ## Verify Activation
103
+ ### Adaptive DiskANN — it tunes itself to your machine
198
104
 
199
- Check which providers are active after `brain.init()`:
105
+ A 100% pure-Rust implementation of the DiskANN algorithm (Microsoft Research, NeurIPS 2019: Vamana graphs + product quantization + an mmap-native format). Zero knobs, by design:
200
106
 
201
107
  ```typescript
202
- const diag = brain.diagnostics()
203
- console.log(diag.providers)
204
- // {
205
- // distance: { source: 'plugin' },
206
- // vectorIndex: { source: 'plugin' }, // Adaptive DiskANN
207
- // embeddings: { source: 'plugin' },
208
- // metadataIndex: { source: 'plugin' },
209
- // graphIndex: { source: 'plugin' },
210
- // ...
211
- // }
108
+ const brain = new Brainy({ storage: { type: 'filesystem', path: './data' } })
109
+ await brain.init()
110
+ // that's the entire configuration — on every machine, at every scale
212
111
  ```
213
112
 
214
- Require specific providers in productionfail fast if something isn't native:
113
+ It observes available RAM and picks in-memory / compressed / on-disk operation, widens its search with corpus size, shares the box fairly with sibling instances, and grows its id space to ~51B entities. Same binary, same files from a laptop to a 128 GB server, it simply uses what it finds.
215
114
 
216
- ```typescript
217
- brain.requireProviders(['distance', 'vectorIndex', 'embeddings', 'metadataIndex', 'graphIndex'])
218
- ```
115
+ **[How Adaptive DiskANN works](docs/diskann.md)** · **[ADR-002: why 100% Rust](docs/ADR-002-diskann-100-percent-rust.md)**
219
116
 
220
- ---
117
+ ### Streaming inserts that never freeze
221
118
 
222
- ## License & Subscription
119
+ Writes absorb instantly and flush to small immutable segments in **O(new-data)** — seconds at any corpus size, not hours of reindexing. Index maintenance runs off-thread; consolidation is rare, background, and **never blocks a read or a write**.
223
120
 
224
- Cor uses a **subscription license** with offline validation. Your key is an Ed25519-signed JWT verified entirely in Rust at process start — no network call required. A background heartbeat runs once every 24 hours to check subscription status.
121
+ ```typescript
122
+ // keep writing at any corpus size — reads stay live throughout
123
+ for (const doc of firehose) await brain.add(doc)
124
+ await brain.find({ query: 'still answering' }) // never waits on a rebuild
125
+ ```
225
126
 
226
- ### Graceful Degradation
127
+ A brain that grows fast never hits a rebuild wall.
227
128
 
228
- Cor **never hard-blocks** your process on a lapsed license. If your subscription lapses:
129
+ ### Time travel
229
130
 
230
- 1. A warning appears on the next process start
231
- 2. A **14-day grace period** begins
232
- 3. After the grace period, Cor silently degrades to free tier — storage keeps working, compute acceleration pauses
131
+ Point-in-time queries across vectors, graph, and metadata together — plus speculative transactions. No other vector database ships this.
233
132
 
234
- ```
235
- [cor] Subscription canceled. Renew at soulcraft.com/account. Grace period: 12 days remaining.
133
+ ```typescript
134
+ const lastWeek = await brain.asOf(Date.now() - 7 * 86_400_000)
135
+ await lastWeek.find({ query: 'what did we know then?' }) // full query surface, past state
236
136
  ```
237
137
 
238
- Renew at any time during the grace period to restore compute acceleration instantly on the next startup.
138
+ **[ADR-003: semantic time travel](docs/ADR-003-semantic-time-travel.md)**
239
139
 
240
- ### Key Source
140
+ ### Cold start = warm
241
141
 
242
- Cor reads `.soulcraft.json` from the project root (`process.cwd()`):
142
+ Every index is mmap-durable — the files *are* the state. A restart serves identical results from the first query, with no rebuild and no warm-up phase (measured: cold-reopen recall matches warm exactly).
243
143
 
244
- ```json
245
- { "cor": "CX-7F3A-9B2D" }
246
- ```
144
+ **[Snapshot safety](docs/snapshot-safety.md)**
247
145
 
248
- On first use, short codes are exchanged for a JWT via `soulcraft.com/api/license/exchange` and cached in memory for the process lifetime. The file itself is never rewritten — each cold start re-exchanges if needed.
146
+ ### Local embeddings, embedded engine
249
147
 
250
- Run `npx @soulcraft/cor activate CX-XXXX-XXXX` to create this file.
148
+ An on-box ML runtime (Candle) — no per-document API fees, no data egress, fully offline-capable. And the whole thing is a library, not a database server: nothing to deploy, monitor, or operate.
251
149
 
252
- ---
150
+ ### Automatic upgrades
253
151
 
254
- ## Platform Support
152
+ Opening an older-format brain triggers a coordinated, observable migration: progress reporting, an automatic pre-upgrade backup, and a guarantee it never serves half-built state or loses a write.
255
153
 
256
- Pre-built binaries ship inside the npm package. No compile step needed.
154
+ **[Upgrading from 2.x / brainy 7.x](docs/migration-3.0.md)**
257
155
 
258
- | Platform | Architecture | Binary Included |
259
- |----------|-------------|:---------------:|
260
- | Linux | x64 (glibc 2.17+) | ✓ |
261
- | Linux | arm64 (glibc) | ✓ |
262
- | macOS | arm64 (Apple Silicon) | ✓ |
263
- | macOS | x64 (Intel) | ✓ |
264
- | Windows | x64 | ✓ |
156
+ ## One box, hundreds of brains or one brain at billion scale
265
157
 
266
- > **GPU / CUDA acceleration** is available for Enterprise customers. [Contact us](https://soulcraft.com/contact-sales) to discuss your requirements.
158
+ The same zero-config design serves both extremes. **Per-user isolation:** run one brain per user or customer — each a physically separate database (own files, own indexes; no shared store, no cross-tenant query surface to secure). Every brain sizes itself from *observed RAM ÷ active brains*, a resource manager rebalances budgets at runtime, and mmap paging means idle tenants cost almost nothing — hundreds of isolated brains fit one commodity box. **Or scale one up:** the identical engine takes a single brain to billions of entities on that same box. No sharding tier, no "multi-tenant edition" — one design, both shapes.
267
159
 
268
- ---
160
+ **[Scaling: sizing, tenants, limits](docs/scaling.md)**
269
161
 
270
- ## Troubleshooting
162
+ ## Measured, not promised
271
163
 
272
- | Symptom | Likely cause | Fix |
273
- |---------|-------------|-----|
274
- | `[cor] missing sc_cor_ prefix` | `.soulcraft.json` contains wrong key or non-cor key | Re-run `npx @soulcraft/cor activate CX-XXXX-XXXX` |
275
- | `[cor] license expired` | Key is past its expiry date | Renew at [soulcraft.com/account](https://soulcraft.com/account) |
276
- | `[cor] invalid signature` | Key was truncated or corrupted | Re-activate: `npx @soulcraft/cor activate CX-XXXX-XXXX` |
277
- | `[cor] invalid product: workshop` | Workshop key used for Cor | Keys are product-specific — get a Cor key at [soulcraft.com/account](https://soulcraft.com/account) |
278
- | `[cor] native module unavailable` | Native binary not found for current platform | Check platform table above |
279
- | Compute providers inactive, no warning | No key set — free tier is active | Run `npx @soulcraft/cor activate CX-XXXX-XXXX` |
280
- | `[cor] License lapsed. Compute acceleration disabled.` | Grace period expired | Renew at [soulcraft.com/account](https://soulcraft.com/account) |
281
- | `[cor] License suspended. Contact support.` | Account suspended | Open a ticket at [soulcraft.com/issues](https://soulcraft.com/issues) |
164
+ SIFT benchmarks on commodity-class hardware; reproducible via `scripts/verify-*.mjs`; methodology + honesty notes in [docs/comparison.md](docs/comparison.md).
282
165
 
283
- ---
166
+ | Scale | Recall@10 | Median latency |
167
+ |---|---|---|
168
+ | 1M | **0.9942** | 0.31 ms |
169
+ | 10M | **0.9647** | 1.33 ms |
170
+ | 100M | **0.9559** | ~7 ms — one box, at the published DiskANN billion-scale operating point |
171
+ | 1B | in validation | measured run in progress; labeled projected until it lands |
284
172
 
285
- ## Direct Native Access
173
+ Cold-reopen recall matches warm exactly (measured). The write path holds flat RSS from 100k → 1M entities (measured). Billion-scale claims stay labeled until the 1B run completes — that's the house rule.
286
174
 
287
- For advanced use cases custom pipelines, tooling, benchmarks — access the Rust bindings directly without Brainy:
175
+ ## Built for teams that can't send data anywhere
288
176
 
289
- ```typescript
290
- import { loadNativeModule, isNativeAvailable } from '@soulcraft/cor'
177
+ Everything runs on your hardware, in your process: search, storage, **and embedding generation** (the on-box ML runtime means documents never leave the machine, even to be vectorized). Air-gapped deployments work — license keys verify offline, and the daily license ping (key id, machine fingerprint, size bucket; never data) degrades gracefully when there's no route out. Point-in-time queries give you an audit dimension most databases can't: *what did the system know, and when?*
291
178
 
292
- if (isNativeAvailable()) {
293
- const native = loadNativeModule()
294
- const dist = native.cosineDistance(vectorA, vectorB)
295
- const encoded = native.msgpackEncode(data)
296
- }
297
- ```
179
+ ## Licensing that never breaks your app
298
180
 
299
- ---
181
+ Start free on brainy. When you outgrow it, `npm install @soulcraft/cor` — nothing else changes. And in the other direction: no key — or an expired one, or no network — means cor quietly steps aside and you're running open-source brainy on the same files. **There is no kill switch, and we will never build one.** Pricing follows the size of your brain, not seats or nodes: free under 1M entities (that's brainy), then simple tiers as you grow. Once a day cor reports its key id, a machine fingerprint, and a coarse size bucket — never data, queries, or content. See [soulcraft.com/pricing](https://soulcraft.com/pricing?focus=cor).
300
182
 
301
183
  ## Requirements
302
184
 
303
- - **Bun 1.0+** (recommended) or **Node.js 22 LTS**
304
- - `@soulcraft/brainy >= 7.15.4`
185
+ - Node.js ≥ 22 (Bun 1.1 as a runtime) · TypeScript-native, ESM
186
+ - `@soulcraft/brainy` 8.0 · local filesystem storage (mmap requires real files)
187
+ - 32 GB RAM serves ~1B entities; 64 GB recommended — see [docs/scaling.md](docs/scaling.md)
305
188
 
306
- ```bash
307
- bun add @soulcraft/brainy @soulcraft/cor # Bun — best performance
308
- npm install @soulcraft/brainy @soulcraft/cor # Node.js — fully supported
309
- ```
189
+ ## Learn more
310
190
 
311
- ---
191
+ | Topic | Doc |
192
+ |---|---|
193
+ | How Adaptive DiskANN works | [docs/diskann.md](docs/diskann.md) · [ADR-002: why 100% Rust](docs/ADR-002-diskann-100-percent-rust.md) |
194
+ | Benchmarks + methodology | [docs/performance.md](docs/performance.md) · [docs/comparison.md](docs/comparison.md) · [docs/verification-report.md](docs/verification-report.md) |
195
+ | Scaling: sizing, tenants, limits | [docs/scaling.md](docs/scaling.md) · [docs/billion-scale.md](docs/billion-scale.md) · [docs/deployment-limits.md](docs/deployment-limits.md) |
196
+ | Durability + snapshots | [docs/snapshot-safety.md](docs/snapshot-safety.md) |
197
+ | Time travel | [ADR-003: semantic time travel](docs/ADR-003-semantic-time-travel.md) |
198
+ | Upgrading from 2.x / brainy 7.x | [docs/migration-3.0.md](docs/migration-3.0.md) |
312
199
 
313
- ## Learn More
200
+ ## The open-core promise
314
201
 
315
- - **[Brainy documentation](https://soulcraft.com/docs)**Full Brainy API reference
316
- - **[Plugin system](https://github.com/soulcraftlabs/brainy/blob/main/docs/PLUGINS.md)** — How Brainy plugins work
317
- - **[Performance benchmarks](https://github.com/soulcraftlabs/cor/blob/main/docs/performance.md)** — Full benchmark table with methodology
318
- - **[Brainy vs Cor comparison](https://github.com/soulcraftlabs/cor/blob/main/docs/comparison.md)** — Side-by-side feature and speed comparison
319
- - **[soulcraft.com/pricing](https://soulcraft.com/pricing?focus=cor)** — Pro and Enterprise plans
202
+ Every accelerated path has a working JavaScript default in brainy (MIT). You upgrade for speed, not capability and you can downgrade at any time with zero migration, because cor works on brainy's files, not its own. Your data is never hostage to a subscription.
320
203
 
321
204
  ---
322
205
 
323
- ## License
324
-
325
- Commercial — [soulcraft.com/pricing](https://soulcraft.com/pricing?focus=cor)
326
-
327
- Free tier (mmap storage) is available without a license key.
328
- Pro and Enterprise tiers require a paid subscription.
206
+ <p align="center">
207
+ <a href="https://soulcraft.com/docs">Documentation</a> ·
208
+ <a href="https://soulcraft.com/pricing?focus=cor">Pricing</a> ·
209
+ <a href="https://github.com/soulcraftlabs/brainy">Brainy (open source)</a> ·
210
+ <a href="https://soulcraft.com/support">Support</a>
211
+ </p>
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@
10
10
  */
11
11
  import { join } from 'node:path';
12
12
  import { readConfig, writeConfig, isShortCode, exchangeShortCode, readLicenseToken } from './license.js';
13
- import { SHORT_CODE_PATTERN, CONFIG_FILE } from './license/constants.js';
13
+ import { SHORT_CODE_PATTERN, CONFIG_FILE, DEVICE_START_URL, DEVICE_TOKEN_URL } from './license/constants.js';
14
14
  const JWT_PREFIX = 'sc_cor_';
15
15
  // Legacy prefix still accepted during the cortex→cor rename transition.
16
16
  const LEGACY_JWT_PREFIX = 'sc_cortex_';
@@ -37,6 +37,83 @@ function resolveLicenseSource(config) {
37
37
  return { source: 'file', value: fileValue };
38
38
  return { source: 'none', value: undefined };
39
39
  }
40
+ /**
41
+ * `cor login` — RFC 8628 device-authorization flow (the `gh auth login` UX):
42
+ * request a device code, show the user code + verification URL, poll until the
43
+ * browser approval lands, write the issued JWT to `.soulcraft.json`. The env
44
+ * var (`COR_LICENSE_KEY`) remains the CI/headless path; `activate <code>`
45
+ * remains the offline fallback.
46
+ */
47
+ async function cmdLogin() {
48
+ let start;
49
+ try {
50
+ const res = await fetch(DEVICE_START_URL, { method: 'POST' });
51
+ if (!res.ok)
52
+ throw new Error(`HTTP ${res.status}`);
53
+ start = await res.json();
54
+ }
55
+ catch (error) {
56
+ console.error('[cor] Could not reach soulcraft.com to start login.');
57
+ console.error(`[cor] (${error instanceof Error ? error.message : String(error)})`);
58
+ console.error('[cor] Offline? Use: npx @soulcraft/cor activate <code-or-key>');
59
+ process.exit(1);
60
+ }
61
+ // RFC 8628 field names, tolerating camelCase servers.
62
+ const deviceCode = start.device_code ?? start.deviceCode;
63
+ const userCode = start.user_code ?? start.userCode;
64
+ const uri = start.verification_uri ?? start.verificationUri ?? 'https://soulcraft.com/activate';
65
+ let intervalS = Number(start.interval ?? 5) || 5;
66
+ const expiresIn = Number(start.expires_in ?? start.expiresIn ?? 900) || 900;
67
+ if (!deviceCode || !userCode) {
68
+ console.error('[cor] Login service returned an unexpected response. Try again, or use `activate <code>`.');
69
+ process.exit(1);
70
+ }
71
+ console.log('');
72
+ console.log(` Open: ${uri}`);
73
+ console.log(` Code: ${userCode}`);
74
+ console.log('');
75
+ console.log(' Waiting for approval in the browser…');
76
+ const deadline = Date.now() + expiresIn * 1000;
77
+ while (Date.now() < deadline) {
78
+ await new Promise((r) => setTimeout(r, intervalS * 1000));
79
+ let body;
80
+ try {
81
+ const res = await fetch(DEVICE_TOKEN_URL, {
82
+ method: 'POST',
83
+ headers: { 'Content-Type': 'application/json' },
84
+ body: JSON.stringify({ device_code: deviceCode }),
85
+ });
86
+ body = await res.json().catch(() => ({}));
87
+ if (res.ok && (body.token ?? body.access_token)) {
88
+ const token = body.token ?? body.access_token;
89
+ const config = await readConfig();
90
+ delete config.cortex; // retire the legacy key on a fresh login
91
+ config.cor = token;
92
+ await writeConfig(config);
93
+ console.log(` ✓ Logged in. License saved to ${CONFIG_FILE} — cor acceleration is active.`);
94
+ return;
95
+ }
96
+ }
97
+ catch {
98
+ continue; // transient network error — keep polling until the deadline
99
+ }
100
+ const err = body?.error;
101
+ if (err === 'authorization_pending')
102
+ continue;
103
+ if (err === 'slow_down') {
104
+ intervalS += 5;
105
+ continue;
106
+ }
107
+ if (err === 'expired_token')
108
+ break;
109
+ if (err === 'access_denied') {
110
+ console.error(' ✗ Login was denied in the browser.');
111
+ process.exit(1);
112
+ }
113
+ }
114
+ console.error(' ✗ Login timed out. Run `npx @soulcraft/cor login` again.');
115
+ process.exit(1);
116
+ }
40
117
  function printHelp() {
41
118
  console.log(`
42
119
  cor — license management for @soulcraft/cor
@@ -45,6 +122,7 @@ USAGE
45
122
  npx @soulcraft/cor <command> [args]
46
123
 
47
124
  COMMANDS
125
+ login Sign in via the browser (device flow) — the easy path
48
126
  activate <code-or-key> Activate with a short code (CO-XXXX-XXXX) or JWT
49
127
  status Show current license status
50
128
  deactivate Remove the cor license key
@@ -213,6 +291,9 @@ async function cmdDeactivate() {
213
291
  }
214
292
  const [, , command, ...args] = process.argv;
215
293
  switch (command) {
294
+ case 'login':
295
+ await cmdLogin();
296
+ break;
216
297
  case 'activate':
217
298
  await cmdActivate(args[0]);
218
299
  break;
@@ -13,6 +13,9 @@ export declare const ONLINE_VALIDATION_TIMEOUT_MS = 10000;
13
13
  export declare const API_URL = "https://soulcraft.com/api/license/validate";
14
14
  /** Short code exchange API URL */
15
15
  export declare const EXCHANGE_URL = "https://soulcraft.com/api/license/exchange";
16
+ /** RFC 8628 device-authorization endpoints (`cor login`). */
17
+ export declare const DEVICE_START_URL = "https://soulcraft.com/api/license/device/start";
18
+ export declare const DEVICE_TOKEN_URL = "https://soulcraft.com/api/license/device/token";
16
19
  /** Pricing URL for license purchase */
17
20
  export declare const PRICING_URL = "https://soulcraft.com/pricing?focus=pro";
18
21
  /**
@@ -13,6 +13,9 @@ export const ONLINE_VALIDATION_TIMEOUT_MS = 10_000;
13
13
  export const API_URL = 'https://soulcraft.com/api/license/validate';
14
14
  /** Short code exchange API URL */
15
15
  export const EXCHANGE_URL = 'https://soulcraft.com/api/license/exchange';
16
+ /** RFC 8628 device-authorization endpoints (`cor login`). */
17
+ export const DEVICE_START_URL = 'https://soulcraft.com/api/license/device/start';
18
+ export const DEVICE_TOKEN_URL = 'https://soulcraft.com/api/license/device/token';
16
19
  /** Pricing URL for license purchase */
17
20
  export const PRICING_URL = 'https://soulcraft.com/pricing?focus=pro';
18
21
  /**
@@ -9,6 +9,16 @@
9
9
  * No signature verification here — that's in Rust.
10
10
  * Default 24h heartbeat interval, 14-day grace period.
11
11
  */
12
+ export declare function setEntityCountSource(source: () => number | undefined): void;
13
+ /** Coarse size bucket for metering — the pricing ladder's rungs. */
14
+ export declare function entityBucketFor(count: number | undefined): string | undefined;
15
+ /**
16
+ * Stable, non-identifying machine fingerprint: a truncated hash of
17
+ * hostname|platform|arch. Lets Portal count concurrent instances per key
18
+ * (the anti-sharing backstop — soft: an email, never a block) without
19
+ * transmitting the hostname itself.
20
+ */
21
+ export declare function machineFingerprint(): string;
12
22
  interface HeartbeatCache {
13
23
  lastCheck: string;
14
24
  nextCheckAt?: string;
@@ -11,7 +11,46 @@
11
11
  */
12
12
  import { readFile, writeFile, mkdir } from 'node:fs/promises';
13
13
  import { join } from 'node:path';
14
+ import { createHash } from 'node:crypto';
15
+ import { hostname, platform, arch } from 'node:os';
14
16
  import { API_URL, CACHE_DIR, HEARTBEAT_FILE, GRACE_PERIOD_DAYS, DEFAULT_CHECK_INTERVAL_MS, ONLINE_VALIDATION_TIMEOUT_MS, } from './constants.js';
17
+ /**
18
+ * Lazy source of the brain's indexed entity count, wired by the plugin
19
+ * (`setEntityCountSource`). The heartbeat reports only a coarse SIZE BUCKET —
20
+ * never data — per the licensing transparency contract ("once a day: key id,
21
+ * machine fingerprint, size bucket"). Undefined (unwired / probe failure)
22
+ * reports no bucket.
23
+ */
24
+ let entityCountSource = null;
25
+ export function setEntityCountSource(source) {
26
+ entityCountSource = source;
27
+ }
28
+ /** Coarse size bucket for metering — the pricing ladder's rungs. */
29
+ export function entityBucketFor(count) {
30
+ if (count === undefined || !Number.isFinite(count) || count < 0)
31
+ return undefined;
32
+ if (count < 1_000_000)
33
+ return '<1M';
34
+ if (count < 10_000_000)
35
+ return '1M-10M';
36
+ if (count < 100_000_000)
37
+ return '10M-100M';
38
+ if (count < 1_000_000_000)
39
+ return '100M-1B';
40
+ return '1B+';
41
+ }
42
+ /**
43
+ * Stable, non-identifying machine fingerprint: a truncated hash of
44
+ * hostname|platform|arch. Lets Portal count concurrent instances per key
45
+ * (the anti-sharing backstop — soft: an email, never a block) without
46
+ * transmitting the hostname itself.
47
+ */
48
+ export function machineFingerprint() {
49
+ return createHash('sha256')
50
+ .update(`${hostname()}|${platform()}|${arch()}`)
51
+ .digest('hex')
52
+ .slice(0, 16);
53
+ }
15
54
  function getDefaultCacheDir() {
16
55
  return join(process.cwd(), CACHE_DIR);
17
56
  }
@@ -98,7 +137,12 @@ async function callApi(token) {
98
137
  const response = await fetch(API_URL, {
99
138
  method: 'POST',
100
139
  headers: { 'Content-Type': 'application/json' },
101
- body: JSON.stringify({ licenseKey: token }),
140
+ body: JSON.stringify({
141
+ licenseKey: token,
142
+ ver: 2,
143
+ sid: machineFingerprint(),
144
+ entityBucket: entityBucketFor(entityCountSource?.()),
145
+ }),
102
146
  signal: controller.signal,
103
147
  });
104
148
  if (!response.ok) {
@@ -4,7 +4,7 @@
4
4
  /** Result of license validation */
5
5
  export interface LicenseResult {
6
6
  valid: boolean;
7
- tier: 'free' | 'pro' | 'enterprise' | 'internal';
7
+ tier: 'free' | 'startup' | 'pro' | 'growth' | 'scale' | 'enterprise' | 'internal';
8
8
  email: string;
9
9
  expiresAt: number;
10
10
  error?: string;
package/dist/license.d.ts CHANGED
@@ -12,7 +12,7 @@
12
12
  */
13
13
  export interface LicenseResult {
14
14
  valid: boolean;
15
- tier: 'free' | 'pro' | 'enterprise' | 'internal';
15
+ tier: 'free' | 'startup' | 'pro' | 'growth' | 'scale' | 'enterprise' | 'internal';
16
16
  email: string;
17
17
  expiresAt: number;
18
18
  error?: string;
package/dist/plugin.js CHANGED
@@ -45,6 +45,8 @@
45
45
  import { loadNativeModule, isNativeAvailable } from './native/index.js';
46
46
  import { validateLicense, readLicenseToken, readConfig, isShortCode } from './license.js';
47
47
  import { MigrationCoordinator } from './migration/MigrationCoordinator.js';
48
+ import { prodLog } from '@soulcraft/brainy/internals';
49
+ import { setEntityCountSource } from './license/onlineValidator.js';
48
50
  const PRICING_URL = 'https://soulcraft.com/pricing?focus=pro';
49
51
  // `brainyRange` engages brainy 8.0's version-coupling gate (handoff LV.3): a
50
52
  // brainy outside this range fails loud at init() instead of silently dropping to
@@ -162,7 +164,10 @@ const corPlugin = {
162
164
  const { readHeartbeatCache, isGracePeriodExpired } = await import('./license/onlineValidator.js');
163
165
  const cachedState = await readHeartbeatCache();
164
166
  if (cachedState?.gracePeriodStart && isGracePeriodExpired(cachedState.gracePeriodStart)) {
165
- console.warn('[cor] License lapsed. Compute acceleration disabled. Renew at soulcraft.com/account');
167
+ // LOUD (prodLog stays on even in silent mode): grace exhausted is the
168
+ // one licensing state an operator must notice — acceleration is now
169
+ // OFF and queries run at open-source speed until the key renews.
170
+ prodLog.error('[cor] License grace period EXPIRED — native acceleration disabled; running at open-source (brainy) speed. Renew at soulcraft.com/account');
166
171
  return true;
167
172
  }
168
173
  }
@@ -354,6 +359,16 @@ const corPlugin = {
354
359
  // ResourceManager runs internally (adaptive cache sizing, wired above) — it is
355
360
  // not registered as a provider since brainy has no consumer for it.
356
361
  resourceManager.startRebalancing();
362
+ // Metering source for the heartbeat: the brain's indexed entity count
363
+ // (O(1) from the vector index), reported as a coarse size bucket only.
364
+ setEntityCountSource(() => {
365
+ try {
366
+ return vectorInstance?.size();
367
+ }
368
+ catch {
369
+ return undefined;
370
+ }
371
+ });
357
372
  // Background heartbeat with forceCheck — always checks Portal on startup.
358
373
  // Updates the cache so the next startup sees current subscription state.
359
374
  // Runs after providers are registered (non-blocking for the user).
@@ -366,7 +381,8 @@ const corPlugin = {
366
381
  .then(result => {
367
382
  if (result.degrade) {
368
383
  const msg = result.warning ?? 'License lapsed. Compute acceleration disabled. Renew at soulcraft.com/account';
369
- console.warn(`[cor] ${msg}`);
384
+ // Loud even in silent mode — see the grace-expiry note above.
385
+ prodLog.error(`[cor] ${msg}`);
370
386
  }
371
387
  else if (result.warning) {
372
388
  console.warn(`[cor] ${result.warning}`);
package/docs/scaling.md CHANGED
@@ -36,6 +36,28 @@ Moving up a tier is `rsync` plus restart at the single-machine side, and adding
36
36
  a routing layer at the horizontal side. The Brainy API doesn't change — your
37
37
  code looks the same whether you're running one instance or 256.
38
38
 
39
+ ## Build time vs serve time — the number that matters is milliseconds
40
+
41
+ A common first worry: "if a billion-vector index takes days to build, will my users wait days?"
42
+ No user ever waits on a build. The two costs are completely different things:
43
+
44
+ | | What it is | How long | Who experiences it |
45
+ |---|---|---|---|
46
+ | **Serving** | answering queries | **milliseconds** (measured: ~1 ms @ 10M, ~7 ms @ 100M) | your users, constantly |
47
+ | **Inserting** | new data becoming searchable | **instant** (bounded buffer + O(new-data) segment flush) | your writers, constantly |
48
+ | **Building** | constructing the optimized graph | minutes at 1M · ~hours at 100M · days at 1B | **nobody waits** — it runs in the background while serving continues |
49
+
50
+ Why building is expensive: a query is *one* walk through the graph; building makes *every*
51
+ vector do that walk to wire itself in — a billion queries' worth of work, performed once.
52
+ This is the DiskANN design working as intended (build once, serve from disk forever), and
53
+ the same physics applies to every vector database at this scale.
54
+
55
+ Why nobody waits: brains grow incrementally — every insert is searchable in seconds via the
56
+ segment tier, and the big consolidation runs off-thread with live progress while reads and
57
+ writes flow uninterrupted. Even a one-time bulk migration of a pre-existing billion-vector
58
+ corpus serves queries the whole time; only *peak* performance arrives when the background
59
+ build completes.
60
+
39
61
  ## Single machine
40
62
 
41
63
  The default unit of deployment is **one Brainy instance** (the data layer —
Binary file
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@soulcraft/cor",
3
- "version": "3.0.0-rc.1",
4
- "description": "Native Rust acceleration for Brainy SIMD distance, vector quantization, zero-copy mmap, native embeddings. Free tier for storage, Pro license for compute acceleration.",
3
+ "version": "3.0.1",
4
+ "description": "Native Rust acceleration for Brainy \u2014 SIMD distance, vector quantization, zero-copy mmap, native embeddings. Free tier for storage, Pro license for compute acceleration.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "type": "module",
@@ -78,11 +78,11 @@
78
78
  "LICENSE"
79
79
  ],
80
80
  "peerDependencies": {
81
- "@soulcraft/brainy": ">=8.0.0-rc.1 <9.0.0"
81
+ "@soulcraft/brainy": ">=8.0.0 <9.0.0"
82
82
  },
83
83
  "devDependencies": {
84
84
  "@napi-rs/cli": "^3.0.0",
85
- "@soulcraft/brainy": "8.0.0-rc.9",
85
+ "@soulcraft/brainy": "8.0.7",
86
86
  "@types/node": "^22.0.0",
87
87
  "pg": "^8.21.0",
88
88
  "tsx": "^4.21.0",