nexo-brain 2.0.0 → 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.
Files changed (370) hide show
  1. package/README.md +143 -44
  2. package/bin/nexo-brain.js +53 -26
  3. package/package.json +15 -3
  4. package/scripts/migrate-to-unified 2.sh +813 -0
  5. package/scripts/migrate-v1.5-to-v1.6 2.py +778 -0
  6. package/scripts/migrate-v1.7-to-v1.8 2.py +214 -0
  7. package/scripts/pre-commit-check 2.sh +55 -0
  8. package/src/__pycache__/auto_update.cpython-310.pyc +0 -0
  9. package/src/__pycache__/hnsw_index.cpython-310.pyc +0 -0
  10. package/src/__pycache__/kg_populate.cpython-310.pyc +0 -0
  11. package/src/__pycache__/knowledge_graph.cpython-310.pyc +0 -0
  12. package/src/__pycache__/plugin_loader.cpython-310.pyc +0 -0
  13. package/src/__pycache__/tools_coordination.cpython-310.pyc +0 -0
  14. package/src/__pycache__/tools_credentials.cpython-310.pyc +0 -0
  15. package/src/__pycache__/tools_learnings.cpython-310.pyc +0 -0
  16. package/src/__pycache__/tools_menu.cpython-310.pyc +0 -0
  17. package/src/__pycache__/tools_reminders.cpython-310.pyc +0 -0
  18. package/src/__pycache__/tools_reminders_crud.cpython-310.pyc +0 -0
  19. package/src/__pycache__/tools_sessions.cpython-310.pyc +0 -0
  20. package/src/__pycache__/tools_task_history.cpython-310.pyc +0 -0
  21. package/src/auto_close_sessions 2.py +159 -0
  22. package/src/auto_update 2.py +634 -0
  23. package/src/claim_graph 2.py +323 -0
  24. package/src/cognitive/__init__ 2.py +62 -0
  25. package/src/cognitive/__pycache__/__init__.cpython-310.pyc +0 -0
  26. package/src/cognitive/__pycache__/_core.cpython-310.pyc +0 -0
  27. package/src/cognitive/__pycache__/_decay.cpython-310.pyc +0 -0
  28. package/src/cognitive/__pycache__/_ingest.cpython-310.pyc +0 -0
  29. package/src/cognitive/__pycache__/_memory.cpython-310.pyc +0 -0
  30. package/src/cognitive/__pycache__/_search.cpython-310.pyc +0 -0
  31. package/src/cognitive/__pycache__/_trust.cpython-310.pyc +0 -0
  32. package/src/cognitive/_core 2.py +567 -0
  33. package/src/cognitive/_decay 2.py +382 -0
  34. package/src/cognitive/_ingest 2.py +892 -0
  35. package/src/cognitive/_memory 2.py +912 -0
  36. package/src/cognitive/_search 2.py +949 -0
  37. package/src/cognitive/_trust 2.py +464 -0
  38. package/src/cognitive/_trust.py +10 -36
  39. package/src/crons/manifest 2.json +106 -0
  40. package/src/crons/manifest.json +106 -0
  41. package/src/crons/sync 2.py +217 -0
  42. package/src/crons/sync.py +217 -0
  43. package/src/dashboard/__init__ 2.py +0 -0
  44. package/src/dashboard/__pycache__/__init__.cpython-310.pyc +0 -0
  45. package/src/dashboard/__pycache__/app.cpython-310.pyc +0 -0
  46. package/src/dashboard/app 2.py +789 -0
  47. package/src/dashboard/app.py +16 -2
  48. package/src/dashboard/templates/dashboard.html +3 -2
  49. package/src/db/__init__ 2.py +89 -0
  50. package/src/db/__pycache__/__init__.cpython-310.pyc +0 -0
  51. package/src/db/__pycache__/__init__.cpython-312.pyc +0 -0
  52. package/src/db/__pycache__/__init__.cpython-314.pyc +0 -0
  53. package/src/db/__pycache__/_core.cpython-310.pyc +0 -0
  54. package/src/db/__pycache__/_core.cpython-312.pyc +0 -0
  55. package/src/db/__pycache__/_core.cpython-314.pyc +0 -0
  56. package/src/db/__pycache__/_credentials.cpython-310.pyc +0 -0
  57. package/src/db/__pycache__/_credentials.cpython-312.pyc +0 -0
  58. package/src/db/__pycache__/_credentials.cpython-314.pyc +0 -0
  59. package/src/db/__pycache__/_entities.cpython-310.pyc +0 -0
  60. package/src/db/__pycache__/_entities.cpython-312.pyc +0 -0
  61. package/src/db/__pycache__/_entities.cpython-314.pyc +0 -0
  62. package/src/db/__pycache__/_episodic.cpython-310.pyc +0 -0
  63. package/src/db/__pycache__/_episodic.cpython-312.pyc +0 -0
  64. package/src/db/__pycache__/_episodic.cpython-314.pyc +0 -0
  65. package/src/db/__pycache__/_evolution.cpython-310.pyc +0 -0
  66. package/src/db/__pycache__/_evolution.cpython-312.pyc +0 -0
  67. package/src/db/__pycache__/_evolution.cpython-314.pyc +0 -0
  68. package/src/db/__pycache__/_fts.cpython-310.pyc +0 -0
  69. package/src/db/__pycache__/_fts.cpython-312.pyc +0 -0
  70. package/src/db/__pycache__/_fts.cpython-314.pyc +0 -0
  71. package/src/db/__pycache__/_learnings.cpython-310.pyc +0 -0
  72. package/src/db/__pycache__/_learnings.cpython-312.pyc +0 -0
  73. package/src/db/__pycache__/_learnings.cpython-314.pyc +0 -0
  74. package/src/db/__pycache__/_reminders.cpython-310.pyc +0 -0
  75. package/src/db/__pycache__/_reminders.cpython-312.pyc +0 -0
  76. package/src/db/__pycache__/_reminders.cpython-314.pyc +0 -0
  77. package/src/db/__pycache__/_schema.cpython-310.pyc +0 -0
  78. package/src/db/__pycache__/_schema.cpython-312.pyc +0 -0
  79. package/src/db/__pycache__/_schema.cpython-314.pyc +0 -0
  80. package/src/db/__pycache__/_sessions.cpython-310.pyc +0 -0
  81. package/src/db/__pycache__/_sessions.cpython-312.pyc +0 -0
  82. package/src/db/__pycache__/_sessions.cpython-314.pyc +0 -0
  83. package/src/db/__pycache__/_tasks.cpython-310.pyc +0 -0
  84. package/src/db/__pycache__/_tasks.cpython-312.pyc +0 -0
  85. package/src/db/__pycache__/_tasks.cpython-314.pyc +0 -0
  86. package/src/db/_core 2.py +417 -0
  87. package/src/db/_credentials 2.py +124 -0
  88. package/src/db/_entities 2.py +178 -0
  89. package/src/db/_episodic 2.py +738 -0
  90. package/src/db/_episodic.py +1 -1
  91. package/src/db/_evolution 2.py +54 -0
  92. package/src/db/_fts 2.py +406 -0
  93. package/src/db/_learnings 2.py +168 -0
  94. package/src/db/_reminders 2.py +338 -0
  95. package/src/db/_reminders.py +9 -5
  96. package/src/db/_schema 2.py +364 -0
  97. package/src/db/_sessions 2.py +300 -0
  98. package/src/db/_tasks 2.py +91 -0
  99. package/src/evolution_cycle 2.py +266 -0
  100. package/src/hnsw_index 2.py +254 -0
  101. package/src/hooks/auto_capture 2.py +208 -0
  102. package/src/hooks/caffeinate-guard 2.sh +8 -0
  103. package/src/hooks/capture-session 2.sh +21 -0
  104. package/src/hooks/capture-session.sh +2 -0
  105. package/src/hooks/capture-tool-logs 2.sh +127 -0
  106. package/src/hooks/capture-tool-logs.sh +3 -2
  107. package/src/hooks/daily-briefing-check 2.sh +33 -0
  108. package/src/hooks/inbox-hook 2.sh +76 -0
  109. package/src/hooks/inbox-hook.sh +3 -2
  110. package/src/hooks/post-compact 2.sh +148 -0
  111. package/src/hooks/post-compact.sh +1 -1
  112. package/src/hooks/pre-compact 2.sh +151 -0
  113. package/src/hooks/pre-compact.sh +1 -1
  114. package/src/hooks/session-start 2.sh +268 -0
  115. package/src/hooks/session-start.sh +6 -3
  116. package/src/hooks/session-stop 2.sh +140 -0
  117. package/src/hooks/session-stop.sh +3 -2
  118. package/src/kg_populate 2.py +290 -0
  119. package/src/knowledge_graph 2.py +257 -0
  120. package/src/maintenance 2.py +59 -0
  121. package/src/migrate_embeddings 2.py +122 -0
  122. package/src/plugin_loader 2.py +202 -0
  123. package/src/plugins/__init__ 2.py +0 -0
  124. package/src/plugins/__pycache__/__init__ 2.cpython-310.pyc +0 -0
  125. package/src/plugins/__pycache__/__init__.cpython-310.pyc +0 -0
  126. package/src/plugins/__pycache__/adaptive_mode 2.cpython-310.pyc +0 -0
  127. package/src/plugins/__pycache__/adaptive_mode.cpython-310.pyc +0 -0
  128. package/src/plugins/__pycache__/agents 2.cpython-310.pyc +0 -0
  129. package/src/plugins/__pycache__/agents.cpython-310.pyc +0 -0
  130. package/src/plugins/__pycache__/artifact_registry 2.cpython-310.pyc +0 -0
  131. package/src/plugins/__pycache__/artifact_registry.cpython-310.pyc +0 -0
  132. package/src/plugins/__pycache__/backup 2.cpython-310.pyc +0 -0
  133. package/src/plugins/__pycache__/backup.cpython-310.pyc +0 -0
  134. package/src/plugins/__pycache__/cognitive_memory 2.cpython-310.pyc +0 -0
  135. package/src/plugins/__pycache__/cognitive_memory.cpython-310.pyc +0 -0
  136. package/src/plugins/__pycache__/core_rules 2.cpython-310.pyc +0 -0
  137. package/src/plugins/__pycache__/core_rules.cpython-310.pyc +0 -0
  138. package/src/plugins/__pycache__/cortex 2.cpython-310.pyc +0 -0
  139. package/src/plugins/__pycache__/cortex.cpython-310.pyc +0 -0
  140. package/src/plugins/__pycache__/entities 2.cpython-310.pyc +0 -0
  141. package/src/plugins/__pycache__/entities.cpython-310.pyc +0 -0
  142. package/src/plugins/__pycache__/episodic_memory 2.cpython-310.pyc +0 -0
  143. package/src/plugins/__pycache__/episodic_memory.cpython-310.pyc +0 -0
  144. package/src/plugins/__pycache__/evolution 2.cpython-310.pyc +0 -0
  145. package/src/plugins/__pycache__/evolution.cpython-310.pyc +0 -0
  146. package/src/plugins/__pycache__/guard 2.cpython-310.pyc +0 -0
  147. package/src/plugins/__pycache__/guard.cpython-310.pyc +0 -0
  148. package/src/plugins/__pycache__/knowledge_graph_tools 2.cpython-310.pyc +0 -0
  149. package/src/plugins/__pycache__/knowledge_graph_tools.cpython-310.pyc +0 -0
  150. package/src/plugins/__pycache__/preferences 2.cpython-310.pyc +0 -0
  151. package/src/plugins/__pycache__/preferences.cpython-310.pyc +0 -0
  152. package/src/plugins/__pycache__/update 2.cpython-310.pyc +0 -0
  153. package/src/plugins/__pycache__/update.cpython-310.pyc +0 -0
  154. package/src/plugins/adaptive_mode 2.py +805 -0
  155. package/src/plugins/agents 2.py +52 -0
  156. package/src/plugins/artifact_registry 2.py +450 -0
  157. package/src/plugins/backup 2.py +104 -0
  158. package/src/plugins/cognitive_memory 2.py +564 -0
  159. package/src/plugins/core_rules 2.py +252 -0
  160. package/src/plugins/core_rules.py +34 -17
  161. package/src/plugins/cortex 2.py +299 -0
  162. package/src/plugins/entities 2.py +67 -0
  163. package/src/plugins/episodic_memory 2.py +533 -0
  164. package/src/plugins/evolution 2.py +115 -0
  165. package/src/plugins/guard 2.py +746 -0
  166. package/src/plugins/knowledge_graph_tools 2.py +105 -0
  167. package/src/plugins/preferences 2.py +47 -0
  168. package/src/plugins/update 2.py +256 -0
  169. package/src/plugins/update.py +18 -0
  170. package/src/requirements 2.txt +12 -0
  171. package/src/rules/__init__ 2.py +0 -0
  172. package/src/rules/core-rules 2.json +331 -0
  173. package/src/rules/migrate 2.py +207 -0
  174. package/src/scripts/check-context 2.py +264 -0
  175. package/src/scripts/check-context.py +4 -7
  176. package/src/scripts/deep-sleep/apply_findings.py +570 -167
  177. package/src/scripts/deep-sleep/collect.py +480 -0
  178. package/src/scripts/deep-sleep/extract-prompt.md +233 -0
  179. package/src/scripts/deep-sleep/extract.py +249 -0
  180. package/src/scripts/deep-sleep/synthesize-prompt.md +197 -0
  181. package/src/scripts/deep-sleep/synthesize.py +191 -0
  182. package/src/scripts/nexo-auto-update 2.py +6 -0
  183. package/src/scripts/nexo-backup 2.sh +25 -0
  184. package/src/scripts/nexo-brain-activation 2.sh +140 -0
  185. package/src/scripts/nexo-catchup 2.py +242 -0
  186. package/src/scripts/nexo-catchup.py +5 -8
  187. package/src/scripts/nexo-cognitive-decay 2.py +182 -0
  188. package/src/scripts/nexo-daily-self-audit 2.py +552 -0
  189. package/src/scripts/nexo-daily-self-audit.py +28 -19
  190. package/src/scripts/nexo-deep-sleep 2.sh +97 -0
  191. package/src/scripts/nexo-deep-sleep.sh +31 -16
  192. package/src/scripts/nexo-evolution-run 2.py +597 -0
  193. package/src/scripts/nexo-evolution-run.py +5 -20
  194. package/src/scripts/nexo-followup-hygiene 2.py +112 -0
  195. package/src/scripts/nexo-followup-hygiene.py +4 -2
  196. package/src/scripts/nexo-github-monitor 2.py +256 -0
  197. package/src/scripts/nexo-github-monitor.py +6 -9
  198. package/src/scripts/nexo-immune 2.py +927 -0
  199. package/src/scripts/nexo-immune.py +4 -17
  200. package/src/scripts/nexo-inbox-hook 2.sh +74 -0
  201. package/src/scripts/nexo-install 2.py +6 -0
  202. package/src/scripts/nexo-learning-housekeep 2.py +245 -0
  203. package/src/scripts/nexo-learning-validator 2.py +207 -0
  204. package/src/scripts/nexo-learning-validator.py +0 -29
  205. package/src/scripts/nexo-migrate 2.py +232 -0
  206. package/src/scripts/nexo-postmortem-consolidator 2.py +421 -0
  207. package/src/scripts/nexo-postmortem-consolidator.py +9 -20
  208. package/src/scripts/nexo-pre-commit 2.py +120 -0
  209. package/src/scripts/nexo-prevent-sleep 2.sh +29 -0
  210. package/src/scripts/nexo-proactive-dashboard 2.py +345 -0
  211. package/src/scripts/nexo-proactive-dashboard.py +1 -0
  212. package/src/scripts/nexo-reflection 2.py +253 -0
  213. package/src/scripts/nexo-runtime-preflight 2.py +274 -0
  214. package/src/scripts/nexo-send-email 2.py +25 -0
  215. package/src/scripts/nexo-send-reply 2.py +178 -0
  216. package/src/scripts/nexo-sleep 2.py +592 -0
  217. package/src/scripts/nexo-sleep.py +8 -18
  218. package/src/scripts/nexo-snapshot-restore 2.sh +35 -0
  219. package/src/scripts/nexo-synthesis 2.py +253 -0
  220. package/src/scripts/nexo-synthesis.py +8 -19
  221. package/src/scripts/nexo-tcc-approve 2.sh +79 -0
  222. package/src/scripts/nexo-update 2.sh +161 -0
  223. package/src/scripts/nexo-watchdog 2.sh +878 -0
  224. package/src/scripts/nexo-watchdog-smoke 2.py +119 -0
  225. package/src/server 2.py +733 -0
  226. package/src/server.py +6 -1
  227. package/src/storage_router 2.py +32 -0
  228. package/src/tools_coordination 2.py +102 -0
  229. package/src/tools_credentials 2.py +68 -0
  230. package/src/tools_learnings 2.py +220 -0
  231. package/src/tools_menu 2.py +227 -0
  232. package/src/tools_menu.py +1 -1
  233. package/src/tools_reminders 2.py +86 -0
  234. package/src/tools_reminders_crud 2.py +159 -0
  235. package/src/tools_reminders_crud.py +7 -0
  236. package/src/tools_sessions 2.py +476 -0
  237. package/src/tools_sessions.py +67 -0
  238. package/src/tools_task_history 2.py +57 -0
  239. package/templates/CLAUDE.md 2.template +63 -0
  240. package/templates/openclaw 2.json +13 -0
  241. package/tests/__init__ 2.py +0 -0
  242. package/tests/conftest 2.py +71 -0
  243. package/tests/test_cognitive 2.py +205 -0
  244. package/tests/test_knowledge_graph 2.py +140 -0
  245. package/tests/test_migrations 2.py +137 -0
  246. package/src/__pycache__/auto_close_sessions.cpython-310.pyc +0 -0
  247. package/src/__pycache__/auto_close_sessions.cpython-314.pyc +0 -0
  248. package/src/__pycache__/auto_update.cpython-314.pyc +0 -0
  249. package/src/__pycache__/claim_graph.cpython-310.pyc +0 -0
  250. package/src/__pycache__/claim_graph.cpython-314.pyc +0 -0
  251. package/src/__pycache__/evolution_cycle.cpython-310.pyc +0 -0
  252. package/src/__pycache__/evolution_cycle.cpython-314.pyc +0 -0
  253. package/src/__pycache__/hnsw_index.cpython-314.pyc +0 -0
  254. package/src/__pycache__/kg_populate.cpython-314.pyc +0 -0
  255. package/src/__pycache__/knowledge_graph.cpython-314.pyc +0 -0
  256. package/src/__pycache__/maintenance.cpython-310.pyc +0 -0
  257. package/src/__pycache__/maintenance.cpython-314.pyc +0 -0
  258. package/src/__pycache__/migrate_embeddings.cpython-310.pyc +0 -0
  259. package/src/__pycache__/migrate_embeddings.cpython-314.pyc +0 -0
  260. package/src/__pycache__/plugin_loader.cpython-314.pyc +0 -0
  261. package/src/__pycache__/server.cpython-310.pyc +0 -0
  262. package/src/__pycache__/server.cpython-314.pyc +0 -0
  263. package/src/__pycache__/storage_router.cpython-310.pyc +0 -0
  264. package/src/__pycache__/storage_router.cpython-314.pyc +0 -0
  265. package/src/__pycache__/tools_coordination.cpython-314.pyc +0 -0
  266. package/src/__pycache__/tools_credentials.cpython-314.pyc +0 -0
  267. package/src/__pycache__/tools_learnings.cpython-314.pyc +0 -0
  268. package/src/__pycache__/tools_menu.cpython-314.pyc +0 -0
  269. package/src/__pycache__/tools_reminders.cpython-314.pyc +0 -0
  270. package/src/__pycache__/tools_reminders_crud.cpython-314.pyc +0 -0
  271. package/src/__pycache__/tools_sessions.cpython-314.pyc +0 -0
  272. package/src/__pycache__/tools_task_history.cpython-314.pyc +0 -0
  273. package/src/cognitive/__pycache__/__init__.cpython-314.pyc +0 -0
  274. package/src/cognitive/__pycache__/_core.cpython-314.pyc +0 -0
  275. package/src/cognitive/__pycache__/_decay.cpython-314.pyc +0 -0
  276. package/src/cognitive/__pycache__/_ingest.cpython-314.pyc +0 -0
  277. package/src/cognitive/__pycache__/_memory.cpython-314.pyc +0 -0
  278. package/src/cognitive/__pycache__/_search.cpython-314.pyc +0 -0
  279. package/src/cognitive/__pycache__/_trust.cpython-314.pyc +0 -0
  280. package/src/dashboard/__pycache__/__init__.cpython-314.pyc +0 -0
  281. package/src/dashboard/__pycache__/app.cpython-314.pyc +0 -0
  282. package/src/hooks/__pycache__/auto_capture.cpython-310.pyc +0 -0
  283. package/src/hooks/__pycache__/auto_capture.cpython-314.pyc +0 -0
  284. package/src/plugins/__pycache__/__init__.cpython-314.pyc +0 -0
  285. package/src/plugins/__pycache__/adaptive_mode.cpython-314.pyc +0 -0
  286. package/src/plugins/__pycache__/agents.cpython-314.pyc +0 -0
  287. package/src/plugins/__pycache__/artifact_registry.cpython-314.pyc +0 -0
  288. package/src/plugins/__pycache__/backup.cpython-314.pyc +0 -0
  289. package/src/plugins/__pycache__/cognitive_memory.cpython-314.pyc +0 -0
  290. package/src/plugins/__pycache__/core_rules.cpython-314.pyc +0 -0
  291. package/src/plugins/__pycache__/cortex.cpython-314.pyc +0 -0
  292. package/src/plugins/__pycache__/entities.cpython-314.pyc +0 -0
  293. package/src/plugins/__pycache__/episodic_memory.cpython-314.pyc +0 -0
  294. package/src/plugins/__pycache__/evolution.cpython-314.pyc +0 -0
  295. package/src/plugins/__pycache__/guard.cpython-314.pyc +0 -0
  296. package/src/plugins/__pycache__/knowledge_graph_tools.cpython-314.pyc +0 -0
  297. package/src/plugins/__pycache__/preferences.cpython-314.pyc +0 -0
  298. package/src/rules/__pycache__/__init__.cpython-310.pyc +0 -0
  299. package/src/rules/__pycache__/__init__.cpython-314.pyc +0 -0
  300. package/src/rules/__pycache__/migrate.cpython-310.pyc +0 -0
  301. package/src/rules/__pycache__/migrate.cpython-314.pyc +0 -0
  302. package/src/scripts/__pycache__/check-context.cpython-310.pyc +0 -0
  303. package/src/scripts/__pycache__/check-context.cpython-314.pyc +0 -0
  304. package/src/scripts/__pycache__/nexo-auto-update.cpython-310.pyc +0 -0
  305. package/src/scripts/__pycache__/nexo-auto-update.cpython-314.pyc +0 -0
  306. package/src/scripts/__pycache__/nexo-catchup.cpython-310.pyc +0 -0
  307. package/src/scripts/__pycache__/nexo-catchup.cpython-314.pyc +0 -0
  308. package/src/scripts/__pycache__/nexo-cognitive-decay.cpython-310.pyc +0 -0
  309. package/src/scripts/__pycache__/nexo-cognitive-decay.cpython-314.pyc +0 -0
  310. package/src/scripts/__pycache__/nexo-daily-self-audit.cpython-310.pyc +0 -0
  311. package/src/scripts/__pycache__/nexo-daily-self-audit.cpython-314.pyc +0 -0
  312. package/src/scripts/__pycache__/nexo-evolution-run.cpython-310.pyc +0 -0
  313. package/src/scripts/__pycache__/nexo-evolution-run.cpython-314.pyc +0 -0
  314. package/src/scripts/__pycache__/nexo-followup-hygiene.cpython-310.pyc +0 -0
  315. package/src/scripts/__pycache__/nexo-followup-hygiene.cpython-314.pyc +0 -0
  316. package/src/scripts/__pycache__/nexo-github-monitor.cpython-310.pyc +0 -0
  317. package/src/scripts/__pycache__/nexo-github-monitor.cpython-314.pyc +0 -0
  318. package/src/scripts/__pycache__/nexo-immune.cpython-310.pyc +0 -0
  319. package/src/scripts/__pycache__/nexo-immune.cpython-314.pyc +0 -0
  320. package/src/scripts/__pycache__/nexo-install.cpython-310.pyc +0 -0
  321. package/src/scripts/__pycache__/nexo-install.cpython-314.pyc +0 -0
  322. package/src/scripts/__pycache__/nexo-learning-housekeep.cpython-310.pyc +0 -0
  323. package/src/scripts/__pycache__/nexo-learning-housekeep.cpython-314.pyc +0 -0
  324. package/src/scripts/__pycache__/nexo-learning-validator.cpython-310.pyc +0 -0
  325. package/src/scripts/__pycache__/nexo-learning-validator.cpython-314.pyc +0 -0
  326. package/src/scripts/__pycache__/nexo-migrate.cpython-310.pyc +0 -0
  327. package/src/scripts/__pycache__/nexo-migrate.cpython-314.pyc +0 -0
  328. package/src/scripts/__pycache__/nexo-postmortem-consolidator.cpython-310.pyc +0 -0
  329. package/src/scripts/__pycache__/nexo-postmortem-consolidator.cpython-314.pyc +0 -0
  330. package/src/scripts/__pycache__/nexo-pre-commit.cpython-310.pyc +0 -0
  331. package/src/scripts/__pycache__/nexo-pre-commit.cpython-314.pyc +0 -0
  332. package/src/scripts/__pycache__/nexo-proactive-dashboard.cpython-310.pyc +0 -0
  333. package/src/scripts/__pycache__/nexo-proactive-dashboard.cpython-314.pyc +0 -0
  334. package/src/scripts/__pycache__/nexo-reflection.cpython-310.pyc +0 -0
  335. package/src/scripts/__pycache__/nexo-reflection.cpython-314.pyc +0 -0
  336. package/src/scripts/__pycache__/nexo-runtime-preflight.cpython-310.pyc +0 -0
  337. package/src/scripts/__pycache__/nexo-runtime-preflight.cpython-314.pyc +0 -0
  338. package/src/scripts/__pycache__/nexo-send-email.cpython-310.pyc +0 -0
  339. package/src/scripts/__pycache__/nexo-send-email.cpython-314.pyc +0 -0
  340. package/src/scripts/__pycache__/nexo-send-reply.cpython-310.pyc +0 -0
  341. package/src/scripts/__pycache__/nexo-send-reply.cpython-314.pyc +0 -0
  342. package/src/scripts/__pycache__/nexo-sleep.cpython-310.pyc +0 -0
  343. package/src/scripts/__pycache__/nexo-sleep.cpython-314.pyc +0 -0
  344. package/src/scripts/__pycache__/nexo-synthesis.cpython-310.pyc +0 -0
  345. package/src/scripts/__pycache__/nexo-synthesis.cpython-314.pyc +0 -0
  346. package/src/scripts/__pycache__/nexo-watchdog-smoke.cpython-310.pyc +0 -0
  347. package/src/scripts/__pycache__/nexo-watchdog-smoke.cpython-314.pyc +0 -0
  348. package/src/scripts/deep-sleep/__pycache__/analyze_session.cpython-310.pyc +0 -0
  349. package/src/scripts/deep-sleep/__pycache__/analyze_session.cpython-314.pyc +0 -0
  350. package/src/scripts/deep-sleep/__pycache__/apply_findings.cpython-310.pyc +0 -0
  351. package/src/scripts/deep-sleep/__pycache__/apply_findings.cpython-314.pyc +0 -0
  352. package/src/scripts/deep-sleep/__pycache__/collect_transcripts.cpython-310.pyc +0 -0
  353. package/src/scripts/deep-sleep/__pycache__/collect_transcripts.cpython-314.pyc +0 -0
  354. package/src/scripts/deep-sleep/analyze_session.py +0 -217
  355. package/src/scripts/deep-sleep/collect_transcripts.py +0 -145
  356. package/src/scripts/deep-sleep/prompt.md +0 -109
  357. package/tests/__pycache__/__init__.cpython-310.pyc +0 -0
  358. package/tests/__pycache__/__init__.cpython-314.pyc +0 -0
  359. package/tests/__pycache__/conftest.cpython-310-pytest-9.0.2.pyc +0 -0
  360. package/tests/__pycache__/conftest.cpython-310.pyc +0 -0
  361. package/tests/__pycache__/conftest.cpython-314-pytest-9.0.2.pyc +0 -0
  362. package/tests/__pycache__/test_cognitive.cpython-310-pytest-9.0.2.pyc +0 -0
  363. package/tests/__pycache__/test_cognitive.cpython-310.pyc +0 -0
  364. package/tests/__pycache__/test_cognitive.cpython-314-pytest-9.0.2.pyc +0 -0
  365. package/tests/__pycache__/test_knowledge_graph.cpython-310-pytest-9.0.2.pyc +0 -0
  366. package/tests/__pycache__/test_knowledge_graph.cpython-310.pyc +0 -0
  367. package/tests/__pycache__/test_knowledge_graph.cpython-314-pytest-9.0.2.pyc +0 -0
  368. package/tests/__pycache__/test_migrations.cpython-310-pytest-9.0.2.pyc +0 -0
  369. package/tests/__pycache__/test_migrations.cpython-310.pyc +0 -0
  370. package/tests/__pycache__/test_migrations.cpython-314-pytest-9.0.2.pyc +0 -0
@@ -0,0 +1,464 @@
1
+ """NEXO Cognitive — Trust scoring, sentiment, dissonance."""
2
+ import re
3
+ import numpy as np
4
+ from datetime import datetime, timedelta
5
+ from cognitive._core import _get_db, embed, cosine_similarity, _blob_to_array
6
+ from cognitive._core import POSITIVE_SIGNALS, NEGATIVE_SIGNALS, URGENCY_SIGNALS
7
+
8
+
9
+ # Trust score events — default deltas (overridable via trust_event_config table)
10
+ _DEFAULT_TRUST_EVENTS = {
11
+ # Positive
12
+ "explicit_thanks": +3,
13
+ "delegation": +2, # user delegates new task without micromanaging
14
+ "paradigm_shift": +2, # user teaches, NEXO learns
15
+ "sibling_detected": +3, # NEXO avoided context error on its own
16
+ "proactive_action": +2, # NEXO did something useful without being asked
17
+ # Negative
18
+ "correction": -3, # user corrects NEXO
19
+ "repeated_error": -7, # Error on something NEXO already had a learning for
20
+ "override": -5, # NEXO's memory was wrong
21
+ "correction_fatigue": -10, # Same memory corrected 3+ times
22
+ "forgot_followup": -4, # Forgot to mark followup or execute it
23
+ }
24
+
25
+ # Lazy-loaded from DB (trust_event_config table overrides defaults)
26
+ _trust_events_cache = None
27
+ _trust_events_cache_ts = 0
28
+
29
+
30
+ def get_trust_events() -> dict:
31
+ """Get trust events with deltas. DB overrides take priority over defaults."""
32
+ global _trust_events_cache, _trust_events_cache_ts
33
+ import time
34
+ now = time.time()
35
+ # Cache for 60s to avoid constant DB reads
36
+ if _trust_events_cache is not None and (now - _trust_events_cache_ts) < 60:
37
+ return _trust_events_cache
38
+
39
+ events = dict(_DEFAULT_TRUST_EVENTS)
40
+ try:
41
+ db = _get_db()
42
+ db.execute("""
43
+ CREATE TABLE IF NOT EXISTS trust_event_config (
44
+ event TEXT PRIMARY KEY,
45
+ delta REAL NOT NULL,
46
+ description TEXT DEFAULT '',
47
+ updated_at TEXT DEFAULT (datetime('now'))
48
+ )
49
+ """)
50
+ rows = db.execute("SELECT event, delta FROM trust_event_config").fetchall()
51
+ for r in rows:
52
+ events[r[0]] = r[1]
53
+ except Exception:
54
+ pass
55
+ _trust_events_cache = events
56
+ _trust_events_cache_ts = now
57
+ return events
58
+
59
+ # For backward compat — code that reads TRUST_EVENTS directly
60
+ TRUST_EVENTS = _DEFAULT_TRUST_EVENTS
61
+
62
+ # Auto-detection patterns for trust events from user text
63
+ # Each pattern: (event_name, keywords/phrases that trigger it, min_matches)
64
+ TRUST_AUTO_PATTERNS = {
65
+ "explicit_thanks": {
66
+ "patterns": [
67
+ "gracias", "buen trabajo", "bien hecho", "perfecto", "genial",
68
+ "excelente", "fenomenal", "great job", "nice work", "thank",
69
+ "thanks", "awesome", "amazing", "love it", "me encanta",
70
+ ],
71
+ "min_matches": 1,
72
+ },
73
+ "correction": {
74
+ "patterns": [
75
+ "ya te dije", "ya te lo dije", "otra vez", "te he dicho",
76
+ "no es así", "eso no", "mal", "incorrecto", "equivocado",
77
+ "no no no", "that's wrong", "te aviso", "te avisé",
78
+ "2ª vez", "segunda vez", "te lo repito",
79
+ ],
80
+ "min_matches": 1,
81
+ },
82
+ "repeated_error": {
83
+ "patterns": [
84
+ "otra vez lo mismo", "siempre igual", "ya te lo dije antes",
85
+ "cuántas veces", "no aprendes", "same mistake", "again the same",
86
+ "ya van", "es la 2", "es la 3", "ya te avisé",
87
+ ],
88
+ "min_matches": 1,
89
+ },
90
+ "delegation": {
91
+ "patterns": [
92
+ "encárgate", "hazlo tú", "dale tú", "te lo dejo",
93
+ "manéjalo", "resuélvelo", "handle it", "take care of",
94
+ "you decide", "tú decides", "lo que veas", "como veas",
95
+ ],
96
+ "min_matches": 1,
97
+ },
98
+ }
99
+
100
+
101
+ def auto_detect_trust_events(text: str) -> list[dict]:
102
+ """Detect trust events from user text. Returns list of {event, delta, reason}.
103
+
104
+ Called automatically by heartbeat. Only fires once per event per heartbeat
105
+ to avoid double-counting.
106
+ """
107
+ if not text or len(text.strip()) < 5:
108
+ return []
109
+
110
+ text_lower = text.lower()
111
+ events = get_trust_events()
112
+ detected = []
113
+
114
+ for event_name, config in TRUST_AUTO_PATTERNS.items():
115
+ matches = [p for p in config["patterns"] if p in text_lower]
116
+ if len(matches) >= config["min_matches"]:
117
+ delta = events.get(event_name, _DEFAULT_TRUST_EVENTS.get(event_name, 0))
118
+ detected.append({
119
+ "event": event_name,
120
+ "delta": delta,
121
+ "reason": f"auto-detected: {', '.join(matches[:3])}",
122
+ })
123
+
124
+ # Priority: if repeated_error detected, remove correction (it's a superset)
125
+ event_names = {d["event"] for d in detected}
126
+ if "repeated_error" in event_names and "correction" in event_names:
127
+ detected = [d for d in detected if d["event"] != "correction"]
128
+ # If explicit_thanks and delegation both detected, keep both (they're independent)
129
+
130
+ return detected
131
+
132
+ def detect_dissonance(new_instruction: str, min_score: float = 0.65) -> list[dict]:
133
+ """Detect cognitive dissonance: find LTM memories that contradict a new instruction.
134
+
135
+ When user gives a new instruction that conflicts with established LTM memories
136
+ (strength > 0.8), this function surfaces the conflict so NEXO can verbalize it
137
+ rather than silently obeying or silently resisting.
138
+
139
+ Args:
140
+ new_instruction: The new instruction or preference from user
141
+ min_score: Minimum cosine similarity to consider as potential conflict
142
+
143
+ Returns:
144
+ List of conflicting memories with their strength and content
145
+ """
146
+ db = _get_db()
147
+ query_vec = embed(new_instruction[:500])
148
+ if np.linalg.norm(query_vec) == 0:
149
+ return []
150
+
151
+ rows = db.execute(
152
+ "SELECT id, content, embedding, source_type, domain, strength, access_count FROM ltm_memories WHERE is_dormant = 0 AND strength > 0.8"
153
+ ).fetchall()
154
+
155
+ conflicts = []
156
+ for row in rows:
157
+ vec = _blob_to_array(row["embedding"])
158
+ score = cosine_similarity(query_vec, vec)
159
+ if score >= min_score:
160
+ conflicts.append({
161
+ "memory_id": row["id"],
162
+ "content": row["content"],
163
+ "source_type": row["source_type"],
164
+ "domain": row["domain"],
165
+ "strength": row["strength"],
166
+ "access_count": row["access_count"],
167
+ "similarity": round(score, 3),
168
+ })
169
+
170
+ conflicts.sort(key=lambda x: x["similarity"], reverse=True)
171
+ return conflicts[:5]
172
+
173
+
174
+ def resolve_dissonance(memory_id: int, resolution: str, context: str = "") -> str:
175
+ """Resolve a cognitive dissonance by applying user's decision.
176
+
177
+ Args:
178
+ memory_id: The LTM memory that conflicts with the new instruction
179
+ resolution: One of:
180
+ - 'paradigm_shift': user changed his mind permanently. Decay old memory,
181
+ new instruction becomes the standard.
182
+ - 'exception': This is a one-time override. Keep old memory as standard.
183
+ - 'override': Old memory was wrong. Mark as corrupted and decay to dormant.
184
+
185
+ Returns:
186
+ Status message
187
+ """
188
+ db = _get_db()
189
+ row = db.execute("SELECT * FROM ltm_memories WHERE id = ?", (memory_id,)).fetchone()
190
+ if not row:
191
+ return f"Memory #{memory_id} not found."
192
+
193
+ now = datetime.utcnow().isoformat()
194
+
195
+ if resolution == "paradigm_shift":
196
+ # Instant decay to 0.3, will naturally fade. New instruction takes over.
197
+ db.execute(
198
+ "UPDATE ltm_memories SET strength = 0.3, last_accessed = ? WHERE id = ?",
199
+ (now, memory_id)
200
+ )
201
+ msg = f"Paradigm shift: Memory #{memory_id} decayed to 0.3. New standard will replace it."
202
+
203
+ elif resolution == "exception":
204
+ # Keep memory as-is, just log the exception
205
+ msg = f"Exception noted: Memory #{memory_id} remains standard. One-time override applied."
206
+
207
+ elif resolution == "override":
208
+ # Memory was wrong — mark as corrupted/dormant
209
+ db.execute(
210
+ "UPDATE ltm_memories SET strength = 0.05, is_dormant = 1, last_accessed = ? WHERE id = ?",
211
+ (now, memory_id)
212
+ )
213
+ msg = f"Override: Memory #{memory_id} marked corrupted and dormant."
214
+
215
+ else:
216
+ return f"Unknown resolution: {resolution}. Use 'paradigm_shift', 'exception', or 'override'."
217
+
218
+ # Log the correction
219
+ db.execute(
220
+ "INSERT INTO memory_corrections (memory_id, store, correction_type, context) VALUES (?, 'ltm', ?, ?)",
221
+ (memory_id, resolution, context[:500])
222
+ )
223
+ db.commit()
224
+
225
+ return msg
226
+
227
+
228
+ def check_correction_fatigue() -> list[dict]:
229
+ """Find memories corrected 3+ times in the last 7 days — mark as 'under review'.
230
+
231
+ These memories are unreliable: user keeps overriding them, suggesting
232
+ the memory itself may be wrong or outdated.
233
+
234
+ Returns:
235
+ List of memories that should be flagged as unreliable
236
+ """
237
+ db = _get_db()
238
+ cutoff = (datetime.utcnow() - timedelta(days=7)).isoformat()
239
+
240
+ rows = db.execute("""
241
+ SELECT memory_id, COUNT(*) as correction_count,
242
+ GROUP_CONCAT(correction_type) as types
243
+ FROM memory_corrections
244
+ WHERE created_at >= ? AND store = 'ltm'
245
+ GROUP BY memory_id
246
+ HAVING COUNT(*) >= 3
247
+ """, (cutoff,)).fetchall()
248
+
249
+ fatigued = []
250
+ for row in rows:
251
+ mem = db.execute(
252
+ "SELECT content, strength, source_type, domain FROM ltm_memories WHERE id = ?",
253
+ (row["memory_id"],)
254
+ ).fetchone()
255
+ if mem:
256
+ fatigued.append({
257
+ "memory_id": row["memory_id"],
258
+ "corrections_7d": row["correction_count"],
259
+ "types": row["types"],
260
+ "content": mem["content"][:200],
261
+ "strength": mem["strength"],
262
+ "source_type": mem["source_type"],
263
+ "domain": mem["domain"],
264
+ })
265
+
266
+ # Auto-mark as under review: decay strength to 0.2
267
+ db.execute(
268
+ "UPDATE ltm_memories SET strength = MIN(strength, 0.2), tags = CASE WHEN tags LIKE '%under_review%' THEN tags ELSE tags || ',under_review' END WHERE id = ?",
269
+ (row["memory_id"],)
270
+ )
271
+
272
+ if fatigued:
273
+ db.commit()
274
+
275
+ return fatigued
276
+
277
+ def detect_sentiment(text: str) -> dict:
278
+ """Analyze user's text for sentiment signals.
279
+
280
+ Returns detected sentiment, intensity, and action guidance for NEXO.
281
+ Not a model — keyword + heuristic based. Fast and deterministic.
282
+ """
283
+ if not text:
284
+ return {"sentiment": "neutral", "intensity": 0.5, "signals": [], "guidance": ""}
285
+
286
+ text_lower = text.lower()
287
+ words = set(text_lower.split())
288
+
289
+ positive_hits = [s for s in POSITIVE_SIGNALS if s in text_lower]
290
+ negative_hits = [s for s in NEGATIVE_SIGNALS if s in text_lower]
291
+ urgency_hits = [s for s in URGENCY_SIGNALS if s in text_lower]
292
+
293
+ # Heuristics
294
+ is_short = len(text) < 30
295
+ has_caps = any(c.isupper() for c in text[1:]) if len(text) > 1 else False # ignore first char
296
+ has_exclamation = "!" in text
297
+ all_caps_words = sum(1 for w in text.split() if w.isupper() and len(w) > 1)
298
+
299
+ # Score
300
+ pos_score = len(positive_hits)
301
+ neg_score = len(negative_hits)
302
+
303
+ # Caps/short boost negative
304
+ if all_caps_words >= 2:
305
+ neg_score += 2
306
+ if is_short and neg_score > 0:
307
+ neg_score += 1 # Short + negative = terse frustration
308
+
309
+ if urgency_hits:
310
+ neg_score += 1 # Urgency often means something is wrong
311
+
312
+ # Determine sentiment
313
+ if neg_score > pos_score and neg_score >= 1:
314
+ sentiment = "negative"
315
+ intensity = min(1.0, 0.3 + neg_score * 0.15)
316
+ if intensity > 0.7:
317
+ guidance = "MODE: Ultra-concise. Zero explanations. Solve and show result."
318
+ else:
319
+ guidance = "MODE: Concise. Less context, more direct action."
320
+ elif pos_score > neg_score and pos_score >= 1:
321
+ sentiment = "positive"
322
+ intensity = min(1.0, 0.3 + pos_score * 0.15)
323
+ guidance = "MODE: Normal. Good time to suggest backlog ideas or improvements."
324
+ elif urgency_hits:
325
+ sentiment = "urgent"
326
+ intensity = 0.8
327
+ guidance = "MODE: Immediate action. No preambles."
328
+ else:
329
+ sentiment = "neutral"
330
+ intensity = 0.5
331
+ guidance = ""
332
+
333
+ return {
334
+ "sentiment": sentiment,
335
+ "intensity": round(intensity, 2),
336
+ "signals": positive_hits + negative_hits + urgency_hits,
337
+ "guidance": guidance,
338
+ }
339
+
340
+
341
+ def log_sentiment(text: str) -> dict:
342
+ """Detect and log user's sentiment. Returns the detection result."""
343
+ result = detect_sentiment(text)
344
+ if result["sentiment"] != "neutral":
345
+ db = _get_db()
346
+ db.execute(
347
+ "INSERT INTO sentiment_log (sentiment, intensity, signals) VALUES (?, ?, ?)",
348
+ (result["sentiment"], result["intensity"], ",".join(result["signals"]))
349
+ )
350
+ db.commit()
351
+ return result
352
+
353
+
354
+ def get_trust_score() -> float:
355
+ """Get current trust score. Starts at 50, range 0-100."""
356
+ db = _get_db()
357
+ row = db.execute("SELECT score FROM trust_score ORDER BY id DESC LIMIT 1").fetchone()
358
+ if row is None:
359
+ # Initialize
360
+ db.execute(
361
+ "INSERT INTO trust_score (score, event, delta, context) VALUES (50, 'init', 0, 'Initial trust score')"
362
+ )
363
+ db.commit()
364
+ return 50.0
365
+ return row[0]
366
+
367
+
368
+ def _annotate_adaptive_log(event: str, delta: float):
369
+ """Retroactively annotate the most recent adaptive_log entry with trust feedback."""
370
+ try:
371
+ from db import get_db
372
+ conn = get_db()
373
+ conn.execute(
374
+ "UPDATE adaptive_log SET feedback_event = ?, feedback_delta = ?, "
375
+ "feedback_ts = datetime('now') "
376
+ "WHERE id = (SELECT id FROM adaptive_log "
377
+ "WHERE feedback_event IS NULL "
378
+ "AND timestamp >= datetime('now', '-5 minutes') "
379
+ "ORDER BY id DESC LIMIT 1)",
380
+ (event, int(delta))
381
+ )
382
+ conn.commit()
383
+ except Exception:
384
+ pass
385
+
386
+
387
+ def adjust_trust(event: str, context: str = "", custom_delta: float = None) -> dict:
388
+ """Adjust trust score based on an event.
389
+
390
+ Args:
391
+ event: Event type from TRUST_EVENTS or custom
392
+ context: Description of what happened
393
+ custom_delta: Override the default point value
394
+
395
+ Returns:
396
+ Dict with old_score, delta, new_score, event
397
+ """
398
+ db = _get_db()
399
+ old_score = get_trust_score()
400
+
401
+ events = get_trust_events()
402
+ delta = custom_delta if custom_delta is not None else events.get(event, 0)
403
+ if delta == 0 and custom_delta is None:
404
+ return {"old_score": old_score, "delta": 0, "new_score": old_score, "event": event, "error": "unknown event"}
405
+
406
+ new_score = max(0.0, min(100.0, old_score + delta))
407
+
408
+ db.execute(
409
+ "INSERT INTO trust_score (score, event, delta, context) VALUES (?, ?, ?, ?)",
410
+ (new_score, event, delta, context[:500])
411
+ )
412
+ db.commit()
413
+
414
+ # Annotate adaptive log for learned weights
415
+ _annotate_adaptive_log(event, delta)
416
+
417
+ # Somatic event logging for repeated_error events (append-only in nexo.db)
418
+ if event == "repeated_error" and context:
419
+ try:
420
+ from db import get_db as get_nexo_db
421
+ area = context.split(":")[0].strip() if ":" in context else "unknown"
422
+ get_nexo_db().execute(
423
+ "INSERT INTO somatic_events (target, target_type, event_type, delta, source) VALUES (?, ?, ?, ?, ?)",
424
+ (area, "area", "repeated_error", 0.20, f"trust:{event}")
425
+ )
426
+ get_nexo_db().commit()
427
+ except Exception:
428
+ pass
429
+
430
+ return {
431
+ "old_score": round(old_score, 1),
432
+ "delta": delta,
433
+ "new_score": round(new_score, 1),
434
+ "event": event,
435
+ }
436
+
437
+
438
+ def get_trust_history(days: int = 7) -> dict:
439
+ """Get trust score history and sentiment summary."""
440
+ db = _get_db()
441
+ cutoff = (datetime.utcnow() - timedelta(days=days)).isoformat()
442
+
443
+ # Trust events
444
+ events = db.execute(
445
+ "SELECT event, delta, score, context, created_at FROM trust_score WHERE created_at >= ? ORDER BY id",
446
+ (cutoff,)
447
+ ).fetchall()
448
+
449
+ # Sentiment distribution
450
+ sentiments = db.execute(
451
+ "SELECT sentiment, COUNT(*) as cnt, AVG(intensity) as avg_int FROM sentiment_log WHERE created_at >= ? GROUP BY sentiment",
452
+ (cutoff,)
453
+ ).fetchall()
454
+
455
+ current = get_trust_score()
456
+ start_score = events[0]["score"] - events[0]["delta"] if events else current
457
+
458
+ return {
459
+ "current_score": round(current, 1),
460
+ "period_start_score": round(start_score, 1),
461
+ "net_change": round(current - start_score, 1),
462
+ "events": [{"event": e["event"], "delta": e["delta"], "score": round(e["score"], 1), "context": e["context"][:100], "at": e["created_at"]} for e in events],
463
+ "sentiment_distribution": {s["sentiment"]: {"count": s["cnt"], "avg_intensity": round(s["avg_int"], 2)} for s in sentiments},
464
+ }
@@ -9,11 +9,14 @@ from cognitive._core import POSITIVE_SIGNALS, NEGATIVE_SIGNALS, URGENCY_SIGNALS
9
9
  # Trust score events — default deltas (overridable via trust_event_config table)
10
10
  _DEFAULT_TRUST_EVENTS = {
11
11
  # Positive
12
- "explicit_thanks": +3,
12
+ "explicit_thanks": +5,
13
13
  "delegation": +2, # user delegates new task without micromanaging
14
14
  "paradigm_shift": +2, # user teaches, NEXO learns
15
15
  "sibling_detected": +3, # NEXO avoided context error on its own
16
16
  "proactive_action": +2, # NEXO did something useful without being asked
17
+ "task_completed": +1, # followup/task completed successfully
18
+ "session_productive": +2, # session with real work done, no corrections
19
+ "clean_deploy": +1, # code deployed without lint errors or rollbacks
17
20
  # Negative
18
21
  "correction": -3, # user corrects NEXO
19
22
  "repeated_error": -7, # Error on something NEXO already had a learning for
@@ -61,41 +64,12 @@ TRUST_EVENTS = _DEFAULT_TRUST_EVENTS
61
64
 
62
65
  # Auto-detection patterns for trust events from user text
63
66
  # Each pattern: (event_name, keywords/phrases that trigger it, min_matches)
64
- TRUST_AUTO_PATTERNS = {
65
- "explicit_thanks": {
66
- "patterns": [
67
- "gracias", "buen trabajo", "bien hecho", "perfecto", "genial",
68
- "excelente", "fenomenal", "great job", "nice work", "thank",
69
- "thanks", "awesome", "amazing", "love it", "me encanta",
70
- ],
71
- "min_matches": 1,
72
- },
73
- "correction": {
74
- "patterns": [
75
- "ya te dije", "ya te lo dije", "otra vez", "te he dicho",
76
- "no es así", "eso no", "mal", "incorrecto", "equivocado",
77
- "no no no", "that's wrong", "te aviso", "te avisé",
78
- "2ª vez", "segunda vez", "te lo repito",
79
- ],
80
- "min_matches": 1,
81
- },
82
- "repeated_error": {
83
- "patterns": [
84
- "otra vez lo mismo", "siempre igual", "ya te lo dije antes",
85
- "cuántas veces", "no aprendes", "same mistake", "again the same",
86
- "ya van", "es la 2", "es la 3", "ya te avisé",
87
- ],
88
- "min_matches": 1,
89
- },
90
- "delegation": {
91
- "patterns": [
92
- "encárgate", "hazlo tú", "dale tú", "te lo dejo",
93
- "manéjalo", "resuélvelo", "handle it", "take care of",
94
- "you decide", "tú decides", "lo que veas", "como veas",
95
- ],
96
- "min_matches": 1,
97
- },
98
- }
67
+ TRUST_AUTO_PATTERNS = {}
68
+ # NOTE: Auto-detection via keyword patterns has been REMOVED.
69
+ # Trust events are now detected in two ways:
70
+ # 1. The LLM emits them during sessions (language-agnostic, via MCP instructions)
71
+ # 2. Deep Sleep calibrates the daily score holistically (Phase 7 in synthesis)
72
+ # The old keyword patterns only worked in Spanish/English and missed most signals.
99
73
 
100
74
 
101
75
  def auto_detect_trust_events(text: str) -> list[dict]:
@@ -0,0 +1,106 @@
1
+ {
2
+ "$schema": "NEXO cron manifest — synced by nexo_update to LaunchAgents (macOS) or systemd timers (Linux)",
3
+ "version": 2,
4
+ "crons": [
5
+ {
6
+ "id": "deep-sleep",
7
+ "script": "scripts/nexo-deep-sleep.sh",
8
+ "type": "shell",
9
+ "schedule": {"hour": 4, "minute": 30},
10
+ "description": "Overnight session analysis — 4 phases: collect, extract, synthesize, apply",
11
+ "core": true
12
+ },
13
+ {
14
+ "id": "sleep",
15
+ "script": "scripts/nexo-sleep.py",
16
+ "schedule": {"hour": 4, "minute": 0},
17
+ "description": "Nightly memory consolidation and dream cycle",
18
+ "core": true
19
+ },
20
+ {
21
+ "id": "cognitive-decay",
22
+ "script": "scripts/nexo-cognitive-decay.py",
23
+ "schedule": {"hour": 3, "minute": 0},
24
+ "description": "Memory decay — reduce strength of unaccessed memories",
25
+ "core": true
26
+ },
27
+ {
28
+ "id": "learning-housekeep",
29
+ "script": "scripts/nexo-learning-housekeep.py",
30
+ "schedule": {"hour": 3, "minute": 15},
31
+ "description": "Archive stale learnings, deduplicate, validate",
32
+ "core": true
33
+ },
34
+ {
35
+ "id": "immune",
36
+ "script": "scripts/nexo-immune.py",
37
+ "interval_seconds": 1800,
38
+ "description": "Health monitor — checks MCP, DB, services, auto-repairs",
39
+ "core": true
40
+ },
41
+ {
42
+ "id": "watchdog",
43
+ "script": "scripts/nexo-watchdog.sh",
44
+ "type": "shell",
45
+ "interval_seconds": 1800,
46
+ "description": "System health checks — snapshots, logs, alerts",
47
+ "core": true
48
+ },
49
+ {
50
+ "id": "self-audit",
51
+ "script": "scripts/nexo-daily-self-audit.py",
52
+ "schedule": {"hour": 7, "minute": 0},
53
+ "description": "Daily self-audit — validates learnings, protocols, drift",
54
+ "core": true
55
+ },
56
+ {
57
+ "id": "postmortem",
58
+ "script": "scripts/nexo-postmortem-consolidator.py",
59
+ "schedule": {"hour": 23, "minute": 30},
60
+ "description": "Consolidate session post-mortems into patterns",
61
+ "core": true
62
+ },
63
+ {
64
+ "id": "evolution",
65
+ "script": "scripts/nexo-evolution-run.py",
66
+ "schedule": {"hour": 5, "minute": 0, "weekday": 0},
67
+ "description": "Weekly self-improvement cycle — propose and evaluate changes",
68
+ "core": true
69
+ },
70
+ {
71
+ "id": "followup-hygiene",
72
+ "script": "scripts/nexo-followup-hygiene.py",
73
+ "schedule": {"hour": 5, "minute": 0},
74
+ "description": "Clean stale followups, archive completed, validate dates",
75
+ "core": true
76
+ },
77
+ {
78
+ "id": "synthesis",
79
+ "script": "scripts/nexo-synthesis.py",
80
+ "interval_seconds": 7200,
81
+ "description": "Periodic synthesis — cross-reference learnings, decisions, changes",
82
+ "core": true
83
+ },
84
+ {
85
+ "id": "auto-close-sessions",
86
+ "script": "scripts/nexo-auto-close-sessions.py",
87
+ "interval_seconds": 300,
88
+ "description": "Close stale sessions that lost their parent process",
89
+ "core": true
90
+ },
91
+ {
92
+ "id": "github-monitor",
93
+ "script": "scripts/nexo-github-monitor.py",
94
+ "schedule": {"hour": 8, "minute": 0},
95
+ "description": "Monitor GitHub repo — issues, PRs, stars, auto-respond",
96
+ "core": true
97
+ },
98
+ {
99
+ "id": "catchup",
100
+ "script": "scripts/nexo-catchup.py",
101
+ "schedule": {"hour": 8, "minute": 30},
102
+ "description": "Morning catchup briefing for the user",
103
+ "core": true
104
+ }
105
+ ]
106
+ }