recallnest 1.4.1 → 2.2.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/.dockerignore +11 -0
- package/CLAUDE.md +7 -3
- package/Dockerfile +20 -0
- package/README.md +202 -130
- package/README_CN.md +263 -190
- package/ROADMAP.md +128 -81
- package/SKILL.md +250 -0
- package/assets/dashboard.png +0 -0
- package/assets/knowledge-graph.png +0 -0
- package/assets/screenshots/ui-full.png +0 -0
- package/assets/screenshots/ui-overview.png +0 -0
- package/assets/screenshots/ui-search.png +0 -0
- package/assets/ui/app.js +227 -3
- package/assets/ui/index.html +81 -11
- package/assets/ui/styles.css +178 -2
- package/bin/recallnest.mjs +62 -0
- package/bun.lock +337 -0
- package/daily-recall.sh +23 -0
- package/daily-reflections/2026-04-02.md +35 -0
- package/daily-reflections/2026-04-03.md +37 -0
- package/daily-reflections/2026-04-04.md +37 -0
- package/daily-reflections/2026-04-05.md +35 -0
- package/daily-reflections/2026-04-06.md +36 -0
- package/daily-reflections/2026-04-07.md +35 -0
- package/daily-reflections/2026-04-08.md +35 -0
- package/daily-reflections/2026-04-12.md +35 -0
- package/data/alias-map.example.json +22 -0
- package/docs/plans/2026-04-01-recall-boost.md +100 -0
- package/docs/superpowers/plans/2026-04-11-constructive-retrieval-emotion.md +1195 -0
- package/docs/superpowers/specs/2026-04-11-constructive-retrieval-emotion-design.md +398 -0
- package/glama.json +6 -0
- package/integrations/setup-all.sh +31 -0
- package/package.json +10 -3
- package/plan-philosophy-upgrades.md +363 -0
- package/plan-product-upgrades.md +155 -0
- package/plan.md +140 -0
- package/research-memory-evolution.md +440 -0
- package/research-rl-agent-memory.md +330 -0
- package/scripts/backfill-anchors.ts +130 -0
- package/scripts/diagnose-vector-search.ts +132 -0
- package/scripts/migrate-language.ts +75 -0
- package/scripts/verify-emotion-decay.ts +148 -0
- package/src/__tests__/activity-counter.test.ts +96 -0
- package/src/__tests__/admission-control.test.ts +206 -0
- package/src/__tests__/anchor-generator.test.ts +67 -0
- package/src/__tests__/babel-integration.test.ts +139 -0
- package/src/__tests__/capture-engine.test.ts +5 -3
- package/src/__tests__/cascade-forget.test.ts +1 -1
- package/src/__tests__/cc8-cc1-essential-context.test.ts +298 -0
- package/src/__tests__/circuit-breaker.test.ts +99 -0
- package/src/__tests__/cluster-consolidation.test.ts +712 -0
- package/src/__tests__/confidence-metadata.test.ts +125 -0
- package/src/__tests__/confidence-tracker.test.ts +53 -0
- package/src/__tests__/consolidation-engine.test.ts +1 -1
- package/src/__tests__/constructive-retrieval.test.ts +509 -0
- package/src/__tests__/context-collapse-renderer.test.ts +214 -0
- package/src/__tests__/context-reconstructor.test.ts +65 -0
- package/src/__tests__/conversation-importer.test.ts +692 -0
- package/src/__tests__/data-checkup.test.ts +225 -0
- package/src/__tests__/decay-exemption.test.ts +84 -0
- package/src/__tests__/dedup-guard.test.ts +39 -0
- package/src/__tests__/distill-lock.test.ts +176 -0
- package/src/__tests__/dream-pipeline.test.ts +232 -0
- package/src/__tests__/emotion-decay.test.ts +46 -0
- package/src/__tests__/emotion-detector.test.ts +56 -0
- package/src/__tests__/emotion-phase1-integration.test.ts +153 -0
- package/src/__tests__/emotion-retrieval.test.ts +56 -0
- package/src/__tests__/ethics-layer.test.ts +476 -0
- package/src/__tests__/feature-flags-integration.test.ts +54 -0
- package/src/__tests__/frequency-tracker.test.ts +113 -0
- package/src/__tests__/graph-export.test.ts +489 -0
- package/src/__tests__/interference-detector.test.ts +203 -0
- package/src/__tests__/mcp-efficiency.test.ts +288 -0
- package/src/__tests__/memory-evolution-b2-b3-e1.test.ts +243 -0
- package/src/__tests__/memory-evolution.test.ts +271 -0
- package/src/__tests__/memory-lint.test.ts +271 -0
- package/src/__tests__/narrative-architecture.test.ts +456 -0
- package/src/__tests__/pending-review.test.ts +77 -0
- package/src/__tests__/post-retrieval-filter.test.ts +178 -0
- package/src/__tests__/prediction-engine.test.ts +349 -0
- package/src/__tests__/predictive-prospective-memory.test.ts +416 -0
- package/src/__tests__/preference-slots.test.ts +99 -0
- package/src/__tests__/query-expander-alias.test.ts +89 -0
- package/src/__tests__/recall-governor.test.ts +227 -0
- package/src/__tests__/resume-context.test.ts +156 -1
- package/src/__tests__/salience-scoring.test.ts +106 -0
- package/src/__tests__/session-distiller.test.ts +611 -0
- package/src/__tests__/skill-engine.test.ts +546 -0
- package/src/__tests__/skill-promotion.test.ts +349 -0
- package/src/__tests__/supersede-chain.test.ts +154 -0
- package/src/__tests__/temporal-validity.test.ts +160 -0
- package/src/__tests__/topic-tag.test.ts +113 -0
- package/src/__tests__/trusted-memory.test.ts +828 -0
- package/src/__tests__/write-verifier.test.ts +122 -0
- package/src/access-tracker.ts +3 -2
- package/src/activity-counter.ts +109 -0
- package/src/adaptive-retrieval.ts +6 -5
- package/src/admission-control.ts +163 -0
- package/src/anchor-generator.ts +80 -0
- package/src/api-server.ts +10 -0
- package/src/audit-log.ts +122 -0
- package/src/auto-gc.ts +98 -29
- package/src/auto-recall.ts +33 -4
- package/src/capture-engine.ts +372 -23
- package/src/cascade-forget.ts +3 -2
- package/src/cli.ts +107 -5
- package/src/compat.ts +22 -0
- package/src/confidence-tracker.ts +210 -47
- package/src/conflict-store.ts +12 -3
- package/src/consolidation-engine.ts +296 -8
- package/src/context-collapse-renderer.ts +222 -0
- package/src/context-composer-stable-selection.ts +5 -1
- package/src/context-composer.ts +239 -4
- package/src/context-reconstructor.ts +404 -0
- package/src/conversation-importer.ts +441 -0
- package/src/data-checkup.ts +232 -0
- package/src/decay-engine.ts +84 -0
- package/src/distill-lock.ts +122 -0
- package/src/doctor.ts +8 -10
- package/src/dream-pipeline.ts +227 -0
- package/src/emotion-detector.ts +90 -0
- package/src/eval.ts +3 -2
- package/src/forget-engine.ts +269 -0
- package/src/frequency-tracker.ts +175 -0
- package/src/graph-export.ts +644 -0
- package/src/ingest.ts +36 -6
- package/src/interference-detector.ts +187 -0
- package/src/kg-extractor.ts +15 -24
- package/src/kg-store.ts +2 -1
- package/src/language-hook.ts +67 -0
- package/src/llm-client.ts +289 -6
- package/src/mcp-server.ts +707 -80
- package/src/memory-assets.ts +22 -5
- package/src/memory-evolution.ts +365 -0
- package/src/memory-lint.ts +429 -0
- package/src/memory-output.ts +69 -0
- package/src/memory-schema.ts +74 -2
- package/src/narrative-schema.ts +79 -0
- package/src/narrative-tagger.ts +164 -0
- package/src/pii-detector.ts +98 -0
- package/src/post-retrieval-filter.ts +76 -0
- package/src/prediction-engine.ts +253 -0
- package/src/preference-slots.ts +65 -2
- package/src/prospective-memory.ts +215 -0
- package/src/query-expander.ts +67 -0
- package/src/recall-governor.ts +183 -0
- package/src/retention-policy.ts +90 -0
- package/src/retriever.ts +828 -55
- package/src/rif.ts +34 -8
- package/src/runtime-config.ts +23 -8
- package/src/scope-inventory.ts +4 -3
- package/src/scope-policy.ts +4 -0
- package/src/session-distiller.ts +307 -0
- package/src/session-output.ts +40 -0
- package/src/session-schema.ts +37 -0
- package/src/session-store.ts +7 -2
- package/src/skill-engine.ts +208 -0
- package/src/skill-promotion.ts +293 -0
- package/src/skill-schema.ts +39 -0
- package/src/store.ts +96 -10
- package/src/topic-tag.ts +66 -0
- package/src/tracker.ts +3 -1
- package/src/ui-server.ts +80 -8
- package/src/workflow-observation-scope-review.ts +2 -1
- package/src/workflow-observation-store.ts +2 -1
- package/src/write-verifier.ts +126 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* F1: Memory Confidence Meta-tags — tests for structured confidence,
|
|
3
|
+
* source-based assignment, retrieval integration, and backward compat.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, test } from "bun:test";
|
|
7
|
+
import {
|
|
8
|
+
assignDefaultConfidence,
|
|
9
|
+
getConfidence,
|
|
10
|
+
getConfidenceMetadata,
|
|
11
|
+
CONFIDENCE_DEFAULT,
|
|
12
|
+
type ConfidenceMetadata,
|
|
13
|
+
} from "../confidence-tracker.js";
|
|
14
|
+
import type { MemoryEntry } from "../store.js";
|
|
15
|
+
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Helper
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
function makeEntry(metadataObj: Record<string, unknown>): MemoryEntry {
|
|
21
|
+
return {
|
|
22
|
+
id: "test-001",
|
|
23
|
+
text: "test",
|
|
24
|
+
vector: [],
|
|
25
|
+
category: "events",
|
|
26
|
+
scope: "test",
|
|
27
|
+
importance: 0.7,
|
|
28
|
+
timestamp: Date.now(),
|
|
29
|
+
metadata: JSON.stringify(metadataObj),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
// assignDefaultConfidence
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
|
|
37
|
+
describe("F1: assignDefaultConfidence", () => {
|
|
38
|
+
test("manual source → direct reliability, score 0.9", () => {
|
|
39
|
+
const c = assignDefaultConfidence("manual");
|
|
40
|
+
expect(c.score).toBe(0.9);
|
|
41
|
+
expect(c.reliability).toBe("direct");
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test("agent source → inferred reliability, score 0.7", () => {
|
|
45
|
+
const c = assignDefaultConfidence("agent");
|
|
46
|
+
expect(c.score).toBe(0.7);
|
|
47
|
+
expect(c.reliability).toBe("inferred");
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test("conversation_import source → hearsay, score 0.5", () => {
|
|
51
|
+
const c = assignDefaultConfidence("conversation_import");
|
|
52
|
+
expect(c.score).toBe(0.5);
|
|
53
|
+
expect(c.reliability).toBe("hearsay");
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test("session_distill source → inferred, score 0.6", () => {
|
|
57
|
+
const c = assignDefaultConfidence("session_distill");
|
|
58
|
+
expect(c.score).toBe(0.6);
|
|
59
|
+
expect(c.reliability).toBe("inferred");
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("explicit override takes precedence", () => {
|
|
63
|
+
const c = assignDefaultConfidence("agent", { score: 0.95, reliability: "direct" });
|
|
64
|
+
expect(c.score).toBe(0.95);
|
|
65
|
+
expect(c.reliability).toBe("direct");
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test("explicit score only, reliability defaults to inferred", () => {
|
|
69
|
+
const c = assignDefaultConfidence("manual", { score: 0.3 });
|
|
70
|
+
expect(c.score).toBe(0.3);
|
|
71
|
+
expect(c.reliability).toBe("inferred");
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// getConfidence — backward compat
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
|
|
79
|
+
describe("F1: getConfidence backward compatibility", () => {
|
|
80
|
+
test("reads flat number confidence (legacy format)", () => {
|
|
81
|
+
const entry = makeEntry({ confidence: 0.42 });
|
|
82
|
+
expect(getConfidence(entry)).toBe(0.42);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test("reads structured confidence object", () => {
|
|
86
|
+
const entry = makeEntry({ confidence: { score: 0.88, reliability: "direct" } });
|
|
87
|
+
expect(getConfidence(entry)).toBe(0.88);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test("returns default when confidence missing", () => {
|
|
91
|
+
const entry = makeEntry({});
|
|
92
|
+
expect(getConfidence(entry)).toBe(CONFIDENCE_DEFAULT);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
// getConfidenceMetadata
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
|
|
100
|
+
describe("F1: getConfidenceMetadata", () => {
|
|
101
|
+
test("extracts structured ConfidenceMetadata", () => {
|
|
102
|
+
const entry = makeEntry({
|
|
103
|
+
confidence: { score: 0.75, reliability: "hearsay", verifiedAt: 1000, verifiedBy: "user" },
|
|
104
|
+
});
|
|
105
|
+
const meta = getConfidenceMetadata(entry);
|
|
106
|
+
expect(meta).not.toBeNull();
|
|
107
|
+
expect(meta!.score).toBe(0.75);
|
|
108
|
+
expect(meta!.reliability).toBe("hearsay");
|
|
109
|
+
expect(meta!.verifiedAt).toBe(1000);
|
|
110
|
+
expect(meta!.verifiedBy).toBe("user");
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
test("wraps legacy flat number into ConfidenceMetadata", () => {
|
|
114
|
+
const entry = makeEntry({ confidence: 0.55 });
|
|
115
|
+
const meta = getConfidenceMetadata(entry);
|
|
116
|
+
expect(meta).not.toBeNull();
|
|
117
|
+
expect(meta!.score).toBe(0.55);
|
|
118
|
+
expect(meta!.reliability).toBe("inferred");
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test("returns null when confidence missing", () => {
|
|
122
|
+
const entry = makeEntry({});
|
|
123
|
+
expect(getConfidenceMetadata(entry)).toBeNull();
|
|
124
|
+
});
|
|
125
|
+
});
|
|
@@ -4,6 +4,9 @@ import {
|
|
|
4
4
|
confirmMemory,
|
|
5
5
|
correctMemory,
|
|
6
6
|
contradictMemory,
|
|
7
|
+
buildConfirmPatch,
|
|
8
|
+
buildCorrectPatch,
|
|
9
|
+
buildContradictPatch,
|
|
7
10
|
getConfidence,
|
|
8
11
|
applyConfidenceWeight,
|
|
9
12
|
CONFIDENCE_DEFAULT,
|
|
@@ -178,6 +181,56 @@ describe("confidence-tracker", () => {
|
|
|
178
181
|
});
|
|
179
182
|
});
|
|
180
183
|
|
|
184
|
+
describe("patch builders (store-agnostic)", () => {
|
|
185
|
+
it("buildConfirmPatch returns metadata patch without touching store", () => {
|
|
186
|
+
const entry = makeEntry("e1", "test fact");
|
|
187
|
+
const patch = buildConfirmPatch(entry);
|
|
188
|
+
expect(patch).not.toBeNull();
|
|
189
|
+
expect(patch!.metadata.confidence).toBe(CONFIDENCE_CONFIRMED);
|
|
190
|
+
expect(patch!.update.entryId).toBe("e1");
|
|
191
|
+
expect(patch!.update.newConfidence).toBe(CONFIDENCE_CONFIRMED);
|
|
192
|
+
// Original entry metadata should NOT be mutated
|
|
193
|
+
expect(JSON.parse(entry.metadata!).confidence).toBeUndefined();
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it("buildCorrectPatch includes correctedBy in history", () => {
|
|
197
|
+
const entry = makeEntry("e1", "old info");
|
|
198
|
+
const patch = buildCorrectPatch(entry, "new-id-123");
|
|
199
|
+
expect(patch).not.toBeNull();
|
|
200
|
+
expect(patch!.metadata.confidence).toBe(CONFIDENCE_CORRECTED);
|
|
201
|
+
expect(patch!.metadata.corrected_by).toBe("new-id-123");
|
|
202
|
+
const history = patch!.metadata.confidence_history as Array<{ correctedBy?: string }>;
|
|
203
|
+
expect(history[0].correctedBy).toBe("new-id-1"); // 8 chars
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it("buildContradictPatch returns zero confidence", () => {
|
|
207
|
+
const entry = makeEntry("e1", "wrong");
|
|
208
|
+
const patch = buildContradictPatch(entry);
|
|
209
|
+
expect(patch!.metadata.confidence).toBe(CONFIDENCE_CONTRADICTED);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it("all patch builders return null for null entry", () => {
|
|
213
|
+
expect(buildConfirmPatch(null)).toBeNull();
|
|
214
|
+
expect(buildCorrectPatch(null)).toBeNull();
|
|
215
|
+
expect(buildContradictPatch(null)).toBeNull();
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it("caps confidence history at 20 entries", () => {
|
|
219
|
+
const longHistory = Array.from({ length: 25 }, (_, i) => ({
|
|
220
|
+
action: "confirmed",
|
|
221
|
+
from: 0.5,
|
|
222
|
+
to: 1.0,
|
|
223
|
+
date: `2026-01-${String(i + 1).padStart(2, "0")}`,
|
|
224
|
+
}));
|
|
225
|
+
const entry = makeEntry("e1", "test", {
|
|
226
|
+
metadata: JSON.stringify({ confidence: 0.5, confidence_history: longHistory }),
|
|
227
|
+
});
|
|
228
|
+
const patch = buildConfirmPatch(entry);
|
|
229
|
+
const history = patch!.metadata.confidence_history as unknown[];
|
|
230
|
+
expect(history.length).toBeLessThanOrEqual(20);
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
|
|
181
234
|
describe("confidence history", () => {
|
|
182
235
|
it("accumulates multiple changes", async () => {
|
|
183
236
|
const entry = makeEntry("e1", "evolving fact");
|
|
@@ -152,7 +152,7 @@ describe("ConsolidationEngine", () => {
|
|
|
152
152
|
|
|
153
153
|
it("skips archived entries", async () => {
|
|
154
154
|
const entryA = makeEntry({ id: "a", text: "active entry here", vector: [1, 0, 0] });
|
|
155
|
-
const entryB = makeEntry({ id: "b", text: "archived entry here", vector: [0.95, 0.1, 0], metadata: JSON.stringify({
|
|
155
|
+
const entryB = makeEntry({ id: "b", text: "archived entry here", vector: [0.95, 0.1, 0], metadata: JSON.stringify({ evolution: { status: "archived" } }) });
|
|
156
156
|
|
|
157
157
|
const { store } = createMockStore([entryA, entryB]);
|
|
158
158
|
const engine = new ConsolidationEngine(store);
|