nexusmem 0.8.0 → 0.9.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/CHANGELOG.md +63 -1
- package/README.md +51 -12
- package/dist/cli/index.js +314 -113
- package/dist/cli/index.js.map +1 -1
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,67 @@ built from, matched by publish timestamp: `v0.1.0` → `67a4776`, `v0.1.1` → `
|
|
|
11
11
|
|
|
12
12
|
No unreleased changes yet.
|
|
13
13
|
|
|
14
|
+
## [0.9.1] — 2026-08-29
|
|
15
|
+
|
|
16
|
+
Three ranking/retrieval correctness fixes, found and validated against a new 28-case retrieval-quality
|
|
17
|
+
eval harness (`npm run eval`, dev-only, not part of the published package).
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- `nodes_vec` (vector search) over-fetched `k` globally, then filtered by `project_id` after the join —
|
|
22
|
+
a heuristic, not a guarantee. A sparse project sharing `memory.db` with a much larger one could have
|
|
23
|
+
every true nearest neighbour fall outside the over-fetch window and get silently dropped (reproduced:
|
|
24
|
+
495 rows in one project + 5 in another, global `k=50` surfaced 0 of the 5). Schema V11 gives `nodes_vec`
|
|
25
|
+
a `PARTITION KEY` on `project_id` (`sqlite-vec` 0.1.9+), pushing the equality filter into the k-NN
|
|
26
|
+
search itself so cross-project exactness is now guaranteed, not probable. Migrates existing databases
|
|
27
|
+
automatically on next `sync`/`query`. `--as-of` date filtering still over-fetches — only the
|
|
28
|
+
`project_id` dimension was ever a correctness guarantee.
|
|
29
|
+
- `MAX_PRIOR_OVERTURN` (the cap on how far a recency/signal prior may overturn relevance) raised
|
|
30
|
+
`2 → 2.4`, the highest value that both improves eval MRR (0.924→0.943) and still passes every legacy
|
|
31
|
+
regression test guarding against the original same-day-fix-commits bug this constant exists to bound.
|
|
32
|
+
- A commit's `code_diff` siblings (one node per changed file, all sharing the same `ts`) could crowd a
|
|
33
|
+
packed result and bury that commit's own `git_commit` node — its answer — several ranks down. Now
|
|
34
|
+
capped per commit, matching the existing `conversation_turn`/`doc_section` family cap.
|
|
35
|
+
- `package.json`/`tsconfig.json` diffs were ranking above more relevant results when a changed file's
|
|
36
|
+
path happened to echo its commit's conventional-commit scope (title is weighted 10x body, so the scope
|
|
37
|
+
word counted twice). Down-weighted as mechanical wiring, same reasoning `TEST_PATHS` already applies to
|
|
38
|
+
tests. Only affects nodes ingested from here on — existing manifest/config diffs need `sync --rebuild`
|
|
39
|
+
to get the corrected signal retroactively.
|
|
40
|
+
|
|
41
|
+
## [0.9.0] — 2026-08-27
|
|
42
|
+
|
|
43
|
+
Closes the three remaining mechanisms from a recurring external review (Simon Strandgaard, Agent
|
|
44
|
+
Memory Atlas): trust_state, bi-temporal reads, and a dismiss verb for standing suggestions. Also
|
|
45
|
+
fixes two real Windows-specific correctness bugs found dogfooding.
|
|
46
|
+
|
|
47
|
+
### Added
|
|
48
|
+
|
|
49
|
+
- `nodes.trust_state` (`candidate` | `verified` | `rejected`, schema V10) and `nexusmem review
|
|
50
|
+
<nodeId> --verify|--reject`: a human verdict on a node, independent of the SLM contradiction
|
|
51
|
+
checker. `--reject` down-weights ranking (harsher than the existing supersede penalty, since a
|
|
52
|
+
human said no directly); `--verify` is a label only, no ranking boost. Both render as a tag in
|
|
53
|
+
packed context. Never deletes — same demote-not-delete rule as `mark-stale`.
|
|
54
|
+
- `--as-of <date>` on `nexusmem query` and the MCP `search_memory` tool: restricts both the BM25
|
|
55
|
+
and vector arms to nodes recorded at or before that instant via `created_at` (record time),
|
|
56
|
+
independent of how old the events themselves (`ts`, event time) are. Read-only — there is no
|
|
57
|
+
equivalent write, and nodes stay write-once.
|
|
58
|
+
- `nexusmem stale --dismiss`: silences a contradiction suggestion the user disagrees with, without
|
|
59
|
+
fabricating a `supersedes` relationship. Previously a wrong `--check-contradictions` verdict had
|
|
60
|
+
no way to be rejected — it re-decorated every future `stale`/`sync` run forever.
|
|
61
|
+
- `--prune-source`/`--prune-stale-shell` now record a `mutation_audit` row on their `--yes` path,
|
|
62
|
+
matching what `forget` already did. The dry-run preview stays a pure read.
|
|
63
|
+
|
|
64
|
+
### Fixed
|
|
65
|
+
|
|
66
|
+
- `git rev-parse` failures reported as "error launching git: Access is denied." (Git for Windows'
|
|
67
|
+
launcher shim failing to exec `git.exe` under handle/AV contention) were treated as git's own
|
|
68
|
+
verdict instead of a transient spawn failure, turning a one-off environment hiccup into a hard
|
|
69
|
+
failure. Now retried the same as the other known transient-spawn classes.
|
|
70
|
+
- The PowerShell prompt hook read only `$LASTEXITCODE`, which cmdlets (`Remove-Item`, `Copy-Item`,
|
|
71
|
+
…) never set — every failing cmdlet was silently logged as a success, and a stale
|
|
72
|
+
`$LASTEXITCODE` from an earlier native command could misattribute to later successful cmdlet
|
|
73
|
+
runs. Now reads `$?` alongside `$LASTEXITCODE`, before anything else can overwrite `$?`.
|
|
74
|
+
|
|
14
75
|
## [0.8.0] — 2026-08-22
|
|
15
76
|
|
|
16
77
|
### Added
|
|
@@ -504,7 +565,8 @@ First public release.
|
|
|
504
565
|
there is no local-model summarization pass, and the conversation collector has never been audited
|
|
505
566
|
for the stale-node bug that was found and fixed in the docs collector.
|
|
506
567
|
|
|
507
|
-
[Unreleased]: https://github.com/yaminbkk/NexusMem/compare/v0.
|
|
568
|
+
[Unreleased]: https://github.com/yaminbkk/NexusMem/compare/v0.9.0...HEAD
|
|
569
|
+
[0.9.0]: https://github.com/yaminbkk/NexusMem/compare/v0.8.0...v0.9.0
|
|
508
570
|
[0.8.0]: https://github.com/yaminbkk/NexusMem/compare/v0.7.0...v0.8.0
|
|
509
571
|
[0.7.0]: https://github.com/yaminbkk/NexusMem/compare/v0.6.0...v0.7.0
|
|
510
572
|
[0.6.0]: https://github.com/yaminbkk/NexusMem/compare/v0.5.4...v0.6.0
|
package/README.md
CHANGED
|
@@ -248,7 +248,9 @@ One thing that is not a percentage: shell commands and conversation turns have n
|
|
|
248
248
|
equivalent. Without something recording them, they are gone, not merely more expensive to find.
|
|
249
249
|
|
|
250
250
|
For how these numbers compare to a similar tool's own claims, see
|
|
251
|
-
[`docs/competitor-comparison.md`](docs/competitor-comparison.md).
|
|
251
|
+
[`docs/competitor-comparison.md`](docs/competitor-comparison.md) (vs. projectmem) and
|
|
252
|
+
[`docs/competitor-comparison-yesmem.md`](docs/competitor-comparison-yesmem.md) (vs. YesMem, including
|
|
253
|
+
native Windows support vs. its documented WSL2 requirement).
|
|
252
254
|
|
|
253
255
|
Latency on a ~530-node corpus, warm, p50 over 10 runs:
|
|
254
256
|
|
|
@@ -316,6 +318,21 @@ candidate against nodes *found by embedding similarity*; a contradiction from an
|
|
|
316
318
|
node would never surface. Comprehensive contradiction detection (not just for the pair the vector
|
|
317
319
|
search happens to surface) is still an open problem, and nothing here supersedes a node on its own.
|
|
318
320
|
|
|
321
|
+
`provenance` is a separate question from `trust_state`: provenance says where a claim came from,
|
|
322
|
+
never whether anyone checked it.
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
nexusmem review <nodeId> --verify
|
|
326
|
+
nexusmem review <nodeId> --reject
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Records your own verdict on one node, independent of the SLM contradiction checker above (which only
|
|
330
|
+
ever writes a suggestion, never a verdict). `--reject` down-weights the node in ranking — same
|
|
331
|
+
demote-not-delete rule as `mark-stale`, it stays queryable, just usually loses to better matches —
|
|
332
|
+
and both verdicts are shown as a `[verified]`/`[rejected]` tag on every query result that returns the
|
|
333
|
+
node afterward. `--verify` is a label only; it does not boost ranking. Every node starts `candidate`
|
|
334
|
+
(untagged) until reviewed, and a re-sync never overwrites a verdict once one is set.
|
|
335
|
+
|
|
319
336
|
## Where it breaks
|
|
320
337
|
|
|
321
338
|
- **Shell history without the hook is unscoped.** Scraped history has no directory context, so it is
|
|
@@ -381,16 +398,20 @@ search happens to surface) is still an open problem, and nothing here supersedes
|
|
|
381
398
|
|
|
382
399
|
## Commands
|
|
383
400
|
|
|
384
|
-
`init`, `sync`, `query <text
|
|
385
|
-
somewhere), `projects`, `mcp`, `forget <value>`,
|
|
386
|
-
content check, see above), `mark-stale
|
|
387
|
-
`
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
`
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
401
|
+
`init`, `sync`, `query <text>` (add `--as-of <date>` for a bi-temporal read, see below), `status` (add
|
|
402
|
+
`--share` for a plain-text summary worth pasting somewhere), `projects`, `mcp`, `forget <value>`,
|
|
403
|
+
`stale` (add `--check-contradictions` for a local-SLM content check, see above), `mark-stale
|
|
404
|
+
<nodeId> --supersedes <newNodeId>`, `review <nodeId> --verify|--reject` (record a human verdict on
|
|
405
|
+
one node, see above), `precheck` (advisory — warns about staged files with an unresolved past
|
|
406
|
+
failure or high recent churn; exits 0 unless `--strict`), `hook install|remove|status` (the
|
|
407
|
+
PowerShell exit-code hook), and `hook git install|remove|status` (a git pre-commit hook that runs
|
|
408
|
+
`precheck` before each commit).
|
|
409
|
+
|
|
410
|
+
There are also seven dry-run previews (`scan-git`, `scan-diff`, `scan-shell`, `scan-docs`,
|
|
411
|
+
`scan-conversation`, `scan-session`, `scan-structure`) that write nothing and print what ingestion
|
|
412
|
+
*would* produce — nodes and their signal scores for the first six, import-graph edges for
|
|
413
|
+
`scan-structure`. That is the intended way to tune scoring against a real repository before
|
|
414
|
+
committing to a change. Add `--json` to pipe them somewhere.
|
|
394
415
|
|
|
395
416
|
Every command takes `-C <path>` to target another repository. On `sync`, `--conversation` opts the
|
|
396
417
|
transcript source in for one run without persisting it, `--no-embed` skips the vector pass,
|
|
@@ -423,6 +444,24 @@ scope 2 project(s): NexusMem, uploader
|
|
|
423
444
|
- 2026-08-09 [observed] [NexusMem] fix(git): retry a transient failure to spawn git
|
|
424
445
|
```
|
|
425
446
|
|
|
447
|
+
## Bi-temporal reads
|
|
448
|
+
|
|
449
|
+
Every node carries two clocks: `ts`, the event's own time ("what happened then"), and `created_at`,
|
|
450
|
+
the moment the store actually recorded it ("what did the store hold then") — normally the same
|
|
451
|
+
question, but not when a sync runs late, a backfill lands weeks after the events it describes, or a
|
|
452
|
+
teammate's clone catches up all at once. `query`/`search_memory` answer the first by default;
|
|
453
|
+
`--as-of <date>` switches to the second:
|
|
454
|
+
|
|
455
|
+
```bash
|
|
456
|
+
nexusmem query "why does the ranker cap joint priors" --as-of 2026-08-10
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
Only nodes recorded at or before that instant are considered, even if the events they describe are
|
|
460
|
+
older still. There is no equivalent write — this is a read-time filter over `created_at`, not a
|
|
461
|
+
snapshot or a way to query a value that has since changed, since nodes are write-once (see
|
|
462
|
+
[Staleness & provenance](#staleness--provenance) for what changes a node's *weight*, not its
|
|
463
|
+
record).
|
|
464
|
+
|
|
426
465
|
Databases stay per-repository — there is no shared global store, and deleting one repo's
|
|
427
466
|
`.nexusmem/` still removes exactly that repo's memory. What makes the others findable is a plain
|
|
428
467
|
index at `~/.nexusmem/projects.json`, written by `init` and refreshed by every `sync`. `nexusmem
|
|
@@ -458,7 +497,7 @@ Deleting `.nexusmem/` loses nothing that `sync` cannot rebuild.
|
|
|
458
497
|
|
|
459
498
|
## Status
|
|
460
499
|
|
|
461
|
-
Ingestion, hybrid retrieval, budgeted packing and the MCP server all work and are covered by
|
|
500
|
+
Ingestion, hybrid retrieval, budgeted packing and the MCP server all work and are covered by 701
|
|
462
501
|
tests running on Linux and Windows across Node 22 and 24.
|
|
463
502
|
|
|
464
503
|
## Development
|