sensorium-mcp 3.1.3 → 3.1.5

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 (203) hide show
  1. package/Install-Sensorium.ps1 +251 -39
  2. package/dist/config/agent-settings.d.ts +11 -0
  3. package/dist/config/agent-settings.d.ts.map +1 -1
  4. package/dist/config/agent-settings.js +79 -0
  5. package/dist/config/agent-settings.js.map +1 -1
  6. package/dist/config/index.d.ts +1 -0
  7. package/dist/config/index.d.ts.map +1 -1
  8. package/dist/config/index.js +12 -0
  9. package/dist/config/index.js.map +1 -1
  10. package/dist/config/misc-settings.d.ts +7 -0
  11. package/dist/config/misc-settings.d.ts.map +1 -1
  12. package/dist/config/misc-settings.js +38 -1
  13. package/dist/config/misc-settings.js.map +1 -1
  14. package/dist/dashboard/routes/codex.d.ts +14 -0
  15. package/dist/dashboard/routes/codex.d.ts.map +1 -0
  16. package/dist/dashboard/routes/codex.js +92 -0
  17. package/dist/dashboard/routes/codex.js.map +1 -0
  18. package/dist/dashboard/routes/prompts.d.ts +2 -2
  19. package/dist/dashboard/routes/prompts.d.ts.map +1 -1
  20. package/dist/dashboard/routes/prompts.js +2 -2
  21. package/dist/dashboard/routes/prompts.js.map +1 -1
  22. package/dist/dashboard/routes/threads-read.d.ts +10 -7
  23. package/dist/dashboard/routes/threads-read.d.ts.map +1 -1
  24. package/dist/dashboard/routes/threads-read.js +21 -16
  25. package/dist/dashboard/routes/threads-read.js.map +1 -1
  26. package/dist/dashboard/routes.d.ts.map +1 -1
  27. package/dist/dashboard/routes.js +3 -0
  28. package/dist/dashboard/routes.js.map +1 -1
  29. package/dist/dashboard/spa.html +11 -11
  30. package/dist/data/memory/bootstrap.d.ts +1 -8
  31. package/dist/data/memory/bootstrap.d.ts.map +1 -1
  32. package/dist/data/memory/bootstrap.js +27 -37
  33. package/dist/data/memory/bootstrap.js.map +1 -1
  34. package/dist/data/memory/consolidation.d.ts +20 -1
  35. package/dist/data/memory/consolidation.d.ts.map +1 -1
  36. package/dist/data/memory/consolidation.js +53 -3
  37. package/dist/data/memory/consolidation.js.map +1 -1
  38. package/dist/data/memory/index.d.ts +0 -4
  39. package/dist/data/memory/index.d.ts.map +1 -1
  40. package/dist/data/memory/index.js +0 -4
  41. package/dist/data/memory/index.js.map +1 -1
  42. package/dist/data/memory/key-knowledge.d.ts +51 -0
  43. package/dist/data/memory/key-knowledge.d.ts.map +1 -0
  44. package/dist/data/memory/key-knowledge.js +128 -0
  45. package/dist/data/memory/key-knowledge.js.map +1 -0
  46. package/dist/data/memory/migration-runner.d.ts +1 -1
  47. package/dist/data/memory/migration-runner.d.ts.map +1 -1
  48. package/dist/data/memory/migration-runner.js +23 -1
  49. package/dist/data/memory/migration-runner.js.map +1 -1
  50. package/dist/data/memory/narrative-lint.d.ts +2 -2
  51. package/dist/data/memory/narrative-lint.d.ts.map +1 -1
  52. package/dist/data/memory/narrative-lint.js +23 -13
  53. package/dist/data/memory/narrative-lint.js.map +1 -1
  54. package/dist/data/memory/narrative-resolutions.d.ts +7 -2
  55. package/dist/data/memory/narrative-resolutions.d.ts.map +1 -1
  56. package/dist/data/memory/narrative-resolutions.js +7 -8
  57. package/dist/data/memory/narrative-resolutions.js.map +1 -1
  58. package/dist/data/memory/narrative-sources.d.ts +1 -1
  59. package/dist/data/memory/narrative-sources.d.ts.map +1 -1
  60. package/dist/data/memory/narrative-sources.js +8 -3
  61. package/dist/data/memory/narrative-sources.js.map +1 -1
  62. package/dist/data/memory/narrative-store.d.ts +14 -0
  63. package/dist/data/memory/narrative-store.d.ts.map +1 -1
  64. package/dist/data/memory/narrative-store.js +36 -0
  65. package/dist/data/memory/narrative-store.js.map +1 -1
  66. package/dist/data/memory/narrative.d.ts.map +1 -1
  67. package/dist/data/memory/narrative.js +47 -29
  68. package/dist/data/memory/narrative.js.map +1 -1
  69. package/dist/data/memory/note-archival.d.ts +1 -1
  70. package/dist/data/memory/note-archival.d.ts.map +1 -1
  71. package/dist/data/memory/note-archival.js +7 -3
  72. package/dist/data/memory/note-archival.js.map +1 -1
  73. package/dist/data/memory/note-embeddings.d.ts +7 -0
  74. package/dist/data/memory/note-embeddings.d.ts.map +1 -1
  75. package/dist/data/memory/note-embeddings.js +6 -2
  76. package/dist/data/memory/note-embeddings.js.map +1 -1
  77. package/dist/data/memory/schema-ddl.d.ts +1 -1
  78. package/dist/data/memory/schema-ddl.d.ts.map +1 -1
  79. package/dist/data/memory/schema-ddl.js +3 -1
  80. package/dist/data/memory/schema-ddl.js.map +1 -1
  81. package/dist/data/memory/semantic-notes.d.ts +13 -8
  82. package/dist/data/memory/semantic-notes.d.ts.map +1 -1
  83. package/dist/data/memory/semantic-notes.js +12 -17
  84. package/dist/data/memory/semantic-notes.js.map +1 -1
  85. package/dist/data/memory/thread-registry.d.ts +7 -1
  86. package/dist/data/memory/thread-registry.d.ts.map +1 -1
  87. package/dist/data/memory/thread-registry.js +14 -5
  88. package/dist/data/memory/thread-registry.js.map +1 -1
  89. package/dist/data/memory/utils.d.ts +6 -0
  90. package/dist/data/memory/utils.d.ts.map +1 -1
  91. package/dist/data/memory/utils.js +13 -0
  92. package/dist/data/memory/utils.js.map +1 -1
  93. package/dist/integrations/openai/speech.js +4 -4
  94. package/dist/integrations/openai/speech.js.map +1 -1
  95. package/dist/lib/http-retry.d.ts +91 -0
  96. package/dist/lib/http-retry.d.ts.map +1 -0
  97. package/dist/lib/http-retry.js +177 -0
  98. package/dist/lib/http-retry.js.map +1 -0
  99. package/dist/lib/usage-metering/pricing.js +1 -1
  100. package/dist/lib/usage-metering/pricing.js.map +1 -1
  101. package/dist/llm/prompts/narrative.d.ts.map +1 -1
  102. package/dist/llm/prompts/narrative.js +27 -86
  103. package/dist/llm/prompts/narrative.js.map +1 -1
  104. package/dist/services/claude-spawn.service.d.ts.map +1 -1
  105. package/dist/services/claude-spawn.service.js +6 -1
  106. package/dist/services/claude-spawn.service.js.map +1 -1
  107. package/dist/services/codex-spawn.service.d.ts +2 -2
  108. package/dist/services/codex-spawn.service.d.ts.map +1 -1
  109. package/dist/services/codex-spawn.service.js +64 -58
  110. package/dist/services/codex-spawn.service.js.map +1 -1
  111. package/dist/services/consolidation.service.d.ts.map +1 -1
  112. package/dist/services/consolidation.service.js +10 -43
  113. package/dist/services/consolidation.service.js.map +1 -1
  114. package/dist/services/copilot-spawn.service.d.ts.map +1 -1
  115. package/dist/services/copilot-spawn.service.js +6 -1
  116. package/dist/services/copilot-spawn.service.js.map +1 -1
  117. package/dist/services/daily-session.d.ts +22 -11
  118. package/dist/services/daily-session.d.ts.map +1 -1
  119. package/dist/services/daily-session.js +69 -24
  120. package/dist/services/daily-session.js.map +1 -1
  121. package/dist/services/dispatcher/poller.d.ts.map +1 -1
  122. package/dist/services/dispatcher/poller.js +8 -15
  123. package/dist/services/dispatcher/poller.js.map +1 -1
  124. package/dist/services/http-retry.d.ts +1 -90
  125. package/dist/services/http-retry.d.ts.map +1 -1
  126. package/dist/services/http-retry.js +1 -176
  127. package/dist/services/http-retry.js.map +1 -1
  128. package/dist/services/mcp-config.service.d.ts.map +1 -1
  129. package/dist/services/mcp-config.service.js +14 -1
  130. package/dist/services/mcp-config.service.js.map +1 -1
  131. package/dist/services/memory-briefing.service.d.ts +1 -1
  132. package/dist/services/memory-briefing.service.d.ts.map +1 -1
  133. package/dist/services/memory-briefing.service.js +27 -73
  134. package/dist/services/memory-briefing.service.js.map +1 -1
  135. package/dist/services/memory-pruning.service.d.ts.map +1 -1
  136. package/dist/services/memory-pruning.service.js +22 -4
  137. package/dist/services/memory-pruning.service.js.map +1 -1
  138. package/dist/services/predefined-prompts.d.ts +11 -0
  139. package/dist/services/predefined-prompts.d.ts.map +1 -0
  140. package/dist/services/predefined-prompts.js +25 -0
  141. package/dist/services/predefined-prompts.js.map +1 -0
  142. package/dist/services/spawn-common.d.ts +10 -2
  143. package/dist/services/spawn-common.d.ts.map +1 -1
  144. package/dist/services/spawn-common.js +25 -4
  145. package/dist/services/spawn-common.js.map +1 -1
  146. package/dist/services/telegram.d.ts +7 -5
  147. package/dist/services/telegram.d.ts.map +1 -1
  148. package/dist/services/telegram.js +18 -13
  149. package/dist/services/telegram.js.map +1 -1
  150. package/dist/sessions/mcp-registry.d.ts +7 -2
  151. package/dist/sessions/mcp-registry.d.ts.map +1 -1
  152. package/dist/sessions/mcp-registry.js +52 -30
  153. package/dist/sessions/mcp-registry.js.map +1 -1
  154. package/dist/tools/defs/memory-defs.d.ts.map +1 -1
  155. package/dist/tools/defs/memory-defs.js +4 -0
  156. package/dist/tools/defs/memory-defs.js.map +1 -1
  157. package/dist/tools/delegate-tool.js +2 -2
  158. package/dist/tools/delegate-tool.js.map +1 -1
  159. package/dist/tools/memory-tools.d.ts.map +1 -1
  160. package/dist/tools/memory-tools.js +9 -1
  161. package/dist/tools/memory-tools.js.map +1 -1
  162. package/dist/tools/start-session-tool.d.ts.map +1 -1
  163. package/dist/tools/start-session-tool.js +13 -1
  164. package/dist/tools/start-session-tool.js.map +1 -1
  165. package/dist/tools/wait/consolidation-strategy.d.ts +42 -0
  166. package/dist/tools/wait/consolidation-strategy.d.ts.map +1 -0
  167. package/dist/tools/wait/consolidation-strategy.js +50 -0
  168. package/dist/tools/wait/consolidation-strategy.js.map +1 -0
  169. package/dist/tools/wait/drive-handler.d.ts +5 -7
  170. package/dist/tools/wait/drive-handler.d.ts.map +1 -1
  171. package/dist/tools/wait/drive-handler.js +45 -59
  172. package/dist/tools/wait/drive-handler.js.map +1 -1
  173. package/dist/tools/wait/message-delivery.d.ts.map +1 -1
  174. package/dist/tools/wait/message-delivery.js +4 -21
  175. package/dist/tools/wait/message-delivery.js.map +1 -1
  176. package/dist/tools/wait/message-processing.d.ts.map +1 -1
  177. package/dist/tools/wait/message-processing.js +2 -1
  178. package/dist/tools/wait/message-processing.js.map +1 -1
  179. package/dist/tools/wait/poll-loop.d.ts.map +1 -1
  180. package/dist/tools/wait/poll-loop.js +8 -8
  181. package/dist/tools/wait/poll-loop.js.map +1 -1
  182. package/package.json +1 -1
  183. package/templates/increment-pr-pipeline.default.md +79 -0
  184. package/dist/data/memory/reflection-dedup.d.ts +0 -17
  185. package/dist/data/memory/reflection-dedup.d.ts.map +0 -1
  186. package/dist/data/memory/reflection-dedup.js +0 -55
  187. package/dist/data/memory/reflection-dedup.js.map +0 -1
  188. package/dist/data/memory/reflection-gates.d.ts +0 -40
  189. package/dist/data/memory/reflection-gates.d.ts.map +0 -1
  190. package/dist/data/memory/reflection-gates.js +0 -220
  191. package/dist/data/memory/reflection-gates.js.map +0 -1
  192. package/dist/data/memory/reflection-sources.d.ts +0 -13
  193. package/dist/data/memory/reflection-sources.d.ts.map +0 -1
  194. package/dist/data/memory/reflection-sources.js +0 -115
  195. package/dist/data/memory/reflection-sources.js.map +0 -1
  196. package/dist/data/memory/reflection.d.ts +0 -43
  197. package/dist/data/memory/reflection.d.ts.map +0 -1
  198. package/dist/data/memory/reflection.js +0 -329
  199. package/dist/data/memory/reflection.js.map +0 -1
  200. package/dist/llm/prompts/reflection.d.ts +0 -6
  201. package/dist/llm/prompts/reflection.d.ts.map +0 -1
  202. package/dist/llm/prompts/reflection.js +0 -77
  203. package/dist/llm/prompts/reflection.js.map +0 -1
@@ -27,11 +27,6 @@ export interface BootstrapNarratives {
27
27
  week?: string;
28
28
  day?: string;
29
29
  }
30
- export interface BootstrapReflection {
31
- content: string;
32
- confidence: number;
33
- createdAt: string;
34
- }
35
30
  export interface BootstrapContext {
36
31
  identityPrompt?: string;
37
32
  threadId: number;
@@ -39,11 +34,9 @@ export interface BootstrapContext {
39
34
  memorySourceThreadId?: number;
40
35
  recentEpisodes: Episode[];
41
36
  guardrails: SemanticNote[];
42
- pinnedNotes: SemanticNote[];
43
37
  keyKnowledge: SemanticNote[];
44
38
  baseline: ReturnType<typeof getVoiceBaseline>;
45
39
  narratives: BootstrapNarratives | null;
46
- reflections: BootstrapReflection[];
47
40
  }
48
41
  export declare function getMemoryStatus(db: Database, threadId: number): MemoryStatus;
49
42
  /**
@@ -54,7 +47,7 @@ export declare function getMemoryStatus(db: Database, threadId: number): MemoryS
54
47
  * this display. Aggregating a few thousand active notes takes milliseconds.
55
48
  */
56
49
  export declare function getTopicIndex(db: Database): TopicEntry[];
57
- export declare function getBootstrapContext(db: Database, threadId: number, memorySourceThreadId?: number): BootstrapContext;
50
+ export declare function getBootstrapContext(db: Database, threadId: number, memorySourceThreadId?: number): Promise<BootstrapContext>;
58
51
  export declare function getCompactRefreshNotes(db: Database, threadId: number): SemanticNote[];
59
52
  export declare function forgetMemory(db: Database, memoryId: string, _reason: string): {
60
53
  layer: string;
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../../src/data/memory/bootstrap.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAqB,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAIL,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAQlD,eAAO,MAAM,gCAAgC,SAAU,CAAC;AACxD,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAE7C,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,SAAS,EAAE,UAAU,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,cAAc,EAAE,OAAO,EAAE,CAAC;IAC1B,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,WAAW,EAAE,YAAY,EAAE,CAAC;IAC5B,YAAY,EAAE,YAAY,EAAE,CAAC;IAC7B,QAAQ,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;IAC9C,UAAU,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACvC,WAAW,EAAE,mBAAmB,EAAE,CAAC;CACpC;AAQD,wBAAgB,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,CAwC5E;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,GAAG,UAAU,EAAE,CAmDxD;AAED,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,QAAQ,EACZ,QAAQ,EAAE,MAAM,EAChB,oBAAoB,CAAC,EAAE,MAAM,GAC5B,gBAAgB,CAkFlB;AAED,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,EAAE,CAMrF;AAED,wBAAgB,YAAY,CAC1B,EAAE,EAAE,QAAQ,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAgDrC"}
1
+ {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../../src/data/memory/bootstrap.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAqB,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAIL,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAgBlD,eAAO,MAAM,gCAAgC,SAAU,CAAC;AACxD,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAE7C,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,SAAS,EAAE,UAAU,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,cAAc,EAAE,OAAO,EAAE,CAAC;IAC1B,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,YAAY,EAAE,YAAY,EAAE,CAAC;IAC7B,QAAQ,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;IAC9C,UAAU,EAAE,mBAAmB,GAAG,IAAI,CAAC;CACxC;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,CAwC5E;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,GAAG,UAAU,EAAE,CAmDxD;AAED,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,QAAQ,EACZ,QAAQ,EAAE,MAAM,EAChB,oBAAoB,CAAC,EAAE,MAAM,GAC5B,OAAO,CAAC,gBAAgB,CAAC,CA8D3B;AAED,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,EAAE,CAMrF;AAED,wBAAgB,YAAY,CAC1B,EAAE,EAAE,QAAQ,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAgDrC"}
@@ -1,12 +1,13 @@
1
1
  import { statSync } from "node:fs";
2
2
  import { dataPath } from "../../lib/paths.js";
3
3
  import { getRecentEpisodes } from "./episodes.js";
4
- import { getTopSemanticNotes, getGuardrailNotes, getPinnedNotes, } from "./semantic-notes.js";
4
+ import { getTopSemanticNotes, getGuardrailNotes, getPinnedNoteIds, } from "./semantic-notes.js";
5
5
  import { getVoiceBaseline } from "./voice-sig.js";
6
6
  import { parseJsonArray } from "./utils.js";
7
7
  import { getNarrativesForBootstrap } from "./narrative.js";
8
8
  import { getThread } from "./thread-registry.js";
9
- import { getGuardrailsEnabled, getBootstrapMessageCount } from "../../config/index.js";
9
+ import { selectKeyKnowledge } from "./key-knowledge.js";
10
+ import { getGuardrailsEnabled, getBootstrapMessageCount, getRelevanceAnchorThreshold, getKeyKnowledgeMax, getRelevanceAnchorTailEpisodes, config, } from "../../config/index.js";
10
11
  import { log } from "../../lib/logger.js";
11
12
  import { errorMessage } from "../../lib/utils.js";
12
13
  export const MAX_BOOTSTRAP_CONVERSATION_CHARS = 100_000;
@@ -88,24 +89,35 @@ export function getTopicIndex(db) {
88
89
  .sort((a, b) => b.totalAccesses - a.totalAccesses || b.semanticCount - a.semanticCount)
89
90
  .slice(0, 50);
90
91
  }
91
- export function getBootstrapContext(db, threadId, memorySourceThreadId) {
92
+ export async function getBootstrapContext(db, threadId, memorySourceThreadId) {
92
93
  const queryThreadId = memorySourceThreadId ?? threadId;
93
94
  const knowledgeThreadId = queryThreadId;
94
95
  const bootstrapMessageCount = getBootstrapMessageCount();
95
96
  const threadEntry = getThread(db, queryThreadId);
96
- const sessionResetAt = threadEntry?.sessionResetAt ?? undefined;
97
- const recentEpisodes = [
98
- ...getRecentEpisodes(db, queryThreadId, bootstrapMessageCount, sessionResetAt ? { since: sessionResetAt } : undefined),
99
- ].reverse();
100
- const topNotes = getTopSemanticNotes(db, {
101
- limit: 20,
102
- sortBy: "access_count",
97
+ // Recent conversation tail — always the last N messages by recency, regardless
98
+ // of session_reset_at. A restarted/rotated session MUST see where the previous
99
+ // session left off and continue from the briefing alone. Clamping this layer to
100
+ // `timestamp > session_reset_at` emptied it right after a daily rotation (which
101
+ // resets session_reset_at to now), so the fresh session had no recent context
102
+ // and produced nonsense/summaries — forcing the operator to manually ask it to
103
+ // re-read recent history. The layer is char-budgeted downstream, so the last N
104
+ // stays bounded; the render also tells the agent to only fetch OLDER episodes,
105
+ // so this never triggers over-reading.
106
+ const recentEpisodes = [...getRecentEpisodes(db, queryThreadId, bootstrapMessageCount)].reverse();
107
+ // Key Knowledge is relevance-anchored, not recency-ranked: embed the recent
108
+ // conversation tail and keep only notes clearing a cosine threshold, rendered
109
+ // in full ("maximally relevant or none"). Pinned notes join the SAME pool with
110
+ // a relevance boost — pinning is a ranking weight now, not forced presence, so
111
+ // an off-topic pin does not surface. Falls back to the freshest notes by
112
+ // updated_at when embedding is unavailable/empty/failing — see selectKeyKnowledge.
113
+ const keyKnowledgeNotes = await selectKeyKnowledge(db, {
103
114
  threadId: knowledgeThreadId,
115
+ apiKey: config.OPENAI_API_KEY,
116
+ threshold: getRelevanceAnchorThreshold(),
117
+ maxResults: getKeyKnowledgeMax(),
118
+ tailEpisodes: getRelevanceAnchorTailEpisodes(),
119
+ pinnedNoteIds: getPinnedNoteIds(db, knowledgeThreadId),
104
120
  });
105
- const preferences = topNotes.filter((note) => note.type === "preference");
106
- const otherNotes = topNotes.filter((note) => note.type !== "preference");
107
- const pinnedNotes = getPinnedNotes(db, knowledgeThreadId);
108
- const pinnedIds = new Set(pinnedNotes.map((note) => note.noteId));
109
121
  let narratives = null;
110
122
  try {
111
123
  const fetched = getNarrativesForBootstrap(db, knowledgeThreadId);
@@ -123,24 +135,6 @@ export function getBootstrapContext(db, threadId, memorySourceThreadId) {
123
135
  log.warn(`[bootstrap] Failed to load narratives for thread ${knowledgeThreadId}: ${errorMessage(err)}`);
124
136
  narratives = null;
125
137
  }
126
- let reflections;
127
- try {
128
- const rows = db
129
- .prepare(`SELECT content, confidence, created_at FROM semantic_notes
130
- WHERE content LIKE '[REFLECTION]%'
131
- AND valid_to IS NULL AND superseded_by IS NULL AND thread_id = ?
132
- ORDER BY created_at DESC LIMIT 5`)
133
- .all(knowledgeThreadId);
134
- reflections = rows.map((row) => ({
135
- content: row.content,
136
- confidence: row.confidence,
137
- createdAt: row.created_at,
138
- }));
139
- }
140
- catch (err) {
141
- log.warn(`[bootstrap] Failed to load reflections for thread ${knowledgeThreadId}: ${errorMessage(err)}`);
142
- reflections = [];
143
- }
144
138
  return {
145
139
  identityPrompt: threadEntry?.identityPrompt ?? undefined,
146
140
  threadId,
@@ -148,13 +142,9 @@ export function getBootstrapContext(db, threadId, memorySourceThreadId) {
148
142
  memorySourceThreadId,
149
143
  recentEpisodes,
150
144
  guardrails: getGuardrailsEnabled() ? getGuardrailNotes(db) : [],
151
- pinnedNotes,
152
- keyKnowledge: [...preferences, ...otherNotes]
153
- .slice(0, 20)
154
- .filter((note) => !pinnedIds.has(note.noteId)),
145
+ keyKnowledge: keyKnowledgeNotes,
155
146
  baseline: getVoiceBaseline(db),
156
147
  narratives,
157
- reflections,
158
148
  };
159
149
  }
160
150
  export function getCompactRefreshNotes(db, threadId) {
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../../src/data/memory/bootstrap.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../../src/data/memory/bootstrap.ts"],"names":[],"mappings":"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"}
@@ -44,7 +44,26 @@ export declare function getActiveNoteContent(db: Database, noteId: string): {
44
44
  content: string;
45
45
  } | null;
46
46
  export declare function expireNote(db: Database, noteId: string, now: string, reason: Extract<ExpiryReason, "pruned" | "quality-gate">): void;
47
- export declare function mergeDuplicateNote(db: Database, keepId: string, expireId: string, now: string, mergedContent?: string): void;
47
+ /**
48
+ * TTL sweep: soft-expire notes whose write-time `expires_at` has elapsed. Runs
49
+ * in the consolidation cycle alongside pruning. Reversible — sets valid_to +
50
+ * expiry_reason='ttl' and prepends [EXPIRED]; never hard-deletes. Applies to
51
+ * pinned/guardrail notes too (a soft expiry can be restored). Notes with
52
+ * expires_at IS NULL — the default — are never touched, so pre-TTL behavior is
53
+ * unchanged. Returns the number of notes expired.
54
+ */
55
+ export declare function sweepExpiredNotes(db: Database): number;
56
+ /**
57
+ * Merge a duplicate note into a kept one, retiring the duplicate (expiry_reason
58
+ * 'merged'). Returns true if the merge happened, false if it was refused.
59
+ *
60
+ * A guardrail or pinned note is NEVER the retired side: dedup must not silently
61
+ * drop an enforced rule or a pinned invariant. When the expire target is
62
+ * protected the whole operation is a no-op (no content rewrite, no retirement) —
63
+ * the protected note stays active — mirroring supersedeNote's guard. This is the
64
+ * "exclude protected notes from the retired side" option.
65
+ */
66
+ export declare function mergeDuplicateNote(db: Database, keepId: string, expireId: string, now: string, mergedContent?: string): boolean;
48
67
  /**
49
68
  * Delete note_embeddings rows only for notes that are gone entirely or
50
69
  * permanently dead (superseded / merged / pruned). Vectors of archived,
@@ -1 +1 @@
1
- {"version":3,"file":"consolidation.d.ts","sourceRoot":"","sources":["../../../src/data/memory/consolidation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAC;AAM5B,MAAM,WAAW,mBAAmB;IAClC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAQD,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,EAAE,CAUjE;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAM5E;AAED,wBAAgB,gCAAgC,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAEnE;AAED,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,EAAE,CAcxF;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAOnE;AAED,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,MAAM,GACb;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAQ5C;AAED,wBAAgB,UAAU,CACxB,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,OAAO,CAAC,YAAY,EAAE,QAAQ,GAAG,cAAc,CAAC,GACvD,IAAI,CAIN;AAED,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,aAAa,CAAC,EAAE,MAAM,GACrB,IAAI,CAeN;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,CAgB5D;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,CAmBvD"}
1
+ {"version":3,"file":"consolidation.d.ts","sourceRoot":"","sources":["../../../src/data/memory/consolidation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAC;AAM5B,MAAM,WAAW,mBAAmB;IAClC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAQD,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,EAAE,CAUjE;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAM5E;AAED,wBAAgB,gCAAgC,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAEnE;AAED,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,EAAE,CAiBxF;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAOnE;AAED,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,MAAM,GACb;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAQ5C;AAED,wBAAgB,UAAU,CACxB,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,OAAO,CAAC,YAAY,EAAE,QAAQ,GAAG,cAAc,CAAC,GACvD,IAAI,CAUN;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,CAgBtD;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CA0BT;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,CAgB5D;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,CAmBvD"}
@@ -27,13 +27,16 @@ export function cleanupConsolidationHousekeeping(db) {
27
27
  cleanupOldSentMessages(db);
28
28
  }
29
29
  export function getCandidateNotesForPruning(db, maxNotes) {
30
+ // Guardrail and pinned notes are INTENTIONALLY candidates: the LLM judge is the
31
+ // only path that can catch a stale pin or a guardrail whose deadline has passed
32
+ // ("tonight", "in progress" from a past date). The judge stays conservative
33
+ // (see memory-pruning.service.ts) and expiry is soft/reversible, so surfacing
34
+ // them here does not endanger durable rules.
30
35
  return db
31
36
  .prepare(`
32
37
  SELECT * FROM semantic_notes
33
38
  WHERE valid_to IS NULL
34
39
  AND superseded_by IS NULL
35
- AND is_guardrail = 0
36
- AND pinned = 0
37
40
  ORDER BY access_count ASC, created_at ASC
38
41
  LIMIT ?
39
42
  `)
@@ -54,15 +57,62 @@ export function getActiveNoteContent(db, noteId) {
54
57
  return { noteId: row.note_id, content: row.content };
55
58
  }
56
59
  export function expireNote(db, noteId, now, reason) {
57
- db.prepare(`UPDATE semantic_notes SET valid_to = ?, updated_at = ?, expiry_reason = ? WHERE note_id = ?`).run(now, now, reason, noteId);
60
+ // Prepend an [EXPIRED] marker so any later inspection of the tombstone reads as
61
+ // deliberately retired (consistent with the TTL sweep). `AND valid_to IS NULL`
62
+ // makes a double-mark / re-expiry structurally impossible — an already-expired
63
+ // note is never re-touched even if a caller passes one in.
64
+ db.prepare(`UPDATE semantic_notes
65
+ SET valid_to = ?, updated_at = ?, expiry_reason = ?, content = '[EXPIRED] ' || content
66
+ WHERE note_id = ? AND valid_to IS NULL`).run(now, now, reason, noteId);
58
67
  }
68
+ /**
69
+ * TTL sweep: soft-expire notes whose write-time `expires_at` has elapsed. Runs
70
+ * in the consolidation cycle alongside pruning. Reversible — sets valid_to +
71
+ * expiry_reason='ttl' and prepends [EXPIRED]; never hard-deletes. Applies to
72
+ * pinned/guardrail notes too (a soft expiry can be restored). Notes with
73
+ * expires_at IS NULL — the default — are never touched, so pre-TTL behavior is
74
+ * unchanged. Returns the number of notes expired.
75
+ */
76
+ export function sweepExpiredNotes(db) {
77
+ const now = nowISO();
78
+ const result = db
79
+ .prepare(`UPDATE semantic_notes
80
+ SET valid_to = ?, updated_at = ?, expiry_reason = 'ttl', content = '[EXPIRED] ' || content
81
+ WHERE expires_at IS NOT NULL
82
+ AND expires_at <= ?
83
+ AND valid_to IS NULL
84
+ AND superseded_by IS NULL`)
85
+ .run(now, now, now);
86
+ if (result.changes > 0) {
87
+ log.info(`[memory] TTL sweep: expired ${result.changes} note(s) past expires_at`);
88
+ }
89
+ return result.changes;
90
+ }
91
+ /**
92
+ * Merge a duplicate note into a kept one, retiring the duplicate (expiry_reason
93
+ * 'merged'). Returns true if the merge happened, false if it was refused.
94
+ *
95
+ * A guardrail or pinned note is NEVER the retired side: dedup must not silently
96
+ * drop an enforced rule or a pinned invariant. When the expire target is
97
+ * protected the whole operation is a no-op (no content rewrite, no retirement) —
98
+ * the protected note stays active — mirroring supersedeNote's guard. This is the
99
+ * "exclude protected notes from the retired side" option.
100
+ */
59
101
  export function mergeDuplicateNote(db, keepId, expireId, now, mergedContent) {
102
+ const expireRow = db
103
+ .prepare(`SELECT is_guardrail, pinned FROM semantic_notes WHERE note_id = ?`)
104
+ .get(expireId);
105
+ if (expireRow && (expireRow.is_guardrail === 1 || expireRow.pinned === 1)) {
106
+ log.warn(`[memory] Refusing to merge-away guardrail/pinned note ${expireId}; leaving it active`);
107
+ return false;
108
+ }
60
109
  if (mergedContent) {
61
110
  db.prepare(`UPDATE semantic_notes SET content = ?, updated_at = ? WHERE note_id = ?`).run(mergedContent, now, keepId);
62
111
  }
63
112
  db.prepare(`UPDATE semantic_notes SET valid_to = ?, superseded_by = ?, updated_at = ?, expiry_reason = 'merged' WHERE note_id = ?`).run(now, keepId, now, expireId);
64
113
  // Repoint inbound causal links from the merged-away note to the kept note.
65
114
  migrateInboundLinks(db, expireId, keepId);
115
+ return true;
66
116
  }
67
117
  /**
68
118
  * Delete note_embeddings rows only for notes that are gone entirely or
@@ -1 +1 @@
1
- {"version":3,"file":"consolidation.js","sourceRoot":"","sources":["../../../src/data/memory/consolidation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"consolidation.js","sourceRoot":"","sources":["../../../src/data/memory/consolidation.ts"],"names":[],"mappings":"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"}
@@ -19,10 +19,6 @@ export * from "./note-embeddings.js";
19
19
  export * from "./note-archival.js";
20
20
  export * from "./voice-sig.js";
21
21
  export * from "./consolidation.js";
22
- export * from "./reflection.js";
23
- export * from "./reflection-gates.js";
24
- export * from "./reflection-dedup.js";
25
- export * from "./reflection-sources.js";
26
22
  export * from "./narrative.js";
27
23
  export * from "./narrative-lint.js";
28
24
  export * from "./narrative-resolutions.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/data/memory/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/data/memory/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC"}
@@ -19,10 +19,6 @@ export * from "./note-embeddings.js";
19
19
  export * from "./note-archival.js";
20
20
  export * from "./voice-sig.js";
21
21
  export * from "./consolidation.js";
22
- export * from "./reflection.js";
23
- export * from "./reflection-gates.js";
24
- export * from "./reflection-dedup.js";
25
- export * from "./reflection-sources.js";
26
22
  export * from "./narrative.js";
27
23
  export * from "./narrative-lint.js";
28
24
  export * from "./narrative-resolutions.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/data/memory/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/data/memory/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Relevance-anchored Key-Knowledge selection for the bootstrap briefing.
3
+ *
4
+ * "Maximally relevant or none": instead of listing the top-N most recent notes
5
+ * (which still surfaces stale, off-topic ones), we anchor an embedding on the
6
+ * RECENT-CONVERSATION tail, cosine-score every active note for the thread, and
7
+ * keep only those clearing a similarity threshold — rendered fully, never
8
+ * truncated. A spike on thread 1327 (1789 notes) validated this: sim>=0.40 gave
9
+ * 23 tightly on-topic notes, 0.45 gave 9. So ~0.40 is a self-limiting, high
10
+ * quality cut.
11
+ *
12
+ * The selector NEVER throws or hangs: a missing API key, an embedding
13
+ * error/timeout, an empty tail (fresh thread), or zero matches all fall back to
14
+ * the historical recency selector so the briefing degrades gracefully.
15
+ */
16
+ import type { Database } from "./schema.js";
17
+ import { type SemanticNote } from "./semantic-notes.js";
18
+ /**
19
+ * Similarity bump a pinned note gets before the threshold cut and ranking.
20
+ * Pinning is a relevance WEIGHT, not forced presence: a pinned note outranks an
21
+ * equally-similar plain note and can clear the threshold on a near-miss, but a
22
+ * pinned note that is genuinely off-topic (well below threshold) still drops.
23
+ * Modest by design — 0.05 nudges neighbours without flooding the list.
24
+ */
25
+ export declare const PINNED_RELEVANCE_BOOST = 0.05;
26
+ export interface KeyKnowledgeParams {
27
+ threadId: number;
28
+ /** OpenAI key; empty string forces the recency fallback. */
29
+ apiKey: string;
30
+ /** Minimum cosine similarity a note must clear to be included. */
31
+ threshold: number;
32
+ /** Upper bound on notes returned (also the fallback slice size). */
33
+ maxResults: number;
34
+ /** How many recent conversation episodes form the anchor. */
35
+ tailEpisodes: number;
36
+ /**
37
+ * Pinned note IDs to boost by PINNED_RELEVANCE_BOOST in the relevance path.
38
+ * Omitted/empty ⇒ no boost (e.g. the recency fallback, or a thread with no pins).
39
+ */
40
+ pinnedNoteIds?: Set<string>;
41
+ }
42
+ /** Drop notes whose content exactly duplicates an earlier one, keeping the first. */
43
+ export declare function dedupeByContent(notes: SemanticNote[]): SemanticNote[];
44
+ /**
45
+ * Select the Key-Knowledge notes for a thread's bootstrap briefing.
46
+ *
47
+ * Relevance path when possible; otherwise the recency fallback. Guaranteed not
48
+ * to throw — every failure mode resolves to the fallback selection.
49
+ */
50
+ export declare function selectKeyKnowledge(db: Database, params: KeyKnowledgeParams): Promise<SemanticNote[]>;
51
+ //# sourceMappingURL=key-knowledge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-knowledge.d.ts","sourceRoot":"","sources":["../../../src/data/memory/key-knowledge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAoB7E;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAE3C,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,UAAU,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC7B;AAUD,qFAAqF;AACrF,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,YAAY,EAAE,CAOrE;AAmDD;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,YAAY,EAAE,CAAC,CAyCzB"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Relevance-anchored Key-Knowledge selection for the bootstrap briefing.
3
+ *
4
+ * "Maximally relevant or none": instead of listing the top-N most recent notes
5
+ * (which still surfaces stale, off-topic ones), we anchor an embedding on the
6
+ * RECENT-CONVERSATION tail, cosine-score every active note for the thread, and
7
+ * keep only those clearing a similarity threshold — rendered fully, never
8
+ * truncated. A spike on thread 1327 (1789 notes) validated this: sim>=0.40 gave
9
+ * 23 tightly on-topic notes, 0.45 gave 9. So ~0.40 is a self-limiting, high
10
+ * quality cut.
11
+ *
12
+ * The selector NEVER throws or hangs: a missing API key, an embedding
13
+ * error/timeout, an empty tail (fresh thread), or zero matches all fall back to
14
+ * the historical recency selector so the briefing degrades gracefully.
15
+ */
16
+ import { getTopSemanticNotes } from "./semantic-notes.js";
17
+ import { searchByEmbedding } from "./note-embeddings.js";
18
+ import { generateEmbedding } from "../../integrations/openai/chat.js";
19
+ import { parseJsonObject } from "./utils.js";
20
+ import { log } from "../../lib/logger.js";
21
+ import { errorMessage } from "../../lib/utils.js";
22
+ /** Max characters of anchor text sent for embedding (model caps at ~8191 tokens). */
23
+ const ANCHOR_TEXT_MAX_CHARS = 8000;
24
+ /**
25
+ * Hard wall-clock bound on the anchor embedding call. generateEmbedding has its
26
+ * own 30s abort, but the bootstrap must not block that long on a slow network —
27
+ * we cut over to the recency fallback well before then.
28
+ */
29
+ const EMBED_TIMEOUT_MS = 12_000;
30
+ /** Episode types that make up the "conversation" used as the relevance anchor. */
31
+ const ANCHOR_EPISODE_TYPES = ["operator_message", "agent_action"];
32
+ /**
33
+ * Similarity bump a pinned note gets before the threshold cut and ranking.
34
+ * Pinning is a relevance WEIGHT, not forced presence: a pinned note outranks an
35
+ * equally-similar plain note and can clear the threshold on a near-miss, but a
36
+ * pinned note that is genuinely off-topic (well below threshold) still drops.
37
+ * Modest by design — 0.05 nudges neighbours without flooding the list.
38
+ */
39
+ export const PINNED_RELEVANCE_BOOST = 0.05;
40
+ /** Drop notes whose content exactly duplicates an earlier one, keeping the first. */
41
+ export function dedupeByContent(notes) {
42
+ const seen = new Set();
43
+ return notes.filter((note) => {
44
+ if (seen.has(note.content))
45
+ return false;
46
+ seen.add(note.content);
47
+ return true;
48
+ });
49
+ }
50
+ /** Historical selector: freshest active notes by updated_at, deduped and capped. */
51
+ function selectByRecency(db, threadId, limit) {
52
+ const notes = getTopSemanticNotes(db, { limit, sortBy: "updated_at", threadId });
53
+ return dedupeByContent(notes).slice(0, limit);
54
+ }
55
+ /**
56
+ * Concatenate the last N conversation episodes (oldest → newest) into anchor
57
+ * text, mirroring the spike: pull operator/agent messages by recency, reverse
58
+ * to chronological, extract the human-readable field, and cap the length.
59
+ */
60
+ function buildAnchorText(db, threadId, tailEpisodes) {
61
+ const typePlaceholders = ANCHOR_EPISODE_TYPES.map(() => "?").join(",");
62
+ const rows = db
63
+ .prepare(`SELECT content FROM episodes
64
+ WHERE thread_id = ? AND type IN (${typePlaceholders})
65
+ ORDER BY timestamp DESC LIMIT ?`)
66
+ .all(threadId, ...ANCHOR_EPISODE_TYPES, tailEpisodes);
67
+ return rows
68
+ .reverse()
69
+ .map((row) => {
70
+ const content = parseJsonObject(row.content);
71
+ return String(content.text || content.raw || content.caption || content.message || "");
72
+ })
73
+ .filter((text) => text.trim())
74
+ .join("\n")
75
+ .slice(0, ANCHOR_TEXT_MAX_CHARS);
76
+ }
77
+ /** Reject after `ms` so a slow embedding can't stall the bootstrap. */
78
+ function withTimeout(promise, ms, label) {
79
+ return new Promise((resolve, reject) => {
80
+ const timer = setTimeout(() => reject(new Error(`${label} timed out after ${ms}ms`)), ms);
81
+ promise.then((value) => {
82
+ clearTimeout(timer);
83
+ resolve(value);
84
+ }, (err) => {
85
+ clearTimeout(timer);
86
+ reject(err);
87
+ });
88
+ });
89
+ }
90
+ /**
91
+ * Select the Key-Knowledge notes for a thread's bootstrap briefing.
92
+ *
93
+ * Relevance path when possible; otherwise the recency fallback. Guaranteed not
94
+ * to throw — every failure mode resolves to the fallback selection.
95
+ */
96
+ export async function selectKeyKnowledge(db, params) {
97
+ const { threadId, apiKey, threshold, maxResults, tailEpisodes, pinnedNoteIds } = params;
98
+ const finish = (notes, source) => {
99
+ log.info(`[key-knowledge] thread ${threadId}: ${notes.length} notes via ${source} (threshold ${threshold})`);
100
+ return notes;
101
+ };
102
+ if (!apiKey)
103
+ return finish(selectByRecency(db, threadId, maxResults), "recency:no-api-key");
104
+ const anchorText = buildAnchorText(db, threadId, tailEpisodes);
105
+ if (!anchorText.trim()) {
106
+ return finish(selectByRecency(db, threadId, maxResults), "recency:empty-tail");
107
+ }
108
+ try {
109
+ const anchor = await withTimeout(generateEmbedding(anchorText, apiKey, threadId), EMBED_TIMEOUT_MS, "anchor embedding");
110
+ const hits = searchByEmbedding(db, anchor, {
111
+ threadId,
112
+ minSimilarity: threshold,
113
+ maxResults,
114
+ skipAccessTracking: true,
115
+ boostNoteIds: pinnedNoteIds,
116
+ boostAmount: PINNED_RELEVANCE_BOOST,
117
+ });
118
+ if (hits.length === 0) {
119
+ return finish(selectByRecency(db, threadId, maxResults), "recency:no-matches");
120
+ }
121
+ return finish(hits, "relevance");
122
+ }
123
+ catch (err) {
124
+ log.warn(`[key-knowledge] thread ${threadId}: relevance selection failed (${errorMessage(err)}); using recency`);
125
+ return finish(selectByRecency(db, threadId, maxResults), "recency:error");
126
+ }
127
+ }
128
+ //# sourceMappingURL=key-knowledge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-knowledge.js","sourceRoot":"","sources":["../../../src/data/memory/key-knowledge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,mBAAmB,EAAqB,MAAM,qBAAqB,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,qFAAqF;AACrF,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAEnC;;;;GAIG;AACH,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEhC,kFAAkF;AAClF,MAAM,oBAAoB,GAAG,CAAC,kBAAkB,EAAE,cAAc,CAAU,CAAC;AAE3E;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC;AA2B3C,qFAAqF;AACrF,MAAM,UAAU,eAAe,CAAC,KAAqB;IACnD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QAC3B,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,OAAO,KAAK,CAAC;QACzC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED,oFAAoF;AACpF,SAAS,eAAe,CAAC,EAAY,EAAE,QAAgB,EAAE,KAAa;IACpE,MAAM,KAAK,GAAG,mBAAmB,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC;IACjF,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AAChD,CAAC;AAED;;;;GAIG;AACH,SAAS,eAAe,CAAC,EAAY,EAAE,QAAgB,EAAE,YAAoB;IAC3E,MAAM,gBAAgB,GAAG,oBAAoB,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvE,MAAM,IAAI,GAAG,EAAE;SACZ,OAAO,CACN;0CACoC,gBAAgB;uCACnB,CAClC;SACA,GAAG,CAAC,QAAQ,EAAE,GAAG,oBAAoB,EAAE,YAAY,CAA0B,CAAC;IAEjF,OAAO,IAAI;SACR,OAAO,EAAE;SACT,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACX,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,OAAO,CAA4B,CAAC;QACxE,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IACzF,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC7B,IAAI,CAAC,IAAI,CAAC;SACV,KAAK,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAC;AACrC,CAAC;AAED,uEAAuE;AACvE,SAAS,WAAW,CAAI,OAAmB,EAAE,EAAU,EAAE,KAAa;IACpE,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACxC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,KAAK,oBAAoB,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1F,OAAO,CAAC,IAAI,CACV,CAAC,KAAK,EAAE,EAAE;YACR,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC,EACD,CAAC,GAAG,EAAE,EAAE;YACN,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,EAAY,EACZ,MAA0B;IAE1B,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,GAAG,MAAM,CAAC;IAExF,MAAM,MAAM,GAAG,CAAC,KAAqB,EAAE,MAAuB,EAAkB,EAAE;QAChF,GAAG,CAAC,IAAI,CACN,0BAA0B,QAAQ,KAAK,KAAK,CAAC,MAAM,cAAc,MAAM,eAAe,SAAS,GAAG,CACnG,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,IAAI,CAAC,MAAM;QAAE,OAAO,MAAM,CAAC,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE,oBAAoB,CAAC,CAAC;IAE5F,MAAM,UAAU,GAAG,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;IAC/D,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;QACvB,OAAO,MAAM,CAAC,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE,oBAAoB,CAAC,CAAC;IACjF,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,WAAW,CAC9B,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAC/C,gBAAgB,EAChB,kBAAkB,CACnB,CAAC;QACF,MAAM,IAAI,GAAG,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE;YACzC,QAAQ;YACR,aAAa,EAAE,SAAS;YACxB,UAAU;YACV,kBAAkB,EAAE,IAAI;YACxB,YAAY,EAAE,aAAa;YAC3B,WAAW,EAAE,sBAAsB;SACpC,CAAC,CAAC;QACH,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,MAAM,CAAC,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE,oBAAoB,CAAC,CAAC;QACjF,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CACN,0BAA0B,QAAQ,iCAAiC,YAAY,CAAC,GAAG,CAAC,kBAAkB,CACvG,CAAC;QACF,OAAO,MAAM,CAAC,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE,eAAe,CAAC,CAAC;IAC5E,CAAC;AACH,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { Database } from "./db-types.js";
2
- export declare const SCHEMA_VERSION = 29;
2
+ export declare const SCHEMA_VERSION = 30;
3
3
  export declare function rebuildThreadRegistryWithExitedStatus(db: Database, existingColumns: string[]): void;
4
4
  /**
5
5
  * Label pre-column tombstones (valid_to set, expiry_reason NULL) with the most
@@ -1 +1 @@
1
- {"version":3,"file":"migration-runner.d.ts","sourceRoot":"","sources":["../../../src/data/memory/migration-runner.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,eAAO,MAAM,cAAc,KAAK,CAAC;AAkBjC,wBAAgB,qCAAqC,CACnD,EAAE,EAAE,QAAQ,EACZ,eAAe,EAAE,MAAM,EAAE,GACxB,IAAI,CA0DN;AAicD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CA+DxD;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAsBhD"}
1
+ {"version":3,"file":"migration-runner.d.ts","sourceRoot":"","sources":["../../../src/data/memory/migration-runner.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,eAAO,MAAM,cAAc,KAAK,CAAC;AAkBjC,wBAAgB,qCAAqC,CACnD,EAAE,EAAE,QAAQ,EACZ,eAAe,EAAE,MAAM,EAAE,GACxB,IAAI,CA0DN;AAudD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CA+DxD;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAsBhD"}
@@ -3,7 +3,7 @@ import { log } from "../../lib/logger.js";
3
3
  import { dataPath } from "../../lib/paths.js";
4
4
  import { errorMessage } from "../../lib/utils.js";
5
5
  import { nowISO } from "./utils.js";
6
- export const SCHEMA_VERSION = 29;
6
+ export const SCHEMA_VERSION = 30;
7
7
  function isDuplicateColumnError(err, columnName) {
8
8
  const message = errorMessage(err).toLowerCase();
9
9
  return message.includes(`duplicate column name: ${columnName}`.toLowerCase());
@@ -518,6 +518,28 @@ const MIGRATIONS = {
518
518
  db.exec(`DROP TABLE IF EXISTS meta_topic_index`);
519
519
  log.info("[migration-29] Dropped meta_topic_index (topics are computed on demand)");
520
520
  },
521
+ 30: (db) => {
522
+ // Optional write-time TTL. expires_at is an ISO timestamp after which the
523
+ // consolidation-cycle TTL sweep (sweepExpiredNotes) soft-expires the note.
524
+ // NULL — the default — means the note never expires on a timer, so an
525
+ // unset expires_at is byte-identical to pre-30 behavior. This is distinct
526
+ // from valid_to (the tombstone written AT expiry): expires_at is a future
527
+ // hint, valid_to is the past fact; the two must never be conflated. The
528
+ // partial index backs the sweep's hot predicate (expires_at set, still live).
529
+ try {
530
+ db.exec(`ALTER TABLE semantic_notes ADD COLUMN expires_at TEXT`);
531
+ }
532
+ catch (err) {
533
+ if (!isDuplicateColumnError(err, "expires_at"))
534
+ throw err;
535
+ }
536
+ db.exec(`CREATE INDEX IF NOT EXISTS idx_sem_expires_at ON semantic_notes(expires_at) WHERE expires_at IS NOT NULL AND valid_to IS NULL`);
537
+ log.info("[migration-30] Added expires_at column to semantic_notes");
538
+ },
539
+ // NOTE: the Agent Task Board deliberately does NOT take a number here — its
540
+ // DDL is versioned in board_schema_version (data/board/board-schema.ts,
541
+ // ensureBoardSchema) so a feature line can never collide with main's next
542
+ // migration number. No deployed DB ever recorded a v30 from the board branch.
521
543
  };
522
544
  /**
523
545
  * Label pre-column tombstones (valid_to set, expiry_reason NULL) with the most