stellar-memory 0.5.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.
Files changed (197) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +362 -0
  3. package/dist/api/routes/analytics.d.ts +15 -0
  4. package/dist/api/routes/analytics.js +131 -0
  5. package/dist/api/routes/analytics.js.map +1 -0
  6. package/dist/api/routes/conflicts.d.ts +12 -0
  7. package/dist/api/routes/conflicts.js +67 -0
  8. package/dist/api/routes/conflicts.js.map +1 -0
  9. package/dist/api/routes/consolidation.d.ts +11 -0
  10. package/dist/api/routes/consolidation.js +63 -0
  11. package/dist/api/routes/consolidation.js.map +1 -0
  12. package/dist/api/routes/constellation.d.ts +4 -0
  13. package/dist/api/routes/constellation.js +84 -0
  14. package/dist/api/routes/constellation.js.map +1 -0
  15. package/dist/api/routes/memories.d.ts +4 -0
  16. package/dist/api/routes/memories.js +219 -0
  17. package/dist/api/routes/memories.js.map +1 -0
  18. package/dist/api/routes/observations.d.ts +10 -0
  19. package/dist/api/routes/observations.js +42 -0
  20. package/dist/api/routes/observations.js.map +1 -0
  21. package/dist/api/routes/orbit.d.ts +4 -0
  22. package/dist/api/routes/orbit.js +71 -0
  23. package/dist/api/routes/orbit.js.map +1 -0
  24. package/dist/api/routes/projects.d.ts +15 -0
  25. package/dist/api/routes/projects.js +121 -0
  26. package/dist/api/routes/projects.js.map +1 -0
  27. package/dist/api/routes/scan.d.ts +4 -0
  28. package/dist/api/routes/scan.js +403 -0
  29. package/dist/api/routes/scan.js.map +1 -0
  30. package/dist/api/routes/sun.d.ts +4 -0
  31. package/dist/api/routes/sun.js +43 -0
  32. package/dist/api/routes/sun.js.map +1 -0
  33. package/dist/api/routes/system.d.ts +4 -0
  34. package/dist/api/routes/system.js +70 -0
  35. package/dist/api/routes/system.js.map +1 -0
  36. package/dist/api/routes/temporal.d.ts +13 -0
  37. package/dist/api/routes/temporal.js +82 -0
  38. package/dist/api/routes/temporal.js.map +1 -0
  39. package/dist/api/server.d.ts +2 -0
  40. package/dist/api/server.js +99 -0
  41. package/dist/api/server.js.map +1 -0
  42. package/dist/api/websocket.d.ts +53 -0
  43. package/dist/api/websocket.js +168 -0
  44. package/dist/api/websocket.js.map +1 -0
  45. package/dist/cli/index.d.ts +12 -0
  46. package/dist/cli/index.js +35 -0
  47. package/dist/cli/index.js.map +1 -0
  48. package/dist/cli/init.d.ts +10 -0
  49. package/dist/cli/init.js +163 -0
  50. package/dist/cli/init.js.map +1 -0
  51. package/dist/engine/analytics.d.ts +93 -0
  52. package/dist/engine/analytics.js +437 -0
  53. package/dist/engine/analytics.js.map +1 -0
  54. package/dist/engine/conflict.d.ts +54 -0
  55. package/dist/engine/conflict.js +322 -0
  56. package/dist/engine/conflict.js.map +1 -0
  57. package/dist/engine/consolidation.d.ts +83 -0
  58. package/dist/engine/consolidation.js +368 -0
  59. package/dist/engine/consolidation.js.map +1 -0
  60. package/dist/engine/constellation.d.ts +66 -0
  61. package/dist/engine/constellation.js +382 -0
  62. package/dist/engine/constellation.js.map +1 -0
  63. package/dist/engine/corona.d.ts +53 -0
  64. package/dist/engine/corona.js +181 -0
  65. package/dist/engine/corona.js.map +1 -0
  66. package/dist/engine/embedding.d.ts +44 -0
  67. package/dist/engine/embedding.js +168 -0
  68. package/dist/engine/embedding.js.map +1 -0
  69. package/dist/engine/gravity.d.ts +63 -0
  70. package/dist/engine/gravity.js +121 -0
  71. package/dist/engine/gravity.js.map +1 -0
  72. package/dist/engine/multiproject.d.ts +75 -0
  73. package/dist/engine/multiproject.js +241 -0
  74. package/dist/engine/multiproject.js.map +1 -0
  75. package/dist/engine/observation.d.ts +82 -0
  76. package/dist/engine/observation.js +357 -0
  77. package/dist/engine/observation.js.map +1 -0
  78. package/dist/engine/orbit.d.ts +91 -0
  79. package/dist/engine/orbit.js +249 -0
  80. package/dist/engine/orbit.js.map +1 -0
  81. package/dist/engine/planet.d.ts +64 -0
  82. package/dist/engine/planet.js +432 -0
  83. package/dist/engine/planet.js.map +1 -0
  84. package/dist/engine/procedural.d.ts +71 -0
  85. package/dist/engine/procedural.js +259 -0
  86. package/dist/engine/procedural.js.map +1 -0
  87. package/dist/engine/quality.d.ts +48 -0
  88. package/dist/engine/quality.js +245 -0
  89. package/dist/engine/quality.js.map +1 -0
  90. package/dist/engine/repository.d.ts +79 -0
  91. package/dist/engine/repository.js +13 -0
  92. package/dist/engine/repository.js.map +1 -0
  93. package/dist/engine/sun.d.ts +61 -0
  94. package/dist/engine/sun.js +240 -0
  95. package/dist/engine/sun.js.map +1 -0
  96. package/dist/engine/temporal.d.ts +67 -0
  97. package/dist/engine/temporal.js +283 -0
  98. package/dist/engine/temporal.js.map +1 -0
  99. package/dist/engine/types.d.ts +179 -0
  100. package/dist/engine/types.js +27 -0
  101. package/dist/engine/types.js.map +1 -0
  102. package/dist/index.d.ts +2 -0
  103. package/dist/index.js +60 -0
  104. package/dist/index.js.map +1 -0
  105. package/dist/mcp/connector-registry.d.ts +20 -0
  106. package/dist/mcp/connector-registry.js +35 -0
  107. package/dist/mcp/connector-registry.js.map +1 -0
  108. package/dist/mcp/server.d.ts +13 -0
  109. package/dist/mcp/server.js +242 -0
  110. package/dist/mcp/server.js.map +1 -0
  111. package/dist/mcp/tools/daemon-tool.d.ts +16 -0
  112. package/dist/mcp/tools/daemon-tool.js +58 -0
  113. package/dist/mcp/tools/daemon-tool.js.map +1 -0
  114. package/dist/mcp/tools/ingestion-tools.d.ts +20 -0
  115. package/dist/mcp/tools/ingestion-tools.js +34 -0
  116. package/dist/mcp/tools/ingestion-tools.js.map +1 -0
  117. package/dist/mcp/tools/memory-tools.d.ts +122 -0
  118. package/dist/mcp/tools/memory-tools.js +1037 -0
  119. package/dist/mcp/tools/memory-tools.js.map +1 -0
  120. package/dist/scanner/cloud/github.d.ts +34 -0
  121. package/dist/scanner/cloud/github.js +260 -0
  122. package/dist/scanner/cloud/github.js.map +1 -0
  123. package/dist/scanner/cloud/google-drive.d.ts +30 -0
  124. package/dist/scanner/cloud/google-drive.js +289 -0
  125. package/dist/scanner/cloud/google-drive.js.map +1 -0
  126. package/dist/scanner/cloud/notion.d.ts +33 -0
  127. package/dist/scanner/cloud/notion.js +231 -0
  128. package/dist/scanner/cloud/notion.js.map +1 -0
  129. package/dist/scanner/cloud/slack.d.ts +38 -0
  130. package/dist/scanner/cloud/slack.js +282 -0
  131. package/dist/scanner/cloud/slack.js.map +1 -0
  132. package/dist/scanner/cloud/types.d.ts +73 -0
  133. package/dist/scanner/cloud/types.js +9 -0
  134. package/dist/scanner/cloud/types.js.map +1 -0
  135. package/dist/scanner/index.d.ts +35 -0
  136. package/dist/scanner/index.js +420 -0
  137. package/dist/scanner/index.js.map +1 -0
  138. package/dist/scanner/local/filesystem.d.ts +33 -0
  139. package/dist/scanner/local/filesystem.js +203 -0
  140. package/dist/scanner/local/filesystem.js.map +1 -0
  141. package/dist/scanner/local/git.d.ts +24 -0
  142. package/dist/scanner/local/git.js +161 -0
  143. package/dist/scanner/local/git.js.map +1 -0
  144. package/dist/scanner/local/parsers/code.d.ts +3 -0
  145. package/dist/scanner/local/parsers/code.js +127 -0
  146. package/dist/scanner/local/parsers/code.js.map +1 -0
  147. package/dist/scanner/local/parsers/index.d.ts +11 -0
  148. package/dist/scanner/local/parsers/index.js +24 -0
  149. package/dist/scanner/local/parsers/index.js.map +1 -0
  150. package/dist/scanner/local/parsers/json-parser.d.ts +3 -0
  151. package/dist/scanner/local/parsers/json-parser.js +117 -0
  152. package/dist/scanner/local/parsers/json-parser.js.map +1 -0
  153. package/dist/scanner/local/parsers/markdown.d.ts +3 -0
  154. package/dist/scanner/local/parsers/markdown.js +120 -0
  155. package/dist/scanner/local/parsers/markdown.js.map +1 -0
  156. package/dist/scanner/local/parsers/text.d.ts +3 -0
  157. package/dist/scanner/local/parsers/text.js +41 -0
  158. package/dist/scanner/local/parsers/text.js.map +1 -0
  159. package/dist/scanner/metadata-scanner.d.ts +67 -0
  160. package/dist/scanner/metadata-scanner.js +356 -0
  161. package/dist/scanner/metadata-scanner.js.map +1 -0
  162. package/dist/scanner/types.d.ts +47 -0
  163. package/dist/scanner/types.js +19 -0
  164. package/dist/scanner/types.js.map +1 -0
  165. package/dist/service/daemon.d.ts +23 -0
  166. package/dist/service/daemon.js +105 -0
  167. package/dist/service/daemon.js.map +1 -0
  168. package/dist/service/scheduler.d.ts +73 -0
  169. package/dist/service/scheduler.js +281 -0
  170. package/dist/service/scheduler.js.map +1 -0
  171. package/dist/storage/database.d.ts +10 -0
  172. package/dist/storage/database.js +265 -0
  173. package/dist/storage/database.js.map +1 -0
  174. package/dist/storage/queries.d.ts +85 -0
  175. package/dist/storage/queries.js +865 -0
  176. package/dist/storage/queries.js.map +1 -0
  177. package/dist/storage/sqlite-repository.d.ts +32 -0
  178. package/dist/storage/sqlite-repository.js +68 -0
  179. package/dist/storage/sqlite-repository.js.map +1 -0
  180. package/dist/storage/vec.d.ts +62 -0
  181. package/dist/storage/vec.js +111 -0
  182. package/dist/storage/vec.js.map +1 -0
  183. package/dist/utils/config.d.ts +5 -0
  184. package/dist/utils/config.js +60 -0
  185. package/dist/utils/config.js.map +1 -0
  186. package/dist/utils/logger.d.ts +36 -0
  187. package/dist/utils/logger.js +86 -0
  188. package/dist/utils/logger.js.map +1 -0
  189. package/dist/utils/time.d.ts +21 -0
  190. package/dist/utils/time.js +42 -0
  191. package/dist/utils/time.js.map +1 -0
  192. package/dist/utils/tokenizer.d.ts +13 -0
  193. package/dist/utils/tokenizer.js +46 -0
  194. package/dist/utils/tokenizer.js.map +1 -0
  195. package/package.json +77 -0
  196. package/scripts/check-node.mjs +36 -0
  197. package/scripts/setup.mjs +157 -0
@@ -0,0 +1,432 @@
1
+ /**
2
+ * planet.ts — Memory (planet) management
3
+ *
4
+ * Memories are "planets" orbiting the sun. This module handles:
5
+ * - createMemory : place a new memory into orbit.
6
+ * - recallMemories: search memories and apply access boost to results (hybrid).
7
+ * - forgetMemory : push a memory to the Oort cloud or soft-delete it.
8
+ *
9
+ * Phase 2: Hybrid search
10
+ * createMemory kicks off an async background embedding job so that the
11
+ * synchronous call returns immediately while the vector index is populated
12
+ * without blocking the caller.
13
+ *
14
+ * recallMemories merges FTS5 keyword results with vector KNN results using
15
+ * Reciprocal Rank Fusion (RRF), then deduplicates and re-ranks.
16
+ */
17
+ import { randomUUID, createHash } from 'node:crypto';
18
+ import { IMPACT_DEFAULTS } from './types.js';
19
+ import { insertMemory, searchMemoriesInRange, updateMemoryAccess, updateMemoryOrbit, insertOrbitLog, softDeleteMemory, getMemoryById, getSunState, getMemoryByIds, getMemoryByContentHash, updateQualityScore, getEdgesForBatch, getMemoriesByProject, } from '../storage/queries.js';
20
+ import { getConfig } from '../utils/config.js';
21
+ import { calculateImportance, importanceToDistance, applyAccessBoost, recencyScore, frequencyScore, } from './orbit.js';
22
+ import { keywordRelevance } from './gravity.js';
23
+ import { generateEmbedding } from './embedding.js';
24
+ import { insertEmbedding, searchByVector, deleteEmbedding } from '../storage/vec.js';
25
+ import { getDatabase, withTransaction } from '../storage/database.js';
26
+ import { createLogger } from '../utils/logger.js';
27
+ import { corona } from './corona.js';
28
+ import { calculateQuality } from './quality.js';
29
+ import { trackBgError } from '../mcp/tools/memory-tools.js';
30
+ import { runConsolidation } from './consolidation.js';
31
+ const log = createLogger('planet');
32
+ // ---------------------------------------------------------------------------
33
+ // createMemory
34
+ // ---------------------------------------------------------------------------
35
+ /**
36
+ * Create a new memory planet and place it in initial orbit.
37
+ *
38
+ * Initial placement uses static component values because the memory has just
39
+ * been created and has no access history or proven relevance yet:
40
+ * - recency = 1.0 (brand new)
41
+ * - frequency = 0.0 (never recalled)
42
+ * - impact = type-specific default (or caller-supplied)
43
+ * - relevance = 0.0 (no context yet; updated on next commit)
44
+ *
45
+ * The resulting distance positions the memory in the inner zone for high-impact
46
+ * types (decisions, milestones) and further out for lower-impact types.
47
+ */
48
+ export function createMemory(data) {
49
+ const config = getConfig();
50
+ const type = data.type ?? 'observation';
51
+ const impact = data.impact ?? IMPACT_DEFAULTS[type];
52
+ const tags = data.tags ?? [];
53
+ // Auto-generate a summary from the first 50 characters if none provided.
54
+ const raw = data.content.trim();
55
+ const summary = data.summary
56
+ ? data.summary
57
+ : raw.slice(0, 50).trimEnd() + (raw.length > 50 ? '…' : '');
58
+ // Content-hash deduplication: return the existing memory if identical content
59
+ // has already been stored in this project.
60
+ const contentHash = createHash('sha256').update(data.content).digest('hex');
61
+ const existing = getMemoryByContentHash(data.project, contentHash);
62
+ if (existing) {
63
+ log.debug('Duplicate content detected — returning existing memory', {
64
+ id: existing.id,
65
+ project: data.project,
66
+ content_hash: contentHash,
67
+ });
68
+ return existing;
69
+ }
70
+ // Compute initial importance using static scores.
71
+ const rec = recencyScore(null, new Date().toISOString(), config.decayHalfLifeHours);
72
+ const freq = frequencyScore(0, config.frequencySaturationPoint);
73
+ // Compute relevance against current sun context so new memories start at a
74
+ // position that reflects their relevance to current work, rather than 0.
75
+ const sunState = getSunState(data.project);
76
+ const sunText = sunState
77
+ ? [sunState.current_work, ...sunState.recent_decisions, ...sunState.next_steps].join(' ')
78
+ : '';
79
+ const memoryText = data.content + ' ' + tags.join(' ');
80
+ const rel = keywordRelevance(memoryText, sunText);
81
+ const total = Math.min(1.0, config.weights.recency * rec +
82
+ config.weights.frequency * freq +
83
+ config.weights.impact * impact +
84
+ config.weights.relevance * rel);
85
+ const distance = importanceToDistance(total);
86
+ const now = new Date().toISOString();
87
+ const memory = insertMemory({
88
+ id: randomUUID(),
89
+ project: data.project,
90
+ content: data.content,
91
+ summary,
92
+ type,
93
+ tags,
94
+ distance,
95
+ importance: total,
96
+ velocity: 0,
97
+ impact,
98
+ access_count: 0,
99
+ last_accessed_at: null,
100
+ metadata: {},
101
+ content_hash: contentHash,
102
+ created_at: now,
103
+ updated_at: now,
104
+ deleted_at: null,
105
+ });
106
+ // Background embedding: fire-and-forget so createMemory stays synchronous.
107
+ // The vector index will be populated within seconds after the model loads.
108
+ scheduleEmbedding(memory.id, memory.content + ' ' + summary);
109
+ // Calculate and persist initial quality score
110
+ try {
111
+ const quality = calculateQuality(memory);
112
+ updateQualityScore(memory.id, quality.overall);
113
+ }
114
+ catch {
115
+ // Quality scoring is non-critical — don't block creation
116
+ }
117
+ // If the new memory lands in the corona zone, cache it immediately.
118
+ if (memory.distance < 5.0) {
119
+ corona.upsert(memory);
120
+ }
121
+ // Auto-consolidation: trigger background consolidation when project
122
+ // memory count exceeds 100 to keep the memory system lean.
123
+ try {
124
+ const projectMemories = getMemoriesByProject(data.project);
125
+ if (projectMemories.length > 100) {
126
+ runConsolidation(data.project).catch(() => {
127
+ try {
128
+ trackBgError('consolidation');
129
+ }
130
+ catch { /* ignore */ }
131
+ });
132
+ }
133
+ }
134
+ catch {
135
+ // Non-critical — skip silently
136
+ }
137
+ return memory;
138
+ }
139
+ /**
140
+ * Schedule an async embedding generation for a memory.
141
+ * Errors are swallowed so they never affect the calling code path.
142
+ */
143
+ function scheduleEmbedding(memoryId, text) {
144
+ generateEmbedding(text)
145
+ .then(embedding => {
146
+ try {
147
+ const db = getDatabase();
148
+ insertEmbedding(db, memoryId, embedding);
149
+ }
150
+ catch {
151
+ // DB may have been reset (tests) — ignore silently
152
+ }
153
+ })
154
+ .catch(() => {
155
+ // Model not loaded / network error — FTS5 fallback remains active
156
+ try {
157
+ trackBgError('embedding');
158
+ }
159
+ catch { /* ignore circular import at startup */ }
160
+ });
161
+ }
162
+ // ---------------------------------------------------------------------------
163
+ // forgetMemory
164
+ // ---------------------------------------------------------------------------
165
+ /**
166
+ * Forget a memory.
167
+ *
168
+ * Modes:
169
+ * - 'push' : Push the memory to the Oort cloud (distance ≈ 95 AU).
170
+ * The memory remains searchable but will rarely surface.
171
+ * - 'delete': Soft-delete the memory (sets deleted_at; excluded from queries).
172
+ */
173
+ export function forgetMemory(memoryId, mode) {
174
+ if (mode === 'delete') {
175
+ softDeleteMemory(memoryId);
176
+ corona.evict(memoryId);
177
+ return;
178
+ }
179
+ // Push mode: drift the memory to the deep Oort cloud.
180
+ const memory = getMemoryById(memoryId);
181
+ if (!memory) {
182
+ return;
183
+ }
184
+ const OORT_DISTANCE = 95.0; // deep Oort cloud but not at maximum
185
+ const newImportance = 0.02; // nearly forgotten
186
+ const velocity = OORT_DISTANCE - memory.distance;
187
+ updateMemoryOrbit(memoryId, OORT_DISTANCE, newImportance, velocity);
188
+ insertOrbitLog({
189
+ memory_id: memoryId,
190
+ project: memory.project,
191
+ old_distance: memory.distance,
192
+ new_distance: OORT_DISTANCE,
193
+ old_importance: memory.importance,
194
+ new_importance: newImportance,
195
+ trigger: 'forget',
196
+ });
197
+ // Also remove the embedding from the vector index
198
+ try {
199
+ const db = getDatabase();
200
+ deleteEmbedding(db, memoryId);
201
+ }
202
+ catch {
203
+ // vec tables may not be available — ignore
204
+ }
205
+ // Evict from corona cache regardless of mode.
206
+ corona.evict(memoryId);
207
+ }
208
+ // ---------------------------------------------------------------------------
209
+ // Hybrid search helpers (Phase 2)
210
+ // ---------------------------------------------------------------------------
211
+ /**
212
+ * Reciprocal Rank Fusion: merge FTS5 results and vector result IDs.
213
+ *
214
+ * RRF(d) = Σ 1 / (k + rank_i) where k = 60 (standard constant)
215
+ *
216
+ * Both lists are ranked 1-based. The merged list is sorted by descending
217
+ * RRF score and de-duplicated.
218
+ *
219
+ * Returns an array of Memory objects in merged order. Memories that only
220
+ * appear in the vecIds list will be represented as partial stubs with just
221
+ * the id field populated — callers should call hydrateVectorOnlyResults().
222
+ */
223
+ function mergeRRF(ftsResults, vecIds, limit) {
224
+ const K = 60;
225
+ const scores = new Map();
226
+ ftsResults.forEach((m, i) => {
227
+ scores.set(m.id, (scores.get(m.id) ?? 0) + 1 / (K + i + 1));
228
+ });
229
+ vecIds.forEach((id, i) => {
230
+ scores.set(id, (scores.get(id) ?? 0) + 1 / (K + i + 1));
231
+ });
232
+ // Sort by descending RRF score
233
+ const sorted = [...scores.entries()]
234
+ .sort((a, b) => b[1] - a[1])
235
+ .slice(0, limit)
236
+ .map(([id]) => id);
237
+ // Build result list: prefer full Memory objects from ftsResults when available
238
+ const ftsMap = new Map(ftsResults.map(m => [m.id, m]));
239
+ return sorted.map(id => ftsMap.get(id) ?? { id });
240
+ }
241
+ /**
242
+ * Resolve partial Memory stubs (from vector-only results) into full objects.
243
+ * Performs a single batched DB lookup for all missing memories.
244
+ */
245
+ function hydrateVectorOnlyResults(merged, ftsResults) {
246
+ const ftsIds = new Set(ftsResults.map(m => m.id));
247
+ const missingIds = merged
248
+ .filter(m => !ftsIds.has(m.id) && m.content === undefined)
249
+ .map(m => m.id);
250
+ if (missingIds.length === 0)
251
+ return merged;
252
+ const fetched = getMemoryByIds(missingIds);
253
+ const fetchedMap = new Map(fetched.map(m => [m.id, m]));
254
+ return merged.map(m => m.content === undefined ? (fetchedMap.get(m.id) ?? m) : m);
255
+ }
256
+ // ---------------------------------------------------------------------------
257
+ // Tiered recall pipeline (Corona architecture)
258
+ // ---------------------------------------------------------------------------
259
+ /** Zone boost factors applied to search results by tier origin. */
260
+ const ZONE_BOOST = {
261
+ core: 1.2,
262
+ near: 1.1,
263
+ active: 1.0,
264
+ archive: 0.95,
265
+ fading: 0.85,
266
+ forgotten: 0.7,
267
+ };
268
+ /** Tier priority multiplier (earlier tiers are preferred at equal relevance). */
269
+ const TIER_PRIORITY = {
270
+ tier1: 1.0,
271
+ tier2: 0.95,
272
+ tier3: 0.90,
273
+ };
274
+ /**
275
+ * Async tiered recall: 3-tier pipeline from corona cache → FTS5 → full hybrid.
276
+ *
277
+ * Tier 1: Corona cache (0ms) — core + near zone, token matching
278
+ * Tier 2: Active zone FTS5 (1-5ms) — distance 5.0–15.0
279
+ * Tier 3: Full hybrid FTS5 + vector (5-50ms) — distance 15.0+
280
+ *
281
+ * Early exit: if Tier 1 fills the requested limit, Tier 2 and 3 are skipped.
282
+ */
283
+ export async function recallMemoriesAsync(project, query, options) {
284
+ const limit = options?.limit ?? 10;
285
+ const scored = [];
286
+ // Pre-seed seenIds with exclusions (e.g., corona IDs already shown in Sun)
287
+ const seenIds = new Set(options?.excludeIds ?? []);
288
+ // ── Tier 1: Corona cache (in-memory, ~0ms) ─────────────────────────────
289
+ const coronaResults = corona.search(query, limit * 2);
290
+ for (let i = 0; i < coronaResults.length; i++) {
291
+ const m = coronaResults[i];
292
+ const zoneBoost = m.distance < 1.0 ? ZONE_BOOST.core : ZONE_BOOST.near;
293
+ const rankScore = 1 / (1 + i); // rank-based score
294
+ scored.push({
295
+ memory: m,
296
+ score: rankScore * zoneBoost * TIER_PRIORITY.tier1,
297
+ tier: m.distance < 1.0 ? 'CORE' : 'NEAR',
298
+ });
299
+ seenIds.add(m.id);
300
+ }
301
+ // Early exit: if corona filled the limit, skip DB searches
302
+ const remaining = limit - scored.length;
303
+ // ── Tier 2: Active zone FTS5 (distance 5.0–15.0, ~1-5ms) ──────────────
304
+ if (remaining > 0) {
305
+ const tier2Results = searchMemoriesInRange(project, query, 5.0, 15.0, remaining * 2);
306
+ for (let i = 0; i < tier2Results.length; i++) {
307
+ const m = tier2Results[i];
308
+ if (seenIds.has(m.id))
309
+ continue;
310
+ const rankScore = 1 / (1 + i);
311
+ scored.push({
312
+ memory: m,
313
+ score: rankScore * ZONE_BOOST.active * TIER_PRIORITY.tier2,
314
+ tier: 'ACTIVE',
315
+ });
316
+ seenIds.add(m.id);
317
+ }
318
+ }
319
+ // ── Tier 3: Full hybrid FTS5 + vector (distance 15.0+, ~5-50ms) ───────
320
+ const remaining3 = limit - scored.filter(s => s.score > 0).length;
321
+ if (remaining3 > 0) {
322
+ const fetchN = remaining3 * 3;
323
+ // FTS5 for far zone
324
+ const ftsResults = searchMemoriesInRange(project, query, 15.0, 100.0, fetchN);
325
+ // Vector KNN search (async embedding)
326
+ let vecIds = [];
327
+ try {
328
+ const db = getDatabase();
329
+ const queryEmbedding = await generateEmbedding(query);
330
+ const vecResults = searchByVector(db, queryEmbedding, fetchN);
331
+ vecIds = vecResults.map(r => r.memoryId);
332
+ }
333
+ catch {
334
+ // Model not ready or vec tables unavailable — FTS5 covers it
335
+ }
336
+ // Merge FTS5 + vector via RRF
337
+ let merged = mergeRRF(ftsResults, vecIds, fetchN);
338
+ merged = hydrateVectorOnlyResults(merged, ftsResults);
339
+ for (let i = 0; i < merged.length; i++) {
340
+ const m = merged[i];
341
+ if (seenIds.has(m.id))
342
+ continue;
343
+ if (!m.content)
344
+ continue; // skip unhydrated stubs
345
+ const zoneBoost = m.distance < 40
346
+ ? ZONE_BOOST.archive
347
+ : m.distance < 70
348
+ ? ZONE_BOOST.fading
349
+ : ZONE_BOOST.forgotten;
350
+ const rankScore = 1 / (1 + i);
351
+ scored.push({
352
+ memory: m,
353
+ score: rankScore * zoneBoost * TIER_PRIORITY.tier3,
354
+ tier: 'DEEP',
355
+ });
356
+ seenIds.add(m.id);
357
+ }
358
+ }
359
+ // ── Constellation edge boost ──────────────────────────────────────────
360
+ // Memories connected via knowledge graph edges get a score boost.
361
+ try {
362
+ const scoredIds = scored.map(s => s.memory.id);
363
+ const edgeMap = getEdgesForBatch(scoredIds, project);
364
+ const EDGE_BOOST = 0.07;
365
+ for (const entry of scored) {
366
+ const neighbors = edgeMap.get(entry.memory.id);
367
+ if (neighbors && neighbors.size > 0) {
368
+ // Boost proportional to number of connections (capped at 3)
369
+ const edgeCount = Math.min(neighbors.size, 3);
370
+ entry.score += edgeCount * EDGE_BOOST;
371
+ }
372
+ }
373
+ }
374
+ catch {
375
+ // Constellation tables may not exist — skip boost silently
376
+ }
377
+ // ── Sort by composite score descending ─────────────────────────────────
378
+ scored.sort((a, b) => b.score - a.score);
379
+ // ── Filter ─────────────────────────────────────────────────────────────
380
+ let filtered = scored;
381
+ if (options?.type && options.type !== 'all') {
382
+ const filterType = options.type;
383
+ filtered = filtered.filter(s => s.memory.type === filterType);
384
+ }
385
+ if (options?.minDistance !== undefined) {
386
+ const minDist = options.minDistance;
387
+ filtered = filtered.filter(s => s.memory.distance >= minDist);
388
+ }
389
+ if (options?.maxDistance !== undefined) {
390
+ const maxDist = options.maxDistance;
391
+ filtered = filtered.filter(s => s.memory.distance <= maxDist);
392
+ }
393
+ const finalScored = filtered.slice(0, limit);
394
+ // ── Access boost + orbit update ────────────────────────────────────────
395
+ const sunState = getSunState(project);
396
+ const sunText = sunState
397
+ ? [sunState.current_work, ...sunState.recent_decisions, ...sunState.next_steps].join(' ')
398
+ : '';
399
+ const config = getConfig();
400
+ const results = withTransaction(() => finalScored.map(({ memory, tier }) => {
401
+ const newDistance = applyAccessBoost(memory.distance);
402
+ const velocity = newDistance - memory.distance;
403
+ updateMemoryAccess(memory.id);
404
+ const updatedMemory = {
405
+ ...memory,
406
+ distance: newDistance,
407
+ access_count: memory.access_count + 1,
408
+ last_accessed_at: new Date().toISOString(),
409
+ };
410
+ const components = calculateImportance(updatedMemory, sunText, config);
411
+ updateMemoryOrbit(memory.id, newDistance, components.total, velocity);
412
+ insertOrbitLog({
413
+ memory_id: memory.id,
414
+ project,
415
+ old_distance: memory.distance,
416
+ new_distance: newDistance,
417
+ old_importance: memory.importance,
418
+ new_importance: components.total,
419
+ trigger: 'access',
420
+ });
421
+ const result = { ...updatedMemory, importance: components.total, velocity };
422
+ // If memory moved into the corona zone (< 5.0 AU), update cache
423
+ if (newDistance < 5.0) {
424
+ corona.upsert(result);
425
+ }
426
+ // Attach tier marker to metadata for display
427
+ result.metadata = { ...result.metadata, _tier: tier };
428
+ return result;
429
+ }));
430
+ return results;
431
+ }
432
+ //# sourceMappingURL=planet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planet.js","sourceRoot":"","sources":["../../src/engine/planet.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * procedural.ts — Procedural Memory ("Navigation Rules")
3
+ *
4
+ * Procedural memories are behavioral rules learned from patterns in other
5
+ * memories. They represent "how we do things here" — conventions, workflows,
6
+ * and recurring solutions extracted from observed repetition.
7
+ *
8
+ * Key behaviors:
9
+ * - Pattern detection: group memories by tags, find groups with 3+ members
10
+ * - Rule creation: procedural memories start with high impact (0.9)
11
+ * - Slow decay: procedural memories decay at 30% of the normal rate
12
+ * - Sun integration: top 5 rules appear in a dedicated section
13
+ */
14
+ import type { Memory } from './types.js';
15
+ /**
16
+ * Detect patterns in the memory corpus that are strong enough to warrant
17
+ * a procedural rule.
18
+ *
19
+ * Returns one candidate per tag-group that has 3+ members, describing the
20
+ * observed pattern and suggesting a concrete rule.
21
+ */
22
+ export declare function detectProceduralPattern(memories: Memory[], project: string): Array<{
23
+ pattern: string;
24
+ frequency: number;
25
+ suggestedRule: string;
26
+ }>;
27
+ /**
28
+ * Create a procedural memory from a learned rule and its supporting evidence.
29
+ *
30
+ * Procedural memories:
31
+ * - Use type 'procedural'
32
+ * - Start with high impact (0.9) so they orbit close to the sun
33
+ * - Include both the rule and the evidence that generated it
34
+ * - Are tagged with 'procedural' plus terms extracted from the rule
35
+ */
36
+ export declare function createProceduralMemory(rule: string, evidence: string[], project: string): Memory;
37
+ /**
38
+ * Get all procedural memories for a project, sorted by importance descending.
39
+ * These feed into the sun content formatter and the suggest logic.
40
+ */
41
+ export declare function getProceduralMemories(project: string): Memory[];
42
+ /**
43
+ * Format procedural memories as a concise "Navigation Rules" section
44
+ * suitable for inclusion in the sun resource content.
45
+ *
46
+ * At most 5 rules are shown (most important first). Each rule is rendered
47
+ * as a single numbered line extracted from the content (the "Rule: ..." part).
48
+ */
49
+ export declare function formatProceduralSection(memories: Memory[]): string;
50
+ /**
51
+ * Procedural memories are hard-won knowledge and should be highly durable.
52
+ * Return 0.3 so that the effective half-life is ~3.3x longer than normal.
53
+ *
54
+ * Used by orbit.ts when calculating recency score for procedural memories:
55
+ * effectiveHalfLife = baseHalfLife / getProceduralDecayMultiplier()
56
+ */
57
+ export declare function getProceduralDecayMultiplier(): number;
58
+ /**
59
+ * Analyse the last 50 memories and suggest concrete procedural rules.
60
+ *
61
+ * Returns candidates sorted by confidence (highest first). Confidence is
62
+ * the proportion of the tag-group that supports a consistent pattern.
63
+ *
64
+ * Skips rules that already exist as procedural memories (by rule text match).
65
+ */
66
+ export declare function suggestRules(recentMemories: Memory[]): Array<{
67
+ rule: string;
68
+ confidence: number;
69
+ evidence: Memory[];
70
+ }>;
71
+ //# sourceMappingURL=procedural.d.ts.map