nexusmem 0.5.4 → 0.7.0
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 +59 -1
- package/README.md +33 -11
- package/dist/cli/index.js +575 -25
- package/dist/cli/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,59 @@ built from, matched by publish timestamp: `v0.1.0` → `67a4776`, `v0.1.1` → `
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
No unreleased changes yet.
|
|
13
|
+
|
|
14
|
+
## [0.7.0] — 2026-08-21
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- `nexusmem stale --check-contradictions`: for each stale candidate, finds the most similar newer
|
|
19
|
+
node (local embedding search) and asks a local SLM (Ollama, `qwen2.5:3b` by default) whether it
|
|
20
|
+
actually contradicts the older one, instead of only surfacing by age. Suggest-only — nothing is
|
|
21
|
+
written, same as plain `stale`. Live-dogfooded against this repo's own real database and Ollama
|
|
22
|
+
instance; found and fixed a real gap along the way (below) before the feature surfaced anything
|
|
23
|
+
useful.
|
|
24
|
+
- Import graph: bare Python imports with no leading dot (`import foo`, `from foo import bar`)
|
|
25
|
+
now resolve to a same-directory sibling file too, alongside the existing relative-dot support.
|
|
26
|
+
Found dogfooding two real local projects: neither used a single PEP 328 relative import, both
|
|
27
|
+
relied entirely on this flat-script style. Guarded by a static list of stdlib module names so a
|
|
28
|
+
bare `import os`/`import queue`/etc. is never mistaken for a same-named local file.
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- Import graph: a Java wildcard import (`import a.b.*;`) no longer merges files from two
|
|
33
|
+
unrelated packages that happen to share a directory-name suffix (e.g. two Gradle/Maven modules
|
|
34
|
+
each with their own `.../foo`) — it now refuses to guess, same as the single-class-import case.
|
|
35
|
+
- `stale --check-contradictions`'s neighbor search now looks past same-timestamp sibling nodes
|
|
36
|
+
(e.g. the many chunks one long conversation gets split into) to reach genuinely newer content.
|
|
37
|
+
Found live-dogfooding against this repo's own database: the first real candidate's closest 15
|
|
38
|
+
neighbors were all same-conversation siblings sharing its exact timestamp, so the original
|
|
39
|
+
5-neighbor default silently found zero suggestions for every candidate, regardless of what the
|
|
40
|
+
SLM would have said.
|
|
41
|
+
|
|
42
|
+
## [0.6.0] — 2026-08-20
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
|
|
46
|
+
- Ranker: `inferred` nodes (summaries, doc snapshots) now decay twice as fast as `observed` ones
|
|
47
|
+
(git commits, diffs, shell commands) for retrieval purposes. A judgment call, not a measured
|
|
48
|
+
optimum — see `INFERRED_HALF_LIFE_RATIO` in `src/retrieval/rank.ts`.
|
|
49
|
+
- `nexusmem stale`: lists aging `inferred` nodes nothing has superseded yet, as candidates for
|
|
50
|
+
`mark-stale`. A heuristic on age and provenance, not real contradiction detection — writes nothing.
|
|
51
|
+
- `nexusmem status` now surfaces an `aging` line with the stale-candidate count when any exist.
|
|
52
|
+
- Import graph: Python relative imports (`from .foo import bar`, `from . import x`) now produce
|
|
53
|
+
file edges too, alongside the existing JS/TS support. Absolute Python imports are still skipped —
|
|
54
|
+
same "missed edge over wrong edge" reasoning as JS/TS's bare-specifier skip.
|
|
55
|
+
- Import graph: Go internal imports (resolved against `go.mod`'s module path, one edge per
|
|
56
|
+
non-test file in the imported package) and Rust `mod foo;` declarations (2018+ edition module
|
|
57
|
+
layout) now produce file edges too. External Go imports and Rust `use` paths are out of scope for
|
|
58
|
+
the same reason.
|
|
59
|
+
- Import graph: Java imports (`import a.b.C;` / `import a.b.*;`, resolved by unambiguous suffix
|
|
60
|
+
match against the tracked source tree) and `__DIR__`-anchored PHP `require`/`include` now produce
|
|
61
|
+
file edges too — all six of `nexusmem scan-structure`'s tracked languages. `import static`, PHP's
|
|
62
|
+
autoloaded `use Namespace\Class;`, and any unanchored PHP include are out of scope for the same
|
|
63
|
+
"missed edge over wrong edge" reason as everywhere else in the import graph.
|
|
64
|
+
|
|
12
65
|
## [0.5.4] — 2026-08-20
|
|
13
66
|
|
|
14
67
|
### Added
|
|
@@ -428,7 +481,12 @@ First public release.
|
|
|
428
481
|
there is no local-model summarization pass, and the conversation collector has never been audited
|
|
429
482
|
for the stale-node bug that was found and fixed in the docs collector.
|
|
430
483
|
|
|
431
|
-
[Unreleased]: https://github.com/yaminbkk/NexusMem/compare/v0.
|
|
484
|
+
[Unreleased]: https://github.com/yaminbkk/NexusMem/compare/v0.7.0...HEAD
|
|
485
|
+
[0.7.0]: https://github.com/yaminbkk/NexusMem/compare/v0.6.0...v0.7.0
|
|
486
|
+
[0.6.0]: https://github.com/yaminbkk/NexusMem/compare/v0.5.4...v0.6.0
|
|
487
|
+
[0.5.4]: https://github.com/yaminbkk/NexusMem/compare/v0.5.3...v0.5.4
|
|
488
|
+
[0.5.3]: https://github.com/yaminbkk/NexusMem/compare/v0.5.2...v0.5.3
|
|
489
|
+
[0.5.2]: https://github.com/yaminbkk/NexusMem/compare/v0.5.1...v0.5.2
|
|
432
490
|
[0.5.1]: https://github.com/yaminbkk/NexusMem/compare/v0.5.0...v0.5.1
|
|
433
491
|
[0.5.0]: https://github.com/yaminbkk/NexusMem/compare/v0.4.0...v0.5.0
|
|
434
492
|
[0.4.0]: https://github.com/yaminbkk/NexusMem/compare/v0.3.3...v0.4.0
|
package/README.md
CHANGED
|
@@ -263,16 +263,25 @@ Latency on a ~530-node corpus, warm, p50 over 10 runs:
|
|
|
263
263
|
All the SQLite work totals about 5 ms. The embedding call is the only thing on this path worth
|
|
264
264
|
optimizing, and it is somebody else's process.
|
|
265
265
|
|
|
266
|
-
##
|
|
266
|
+
## Staleness & provenance
|
|
267
267
|
|
|
268
268
|
Two things a memory layer needs and this one only partly has: a way to tell an observed fact from a
|
|
269
|
-
guess, and a way to retire a conclusion once something contradicts it.
|
|
270
|
-
|
|
269
|
+
guess, and a way to retire a conclusion once something contradicts it. This section is what exists
|
|
270
|
+
and what doesn't.
|
|
271
271
|
|
|
272
272
|
Every node carries a `provenance`: `observed` (a commit that landed, a shell command's real exit
|
|
273
273
|
code) or `inferred` (a conversation turn, a session summary, a doc section — all readable as claims
|
|
274
|
-
that could be wrong or go stale). Set once per collector at ingest time,
|
|
275
|
-
|
|
274
|
+
that could be wrong or go stale). Set once per collector at ingest time, shown as a `[observed]` /
|
|
275
|
+
`[inferred]` tag on every query result, and now used to decay retrieval weight too — `inferred` nodes
|
|
276
|
+
fade from ranking twice as fast as `observed` ones as they age.
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
nexusmem stale
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Lists `inferred` nodes old enough (45+ days by default) that nothing has confirmed they still hold —
|
|
283
|
+
a heuristic on age and provenance, not on content. It writes nothing; you decide which candidates are
|
|
284
|
+
actually wrong.
|
|
276
285
|
|
|
277
286
|
```bash
|
|
278
287
|
nexusmem mark-stale <oldNodeId> --supersedes <newNodeId>
|
|
@@ -281,10 +290,22 @@ nexusmem mark-stale <oldNodeId> --supersedes <newNodeId>
|
|
|
281
290
|
Links `newNodeId` as the replacement for `oldNodeId`. The ranker down-weights the old node from then
|
|
282
291
|
on (it stays queryable, just usually loses to its replacement) — nothing is deleted, unlike `forget`.
|
|
283
292
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
293
|
+
```bash
|
|
294
|
+
nexusmem stale --check-contradictions
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
For each candidate, finds the most similar newer node (local embedding search) and asks a local SLM
|
|
298
|
+
(Ollama, `qwen2.5:3b` by default) whether it actually contradicts the older one — real content
|
|
299
|
+
comparison, not just age. A match is printed as `likely superseded by <id> <title> -- <reason>`
|
|
300
|
+
under the candidate; nothing is written, same as plain `stale`. Needs Ollama running; costs one
|
|
301
|
+
embedding call and, when a plausible newer node exists, one chat completion per candidate (capped at
|
|
302
|
+
10 by default — pass `-n` to raise it).
|
|
303
|
+
|
|
304
|
+
**What this doesn't do:** it is one small model's yes/no judgment on one older/newer pair, not a
|
|
305
|
+
verified fact — treat a match as a lead to check, not a conclusion. It also only ever compares a
|
|
306
|
+
candidate against nodes *found by embedding similarity*; a contradiction from an unrelated-sounding
|
|
307
|
+
node would never surface. Real contradiction detection (comprehensively, not just for the pair the
|
|
308
|
+
vector search happens to surface) is still an open problem.
|
|
288
309
|
|
|
289
310
|
## Where it breaks
|
|
290
311
|
|
|
@@ -352,8 +373,9 @@ problem.
|
|
|
352
373
|
## Commands
|
|
353
374
|
|
|
354
375
|
`init`, `sync`, `query <text>`, `status` (add `--share` for a plain-text summary worth pasting
|
|
355
|
-
somewhere), `projects`, `mcp`, `forget <value>`, `
|
|
356
|
-
|
|
376
|
+
somewhere), `projects`, `mcp`, `forget <value>`, `stale` (add `--check-contradictions` for a local-SLM
|
|
377
|
+
content check, see above), `mark-stale <nodeId> --supersedes <newNodeId>`, and
|
|
378
|
+
`hook install|remove|status`.
|
|
357
379
|
|
|
358
380
|
There are also five dry-run previews (`scan-git`, `scan-diff`, `scan-shell`, `scan-docs`,
|
|
359
381
|
`scan-conversation`)
|