claude-mem-lite 3.86.0 → 3.87.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.
@@ -10,7 +10,7 @@
10
10
  "plugins": [
11
11
  {
12
12
  "name": "claude-mem-lite",
13
- "version": "3.86.0",
13
+ "version": "3.87.0",
14
14
  "source": "./",
15
15
  "description": "Persistent long-term memory for Claude Code via MCP — captures coding decisions, bugfixes, and context across sessions. Hybrid FTS5 + TF-IDF search with episode batching. Single SQLite DB, no external services. A lighter, lower-cost alternative to claude-mem (episode batching + a smaller model; cost savings are an internal estimate, not a measured benchmark)."
16
16
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-mem-lite",
3
- "version": "3.86.0",
3
+ "version": "3.87.0",
4
4
  "description": "Persistent long-term memory for Claude Code via MCP — captures coding decisions, bugfixes, and context across sessions. Hybrid FTS5 + TF-IDF search with episode batching. Single SQLite DB, no external services. A lighter, lower-cost alternative to claude-mem (episode batching + a smaller model; cost savings are an internal estimate, not a measured benchmark).",
5
5
  "author": {
6
6
  "name": "sdsrss"
package/hook-context.mjs CHANGED
@@ -70,12 +70,54 @@ export function computeAdaptiveWindows(db, project) {
70
70
  // however well it scores.
71
71
  //
72
72
  // Named rather than inline so benchmark/keyctx-pool-replay.mjs can patch a twin and
73
- // price a change to them. Extracting them changed no value.
73
+ // price a change to them. Keep the `export const NAME = <int>;` shape — that ruler
74
+ // patches the DECLARATION by regex and throws when the anchor moves.
74
75
  //
75
- // NOT yet widened: SessionStart injects on every start, so moving these is a
76
- // user-visible default-behaviour change to a released artifact (L3) and gets its own
77
- // round. Measured truncation as of 2026-09-01 is in the replay's header.
78
- export const KEYCTX_POOL_OBS = 50;
76
+ // OBS was 50 through v3.86.0 and is now an OOM backstop, not a relevance gate. What the
77
+ // ruler measured before the change (2026-09-02T06:11Z, 11 projects with >=20 live rows,
78
+ // budget 2000, AGAINST THE 50/10 TREE reproduce with `--population --ref-obs 50
79
+ // --ref-sess 10` and with `--wide-obs 50 --wide-sess 10`, which runs the comparison
80
+ // backwards; the bare command now reports 0/11 because shipped is the wider bound):
81
+ // the 50-row bound truncated the pool in 3 of 11 projects, and lifting it
82
+ // alone moved the injected block in 2 of 11 — 8 rows newly reachable against 2 displaced,
83
+ // for +81 and +16 tokens. Selection here is NOT monotone, so a displaced row is a real
84
+ // cost and the ruler prints it as a first-class number (`--why-displaced` names the rows
85
+ // and the gate that dropped each).
86
+ //
87
+ // Both displaced rows lost their slot to the 3-per-type diversity cap. That is not a
88
+ // three-way discrimination: the token budget does not bind on this corpus (651 of 2000 in
89
+ // the widest arm's largest project) and the file-overlap `continue` below is UNREACHABLE
90
+ // (D#197) — so the cap is currently the only gate that can fire.
91
+ //
92
+ // 200 is ~2x the largest pool observed (107). The ruler CANNOT distinguish 200 from 500
93
+ // on this corpus — every bound >= the largest pool is one arm, identical in both
94
+ // selection and cost — so this value is a headroom choice, not a measured optimum.
95
+ // computeAdaptiveWindows NARROWS the windows as velocity rises (tier3 60d -> 30d -> 14d),
96
+ // so activity counteracts pool growth instead of driving it: the largest pool here is the
97
+ // lowest-velocity high-volume project (1.14 obs/day, 107 rows) while the only project a
98
+ // band up has 2.9x the velocity and 29% of the pool. A draft of this comment had that
99
+ // backwards.
100
+ //
101
+ // Cost is PER PROJECT: ~2.7x where the pool is 107, ~2.0x at 59, ~1.5x at 62, and
102
+ // unchanged (inferred, not measured) for the eight projects whose pool never reached 50.
103
+ // Once per SessionStart, both arms in the low single-digit milliseconds. It is NOT a clean
104
+ // function of pool growth — the 59-row project grows less than the 62-row one and costs
105
+ // more, on two independent harnesses, because fixed per-call work (SQL fetch,
106
+ // estimateTokens, JSON.parse, the unchanged summary half) sets the denominator. Three
107
+ // drafts were wrong here in three ways: a point estimate (2.65x), a global range
108
+ // (2.1x-3.8x) no measurement produced, and a causal claim n=3 refutes. Absolute
109
+ // milliseconds are not quotable. Re-derive with `--cost --wide-obs 50 --wide-sess 10
110
+ // --project <p>`, which prices the widening in the correct direction.
111
+ //
112
+ // SESS stays 10 DELIBERATELY, and the discriminator is `sessDisplaced = 0` in 11 of 11
113
+ // projects, not the observation column. Widening it to 40 displaces no summary at all —
114
+ // it is PURELY ADDITIVE, so that LIMIT is a volume cap and not the D#172 shape, which is
115
+ // the actual reason it does not need lifting. (It also changed zero observations, but
116
+ // that only says the obs side is unaffected.) What widening does buy is 130 newly injected
117
+ // summaries, roughly tripling the emitted block on the largest projects. It truncates MORE
118
+ // projects than the obs bound, 5 of 11 against 3 of 11, which is what made the original
119
+ // review propose it first; truncation count is not harm.
120
+ export const KEYCTX_POOL_OBS = 200;
79
121
  export const KEYCTX_POOL_SESS = 10;
80
122
 
81
123
  /**
@@ -53,10 +53,16 @@ export function injectedIdsFileName(project, sessionId) {
53
53
  * and feeds that single value to BOTH `crossHookInjectedFile(project, sessionId)` and
54
54
  * the events `SELECT ... WHERE project = ?`. So the scoping that matters is the
55
55
  * SESSION's project. The draft instead scoped by the injected observation's own
56
- * `project` column a different question, since the `ups`/`fyi` faces do inject
57
- * cross-project rows — and reported 9 in 9 (15.5%), understating it. The pre-tag claims
56
+ * `project` column and reported 9 in 9 (15.5%), understating it. The pre-tag claims
58
57
  * review caught the population, having reconstructed it independently at 12 in 10.
59
58
  *
59
+ * That is not a rounding difference, and the number that proves it is worth carrying:
60
+ * **134 of 216 injected `ups` ids (62.0%) belong to a project OTHER than the session
61
+ * they were injected into** (2026-09-01T20:36Z; the review measured 128/210 = 61% an
62
+ * hour earlier). The `ups` face has a cross-project leg and it dominates, so "the
63
+ * observation's project" and "the session's project" select genuinely different
64
+ * populations — and only the latter is one the dedup mechanism ever asks about.
65
+ *
60
66
  * The predicate, stated here because no harness is committed for it: seen-set per
61
67
  * session = the shipped `extractInjectedBySurface(path).ups`; injectable events =
62
68
  * `importance >= 2 AND superseded_at_epoch IS NULL AND file_paths NOT IN (NULL,'[]')`;
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "claude-mem-lite",
3
- "version": "3.86.0",
3
+ "version": "3.87.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "claude-mem-lite",
9
- "version": "3.86.0",
9
+ "version": "3.87.0",
10
10
  "dependencies": {
11
11
  "@modelcontextprotocol/sdk": "^1.26.0",
12
12
  "better-sqlite3": "^12.6.2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-mem-lite",
3
- "version": "3.86.0",
3
+ "version": "3.87.0",
4
4
  "description": "Persistent long-term memory for Claude Code via MCP — captures coding decisions, bugfixes, and context across sessions. Hybrid FTS5 + TF-IDF search with episode batching. Single SQLite DB, no external services. A lighter, lower-cost alternative to claude-mem (episode batching + a smaller model; cost savings are an internal estimate, not a measured benchmark).",
5
5
  "type": "module",
6
6
  "packageManager": "npm@10.9.2",