@monoes/monomindcli 2.16.12 → 2.16.14

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 (386) hide show
  1. package/.claude/agents/core/coder.md +1 -1
  2. package/.claude/agents/engineering/engineering-devops-automator.md +1 -1
  3. package/.claude/agents/github/repo-architect.md +1 -1
  4. package/.claude/agents/testing/production-validator.md +1 -1
  5. package/.claude/agents/testing/testing-tool-evaluator.md +1 -1
  6. package/.claude/commands/github/pr-manager.md +1 -1
  7. package/.claude/helpers/pick-rank.cjs +34 -4
  8. package/.claude/skills/monolean-audit/SKILL.md +1 -1
  9. package/README.md +1 -1
  10. package/dist/src/commands/cleanup-data.d.ts +30 -0
  11. package/dist/src/commands/cleanup-data.d.ts.map +1 -0
  12. package/dist/src/commands/cleanup-data.js +138 -0
  13. package/dist/src/commands/cleanup-data.js.map +1 -0
  14. package/dist/src/commands/cleanup-scratch.d.ts +43 -0
  15. package/dist/src/commands/cleanup-scratch.d.ts.map +1 -0
  16. package/dist/src/commands/cleanup-scratch.js +125 -0
  17. package/dist/src/commands/cleanup-scratch.js.map +1 -0
  18. package/dist/src/commands/cleanup.d.ts +2 -39
  19. package/dist/src/commands/cleanup.d.ts.map +1 -1
  20. package/dist/src/commands/cleanup.js +5 -247
  21. package/dist/src/commands/cleanup.js.map +1 -1
  22. package/dist/src/commands/doctor-gitignore-checks.d.ts +10 -0
  23. package/dist/src/commands/doctor-gitignore-checks.d.ts.map +1 -0
  24. package/dist/src/commands/doctor-gitignore-checks.js +141 -0
  25. package/dist/src/commands/doctor-gitignore-checks.js.map +1 -0
  26. package/dist/src/commands/doctor-helpers-checks.d.ts +10 -0
  27. package/dist/src/commands/doctor-helpers-checks.d.ts.map +1 -0
  28. package/dist/src/commands/doctor-helpers-checks.js +292 -0
  29. package/dist/src/commands/doctor-helpers-checks.js.map +1 -0
  30. package/dist/src/commands/doctor-memory-checks.d.ts +47 -0
  31. package/dist/src/commands/doctor-memory-checks.d.ts.map +1 -0
  32. package/dist/src/commands/doctor-memory-checks.js +298 -0
  33. package/dist/src/commands/doctor-memory-checks.js.map +1 -0
  34. package/dist/src/commands/doctor-monograph-checks.d.ts +9 -0
  35. package/dist/src/commands/doctor-monograph-checks.d.ts.map +1 -0
  36. package/dist/src/commands/doctor-monograph-checks.js +331 -0
  37. package/dist/src/commands/doctor-monograph-checks.js.map +1 -0
  38. package/dist/src/commands/doctor-project-checks.d.ts +7 -66
  39. package/dist/src/commands/doctor-project-checks.d.ts.map +1 -1
  40. package/dist/src/commands/doctor-project-checks.js +10 -1331
  41. package/dist/src/commands/doctor-project-checks.js.map +1 -1
  42. package/dist/src/commands/doctor-routing-checks.d.ts +10 -0
  43. package/dist/src/commands/doctor-routing-checks.d.ts.map +1 -0
  44. package/dist/src/commands/doctor-routing-checks.js +194 -0
  45. package/dist/src/commands/doctor-routing-checks.js.map +1 -0
  46. package/dist/src/commands/doctor-worker-checks.d.ts +17 -0
  47. package/dist/src/commands/doctor-worker-checks.d.ts.map +1 -0
  48. package/dist/src/commands/doctor-worker-checks.js +122 -0
  49. package/dist/src/commands/doctor-worker-checks.js.map +1 -0
  50. package/dist/src/commands/hooks-routing-commands.js +1 -1
  51. package/dist/src/commands/hooks-routing-commands.js.map +1 -1
  52. package/dist/src/commands/init.d.ts.map +1 -1
  53. package/dist/src/commands/init.js +6 -15
  54. package/dist/src/commands/init.js.map +1 -1
  55. package/dist/src/commands/org-control.d.ts +117 -0
  56. package/dist/src/commands/org-control.d.ts.map +1 -0
  57. package/dist/src/commands/org-control.js +274 -0
  58. package/dist/src/commands/org-control.js.map +1 -0
  59. package/dist/src/commands/org-lifecycle.d.ts +7 -0
  60. package/dist/src/commands/org-lifecycle.d.ts.map +1 -0
  61. package/dist/src/commands/org-lifecycle.js +298 -0
  62. package/dist/src/commands/org-lifecycle.js.map +1 -0
  63. package/dist/src/commands/org-manage.d.ts +7 -0
  64. package/dist/src/commands/org-manage.d.ts.map +1 -0
  65. package/dist/src/commands/org-manage.js +357 -0
  66. package/dist/src/commands/org-manage.js.map +1 -0
  67. package/dist/src/commands/org-memory-command.d.ts +3 -0
  68. package/dist/src/commands/org-memory-command.d.ts.map +1 -0
  69. package/dist/src/commands/org-memory-command.js +178 -0
  70. package/dist/src/commands/org-memory-command.js.map +1 -0
  71. package/dist/src/commands/org-observe-approvals.d.ts +8 -0
  72. package/dist/src/commands/org-observe-approvals.d.ts.map +1 -0
  73. package/dist/src/commands/org-observe-approvals.js +211 -0
  74. package/dist/src/commands/org-observe-approvals.js.map +1 -0
  75. package/dist/src/commands/org-observe-checkpoint.d.ts +26 -0
  76. package/dist/src/commands/org-observe-checkpoint.d.ts.map +1 -0
  77. package/dist/src/commands/org-observe-checkpoint.js +180 -0
  78. package/dist/src/commands/org-observe-checkpoint.js.map +1 -0
  79. package/dist/src/commands/org-observe-config.d.ts +8 -0
  80. package/dist/src/commands/org-observe-config.d.ts.map +1 -0
  81. package/dist/src/commands/org-observe-config.js +160 -0
  82. package/dist/src/commands/org-observe-config.js.map +1 -0
  83. package/dist/src/commands/org-observe-gates.d.ts +4 -0
  84. package/dist/src/commands/org-observe-gates.d.ts.map +1 -0
  85. package/dist/src/commands/org-observe-gates.js +182 -0
  86. package/dist/src/commands/org-observe-gates.js.map +1 -0
  87. package/dist/src/commands/org-observe-inbox.d.ts +18 -0
  88. package/dist/src/commands/org-observe-inbox.d.ts.map +1 -0
  89. package/dist/src/commands/org-observe-inbox.js +154 -0
  90. package/dist/src/commands/org-observe-inbox.js.map +1 -0
  91. package/dist/src/commands/org-observe-logs.d.ts +31 -0
  92. package/dist/src/commands/org-observe-logs.d.ts.map +1 -0
  93. package/dist/src/commands/org-observe-logs.js +272 -0
  94. package/dist/src/commands/org-observe-logs.js.map +1 -0
  95. package/dist/src/commands/org-observe-questions.d.ts +8 -0
  96. package/dist/src/commands/org-observe-questions.d.ts.map +1 -0
  97. package/dist/src/commands/org-observe-questions.js +201 -0
  98. package/dist/src/commands/org-observe-questions.js.map +1 -0
  99. package/dist/src/commands/org-observe-report.d.ts +8 -0
  100. package/dist/src/commands/org-observe-report.d.ts.map +1 -0
  101. package/dist/src/commands/org-observe-report.js +366 -0
  102. package/dist/src/commands/org-observe-report.js.map +1 -0
  103. package/dist/src/commands/org-observe-shared.d.ts +20 -0
  104. package/dist/src/commands/org-observe-shared.d.ts.map +1 -0
  105. package/dist/src/commands/org-observe-shared.js +55 -0
  106. package/dist/src/commands/org-observe-shared.js.map +1 -0
  107. package/dist/src/commands/org-observe.d.ts +9 -101
  108. package/dist/src/commands/org-observe.d.ts.map +1 -1
  109. package/dist/src/commands/org-observe.js +12 -1675
  110. package/dist/src/commands/org-observe.js.map +1 -1
  111. package/dist/src/commands/org-poll.d.ts +57 -0
  112. package/dist/src/commands/org-poll.d.ts.map +1 -0
  113. package/dist/src/commands/org-poll.js +194 -0
  114. package/dist/src/commands/org-poll.js.map +1 -0
  115. package/dist/src/commands/org-run.d.ts +3 -0
  116. package/dist/src/commands/org-run.d.ts.map +1 -0
  117. package/dist/src/commands/org-run.js +449 -0
  118. package/dist/src/commands/org-run.js.map +1 -0
  119. package/dist/src/commands/org-serve.d.ts +19 -0
  120. package/dist/src/commands/org-serve.d.ts.map +1 -0
  121. package/dist/src/commands/org-serve.js +395 -0
  122. package/dist/src/commands/org-serve.js.map +1 -0
  123. package/dist/src/commands/org-subcommands-config.d.ts +8 -0
  124. package/dist/src/commands/org-subcommands-config.d.ts.map +1 -0
  125. package/dist/src/commands/org-subcommands-config.js +93 -0
  126. package/dist/src/commands/org-subcommands-config.js.map +1 -0
  127. package/dist/src/commands/org-subcommands-hil.d.ts +11 -0
  128. package/dist/src/commands/org-subcommands-hil.d.ts.map +1 -0
  129. package/dist/src/commands/org-subcommands-hil.js +216 -0
  130. package/dist/src/commands/org-subcommands-hil.js.map +1 -0
  131. package/dist/src/commands/org-subcommands-observe.d.ts +12 -0
  132. package/dist/src/commands/org-subcommands-observe.d.ts.map +1 -0
  133. package/dist/src/commands/org-subcommands-observe.js +249 -0
  134. package/dist/src/commands/org-subcommands-observe.js.map +1 -0
  135. package/dist/src/commands/org-subcommands-runtime.d.ts +12 -0
  136. package/dist/src/commands/org-subcommands-runtime.d.ts.map +1 -0
  137. package/dist/src/commands/org-subcommands-runtime.js +163 -0
  138. package/dist/src/commands/org-subcommands-runtime.js.map +1 -0
  139. package/dist/src/commands/org.d.ts +3 -151
  140. package/dist/src/commands/org.d.ts.map +1 -1
  141. package/dist/src/commands/org.js +43 -2735
  142. package/dist/src/commands/org.js.map +1 -1
  143. package/dist/src/index.js +2 -2
  144. package/dist/src/index.js.map +1 -1
  145. package/dist/src/init/never-commit.d.ts +3 -3
  146. package/dist/src/init/types.d.ts +1 -1
  147. package/dist/src/init/types.js +1 -1
  148. package/dist/src/knowledge/document-store.js +1 -1
  149. package/dist/src/knowledge/document-store.js.map +1 -1
  150. package/dist/src/mcp-tools/hooks-edit-command.d.ts +10 -0
  151. package/dist/src/mcp-tools/hooks-edit-command.d.ts.map +1 -0
  152. package/dist/src/mcp-tools/hooks-edit-command.js +247 -0
  153. package/dist/src/mcp-tools/hooks-edit-command.js.map +1 -0
  154. package/dist/src/mcp-tools/hooks-learning.d.ts +9 -0
  155. package/dist/src/mcp-tools/hooks-learning.d.ts.map +1 -0
  156. package/dist/src/mcp-tools/hooks-learning.js +408 -0
  157. package/dist/src/mcp-tools/hooks-learning.js.map +1 -0
  158. package/dist/src/mcp-tools/hooks-metrics-list.d.ts +8 -0
  159. package/dist/src/mcp-tools/hooks-metrics-list.d.ts.map +1 -0
  160. package/dist/src/mcp-tools/hooks-metrics-list.js +205 -0
  161. package/dist/src/mcp-tools/hooks-metrics-list.js.map +1 -0
  162. package/dist/src/mcp-tools/hooks-route.d.ts +12 -0
  163. package/dist/src/mcp-tools/hooks-route.d.ts.map +1 -0
  164. package/dist/src/mcp-tools/hooks-route.js +251 -0
  165. package/dist/src/mcp-tools/hooks-route.js.map +1 -0
  166. package/dist/src/mcp-tools/hooks-routing.d.ts +6 -27
  167. package/dist/src/mcp-tools/hooks-routing.d.ts.map +1 -1
  168. package/dist/src/mcp-tools/hooks-routing.js +6 -1727
  169. package/dist/src/mcp-tools/hooks-routing.js.map +1 -1
  170. package/dist/src/mcp-tools/hooks-session.d.ts +9 -0
  171. package/dist/src/mcp-tools/hooks-session.d.ts.map +1 -0
  172. package/dist/src/mcp-tools/hooks-session.js +243 -0
  173. package/dist/src/mcp-tools/hooks-session.js.map +1 -0
  174. package/dist/src/mcp-tools/hooks-task.d.ts +17 -0
  175. package/dist/src/mcp-tools/hooks-task.d.ts.map +1 -0
  176. package/dist/src/mcp-tools/hooks-task.js +427 -0
  177. package/dist/src/mcp-tools/hooks-task.js.map +1 -0
  178. package/dist/src/mcp-tools/hooks-tools.d.ts +2 -1
  179. package/dist/src/mcp-tools/hooks-tools.d.ts.map +1 -1
  180. package/dist/src/mcp-tools/hooks-tools.js +2 -1
  181. package/dist/src/mcp-tools/hooks-tools.js.map +1 -1
  182. package/dist/src/mcp-tools/memory-tools.js +1 -1
  183. package/dist/src/mcp-tools/memory-tools.js.map +1 -1
  184. package/dist/src/memory/bm25-index.d.ts +2 -2
  185. package/dist/src/memory/bm25-index.js +2 -2
  186. package/dist/src/memory/embedding-operations.js +2 -2
  187. package/dist/src/memory/embedding-operations.js.map +1 -1
  188. package/dist/src/memory/entity-name-key.d.ts +1 -1
  189. package/dist/src/memory/entity-name-key.js +1 -1
  190. package/dist/src/memory/hnsw-operations.d.ts +1 -1
  191. package/dist/src/memory/hnsw-operations.js +1 -1
  192. package/dist/src/memory/memory-bridge-backend.d.ts +43 -0
  193. package/dist/src/memory/memory-bridge-backend.d.ts.map +1 -0
  194. package/dist/src/memory/memory-bridge-backend.js +363 -0
  195. package/dist/src/memory/memory-bridge-backend.js.map +1 -0
  196. package/dist/src/memory/memory-bridge-core.d.ts +42 -0
  197. package/dist/src/memory/memory-bridge-core.d.ts.map +1 -0
  198. package/dist/src/memory/memory-bridge-core.js +126 -0
  199. package/dist/src/memory/memory-bridge-core.js.map +1 -0
  200. package/dist/src/memory/memory-bridge-entries.d.ts +131 -0
  201. package/dist/src/memory/memory-bridge-entries.d.ts.map +1 -0
  202. package/dist/src/memory/memory-bridge-entries.js +227 -0
  203. package/dist/src/memory/memory-bridge-entries.js.map +1 -0
  204. package/dist/src/memory/memory-bridge-feedback.d.ts +60 -0
  205. package/dist/src/memory/memory-bridge-feedback.d.ts.map +1 -0
  206. package/dist/src/memory/memory-bridge-feedback.js +118 -0
  207. package/dist/src/memory/memory-bridge-feedback.js.map +1 -0
  208. package/dist/src/memory/memory-bridge-paths.d.ts +123 -0
  209. package/dist/src/memory/memory-bridge-paths.d.ts.map +1 -0
  210. package/dist/src/memory/memory-bridge-paths.js +335 -0
  211. package/dist/src/memory/memory-bridge-paths.js.map +1 -0
  212. package/dist/src/memory/memory-bridge-search.d.ts +48 -0
  213. package/dist/src/memory/memory-bridge-search.d.ts.map +1 -0
  214. package/dist/src/memory/memory-bridge-search.js +383 -0
  215. package/dist/src/memory/memory-bridge-search.js.map +1 -0
  216. package/dist/src/memory/memory-bridge-sessions.d.ts +38 -0
  217. package/dist/src/memory/memory-bridge-sessions.d.ts.map +1 -0
  218. package/dist/src/memory/memory-bridge-sessions.js +109 -0
  219. package/dist/src/memory/memory-bridge-sessions.js.map +1 -0
  220. package/dist/src/memory/memory-bridge-store.d.ts +58 -0
  221. package/dist/src/memory/memory-bridge-store.d.ts.map +1 -0
  222. package/dist/src/memory/memory-bridge-store.js +201 -0
  223. package/dist/src/memory/memory-bridge-store.js.map +1 -0
  224. package/dist/src/memory/memory-bridge.d.ts +10 -438
  225. package/dist/src/memory/memory-bridge.d.ts.map +1 -1
  226. package/dist/src/memory/memory-bridge.js +14 -1787
  227. package/dist/src/memory/memory-bridge.js.map +1 -1
  228. package/dist/src/memory/memory-kg-claims.d.ts +52 -0
  229. package/dist/src/memory/memory-kg-claims.d.ts.map +1 -0
  230. package/dist/src/memory/memory-kg-claims.js +99 -0
  231. package/dist/src/memory/memory-kg-claims.js.map +1 -0
  232. package/dist/src/memory/memory-kg-index.d.ts +86 -0
  233. package/dist/src/memory/memory-kg-index.d.ts.map +1 -0
  234. package/dist/src/memory/memory-kg-index.js +256 -0
  235. package/dist/src/memory/memory-kg-index.js.map +1 -0
  236. package/dist/src/memory/memory-kg-ingest.d.ts +44 -0
  237. package/dist/src/memory/memory-kg-ingest.d.ts.map +1 -0
  238. package/dist/src/memory/memory-kg-ingest.js +361 -0
  239. package/dist/src/memory/memory-kg-ingest.js.map +1 -0
  240. package/dist/src/memory/memory-kg-model.d.ts +168 -0
  241. package/dist/src/memory/memory-kg-model.d.ts.map +1 -0
  242. package/dist/src/memory/memory-kg-model.js +158 -0
  243. package/dist/src/memory/memory-kg-model.js.map +1 -0
  244. package/dist/src/memory/memory-kg-names.d.ts +64 -0
  245. package/dist/src/memory/memory-kg-names.d.ts.map +1 -0
  246. package/dist/src/memory/memory-kg-names.js +187 -0
  247. package/dist/src/memory/memory-kg-names.js.map +1 -0
  248. package/dist/src/memory/memory-kg-promote.d.ts +79 -0
  249. package/dist/src/memory/memory-kg-promote.d.ts.map +1 -0
  250. package/dist/src/memory/memory-kg-promote.js +248 -0
  251. package/dist/src/memory/memory-kg-promote.js.map +1 -0
  252. package/dist/src/memory/memory-kg-rebuild.d.ts +77 -0
  253. package/dist/src/memory/memory-kg-rebuild.d.ts.map +1 -0
  254. package/dist/src/memory/memory-kg-rebuild.js +299 -0
  255. package/dist/src/memory/memory-kg-rebuild.js.map +1 -0
  256. package/dist/src/memory/memory-kg-rollback.d.ts +47 -0
  257. package/dist/src/memory/memory-kg-rollback.d.ts.map +1 -0
  258. package/dist/src/memory/memory-kg-rollback.js +193 -0
  259. package/dist/src/memory/memory-kg-rollback.js.map +1 -0
  260. package/dist/src/memory/memory-kg-rules.d.ts +64 -0
  261. package/dist/src/memory/memory-kg-rules.d.ts.map +1 -0
  262. package/dist/src/memory/memory-kg-rules.js +251 -0
  263. package/dist/src/memory/memory-kg-rules.js.map +1 -0
  264. package/dist/src/memory/memory-kg-scan.d.ts +118 -0
  265. package/dist/src/memory/memory-kg-scan.d.ts.map +1 -0
  266. package/dist/src/memory/memory-kg-scan.js +209 -0
  267. package/dist/src/memory/memory-kg-scan.js.map +1 -0
  268. package/dist/src/memory/memory-kg-search.d.ts +80 -0
  269. package/dist/src/memory/memory-kg-search.d.ts.map +1 -0
  270. package/dist/src/memory/memory-kg-search.js +239 -0
  271. package/dist/src/memory/memory-kg-search.js.map +1 -0
  272. package/dist/src/memory/memory-kg.d.ts +19 -547
  273. package/dist/src/memory/memory-kg.d.ts.map +1 -1
  274. package/dist/src/memory/memory-kg.js +10 -2389
  275. package/dist/src/memory/memory-kg.js.map +1 -1
  276. package/dist/src/orgrt/daemon-types.d.ts +196 -0
  277. package/dist/src/orgrt/daemon-types.d.ts.map +1 -0
  278. package/dist/src/orgrt/daemon-types.js +38 -0
  279. package/dist/src/orgrt/daemon-types.js.map +1 -0
  280. package/dist/src/orgrt/daemon.d.ts +70 -300
  281. package/dist/src/orgrt/daemon.d.ts.map +1 -1
  282. package/dist/src/orgrt/daemon.js +41 -2536
  283. package/dist/src/orgrt/daemon.js.map +1 -1
  284. package/dist/src/orgrt/idle-watchdog.d.ts +39 -0
  285. package/dist/src/orgrt/idle-watchdog.d.ts.map +1 -0
  286. package/dist/src/orgrt/idle-watchdog.js +289 -0
  287. package/dist/src/orgrt/idle-watchdog.js.map +1 -0
  288. package/dist/src/orgrt/org-reload.d.ts +7 -0
  289. package/dist/src/orgrt/org-reload.d.ts.map +1 -0
  290. package/dist/src/orgrt/org-reload.js +111 -0
  291. package/dist/src/orgrt/org-reload.js.map +1 -0
  292. package/dist/src/orgrt/org-start-steps.d.ts +21 -0
  293. package/dist/src/orgrt/org-start-steps.d.ts.map +1 -0
  294. package/dist/src/orgrt/org-start-steps.js +305 -0
  295. package/dist/src/orgrt/org-start-steps.js.map +1 -0
  296. package/dist/src/orgrt/org-start.d.ts +7 -0
  297. package/dist/src/orgrt/org-start.d.ts.map +1 -0
  298. package/dist/src/orgrt/org-start.js +435 -0
  299. package/dist/src/orgrt/org-start.js.map +1 -0
  300. package/dist/src/orgrt/org-state-file.d.ts +8 -0
  301. package/dist/src/orgrt/org-state-file.d.ts.map +1 -0
  302. package/dist/src/orgrt/org-state-file.js +116 -0
  303. package/dist/src/orgrt/org-state-file.js.map +1 -0
  304. package/dist/src/orgrt/org-stop.d.ts +6 -0
  305. package/dist/src/orgrt/org-stop.d.ts.map +1 -0
  306. package/dist/src/orgrt/org-stop.js +332 -0
  307. package/dist/src/orgrt/org-stop.js.map +1 -0
  308. package/dist/src/orgrt/org-tools.d.ts +11 -0
  309. package/dist/src/orgrt/org-tools.d.ts.map +1 -0
  310. package/dist/src/orgrt/org-tools.js +305 -0
  311. package/dist/src/orgrt/org-tools.js.map +1 -0
  312. package/dist/src/orgrt/role-incarnation.d.ts +18 -0
  313. package/dist/src/orgrt/role-incarnation.d.ts.map +1 -0
  314. package/dist/src/orgrt/role-incarnation.js +374 -0
  315. package/dist/src/orgrt/role-incarnation.js.map +1 -0
  316. package/dist/src/orgrt/role-respawn.d.ts +7 -0
  317. package/dist/src/orgrt/role-respawn.d.ts.map +1 -0
  318. package/dist/src/orgrt/role-respawn.js +318 -0
  319. package/dist/src/orgrt/role-respawn.js.map +1 -0
  320. package/dist/src/orgrt/role-session-opts.d.ts +389 -0
  321. package/dist/src/orgrt/role-session-opts.d.ts.map +1 -0
  322. package/dist/src/orgrt/role-session-opts.js +289 -0
  323. package/dist/src/orgrt/role-session-opts.js.map +1 -0
  324. package/dist/src/orgrt/runner-resolve.d.ts +43 -0
  325. package/dist/src/orgrt/runner-resolve.d.ts.map +1 -0
  326. package/dist/src/orgrt/runner-resolve.js +77 -0
  327. package/dist/src/orgrt/runner-resolve.js.map +1 -0
  328. package/dist/src/orgrt/session-gate.d.ts +34 -0
  329. package/dist/src/orgrt/session-gate.d.ts.map +1 -0
  330. package/dist/src/orgrt/session-gate.js +74 -0
  331. package/dist/src/orgrt/session-gate.js.map +1 -0
  332. package/dist/src/orgrt/session-prompt.d.ts +31 -0
  333. package/dist/src/orgrt/session-prompt.d.ts.map +1 -0
  334. package/dist/src/orgrt/session-prompt.js +115 -0
  335. package/dist/src/orgrt/session-prompt.js.map +1 -0
  336. package/dist/src/orgrt/session-run.d.ts +18 -0
  337. package/dist/src/orgrt/session-run.d.ts.map +1 -0
  338. package/dist/src/orgrt/session-run.js +429 -0
  339. package/dist/src/orgrt/session-run.js.map +1 -0
  340. package/dist/src/orgrt/session-stream.d.ts +21 -0
  341. package/dist/src/orgrt/session-stream.d.ts.map +1 -0
  342. package/dist/src/orgrt/session-stream.js +173 -0
  343. package/dist/src/orgrt/session-stream.js.map +1 -0
  344. package/dist/src/orgrt/session-types.d.ts +219 -0
  345. package/dist/src/orgrt/session-types.d.ts.map +1 -0
  346. package/dist/src/orgrt/session-types.js +2 -0
  347. package/dist/src/orgrt/session-types.js.map +1 -0
  348. package/dist/src/orgrt/session-usage.d.ts +29 -0
  349. package/dist/src/orgrt/session-usage.d.ts.map +1 -0
  350. package/dist/src/orgrt/session-usage.js +64 -0
  351. package/dist/src/orgrt/session-usage.js.map +1 -0
  352. package/dist/src/orgrt/session.d.ts +5 -281
  353. package/dist/src/orgrt/session.d.ts.map +1 -1
  354. package/dist/src/orgrt/session.js +8 -1117
  355. package/dist/src/orgrt/session.js.map +1 -1
  356. package/dist/src/ui/org-hil.mjs +1 -1
  357. package/dist/src/ui/routes-org-agents.mjs +318 -0
  358. package/dist/src/ui/routes-org-approvals.mjs +133 -0
  359. package/dist/src/ui/routes-org-config.mjs +459 -0
  360. package/dist/src/ui/routes-org-control.mjs +300 -0
  361. package/dist/src/ui/routes-org-files.mjs +172 -0
  362. package/dist/src/ui/routes-org-helpers.mjs +84 -0
  363. package/dist/src/ui/routes-org-knowledge.mjs +262 -0
  364. package/dist/src/ui/routes-org-lifecycle.mjs +224 -0
  365. package/dist/src/ui/routes-org-live.mjs +278 -0
  366. package/dist/src/ui/routes-org-mastermind.mjs +346 -0
  367. package/dist/src/ui/routes-org-planning.mjs +398 -0
  368. package/dist/src/ui/routes-org-runs.mjs +430 -0
  369. package/dist/src/ui/routes-org-status.mjs +342 -0
  370. package/dist/src/ui/routes-org-workflows.mjs +212 -0
  371. package/dist/src/ui/routes-org.mjs +26 -3847
  372. package/dist/src/ui/server.mjs +1 -1
  373. package/dist/src/utils/native-error.d.ts +1 -1
  374. package/dist/src/utils/native-error.js +1 -1
  375. package/dist/src/utils/paths.d.ts +2 -1
  376. package/dist/src/utils/paths.d.ts.map +1 -1
  377. package/dist/src/utils/paths.js +2 -1
  378. package/dist/src/utils/paths.js.map +1 -1
  379. package/dist/tsconfig.tsbuildinfo +1 -1
  380. package/org-skills/adversarial-reviewer/SKILL.md +1 -1
  381. package/org-skills/board-deck-builder/SKILL.md +1 -1
  382. package/org-skills/code-reviewer/SKILL.md +1 -1
  383. package/org-skills/debugging-wizard/SKILL.md +1 -1
  384. package/org-skills/scientific-thinking-literature-review/SKILL.md +1 -1
  385. package/org-skills/scientific-thinking-scholar-evaluation/SKILL.md +1 -1
  386. package/package.json +5 -5
@@ -0,0 +1,248 @@
1
+ /**
2
+ * Memory Knowledge Graph — graph maintenance reads and moves: kgPromote
3
+ * (org-owned → project-shared, explicit), consolidation candidates, and
4
+ * kgStats. Split out of memory-kg.ts, which re-exports the public symbols.
5
+ */
6
+ import { bridgeCountEntries } from './memory-bridge.js';
7
+ import { kgIngest } from './memory-kg-ingest.js';
8
+ import { kgNamespaces, kgQualifyOrigin, MAX_DESC_LEN, MAX_EDGES_PER_CALL, MAX_NODES_PER_CALL, MAX_RULES_PER_CALL, } from './memory-kg-model.js';
9
+ import { kgIngestRules } from './memory-kg-rules.js';
10
+ import { collectByOrigin, FailureLog, scanNamespace } from './memory-kg-scan.js';
11
+ /** Copy one origin's claims out of an org's scope into project-shared
12
+ * knowledge.
13
+ *
14
+ * Sharing is deliberate, never a side effect of learning: `kgIngest` under a
15
+ * scope only ever writes that org's namespaces, and this is the one path a
16
+ * claim takes across the boundary. The org keeps its own copy untouched — the
17
+ * shared copy is an INDEPENDENT assertion under `promoted:<org-ref>`, so
18
+ * rolling back either side leaves the other standing, and a shared claim
19
+ * always names the org that vouched for it.
20
+ *
21
+ * Like ingest, NOT atomic: the counters report what actually landed. */
22
+ export async function kgPromote(options) {
23
+ const empty = { nodes: 0, edges: 0, rules: 0 };
24
+ if (!options.from?.org?.trim())
25
+ return {
26
+ success: false,
27
+ ...empty,
28
+ promotedAs: '',
29
+ error: 'promotion needs an owning org to promote from',
30
+ };
31
+ const ns = kgNamespaces(options.from);
32
+ const sourceRef = kgQualifyOrigin(options.originRef, options.from);
33
+ const promotedAs = `promoted:${sourceRef}`;
34
+ const failures = new FailureLog();
35
+ try {
36
+ const [nodeHits, edgeHits, ruleHits] = await Promise.all([
37
+ collectByOrigin(ns.nodes, sourceRef, options.dbPath),
38
+ collectByOrigin(ns.edges, sourceRef, options.dbPath),
39
+ collectByOrigin(ns.rules, sourceRef, options.dbPath),
40
+ ]);
41
+ // A partial read would promote a partial claim set while reporting the
42
+ // whole origin as shared.
43
+ for (const [name, hit] of [
44
+ ['nodes', nodeHits],
45
+ ['edges', edgeHits],
46
+ ['rules', ruleHits],
47
+ ])
48
+ if (!hit.covered)
49
+ failures.note(`${name}: memory backend unavailable`);
50
+ if (failures.failed)
51
+ return {
52
+ success: false,
53
+ ...empty,
54
+ promotedAs,
55
+ failures: failures.messages,
56
+ error: failures.summary(),
57
+ };
58
+ // Rule NODES are re-created by kgIngestRules; promoting them again through
59
+ // kgIngest would double-count and strip their rules-namespace entry.
60
+ const nodes = nodeHits.entries
61
+ .filter((e) => {
62
+ const md = (e.metadata ?? {});
63
+ return md.node_set !== 'rules' && String(md.type ?? '').toLowerCase() !== 'rule';
64
+ })
65
+ .map((e) => {
66
+ const md = (e.metadata ?? {});
67
+ return {
68
+ name: String(md.name ?? e.key),
69
+ type: String(md.type ?? 'entity'),
70
+ description: String(md.description ?? ''),
71
+ nodeSet: typeof md.node_set === 'string' ? md.node_set : undefined,
72
+ };
73
+ });
74
+ const edges = edgeHits.entries.map((e) => {
75
+ const md = (e.metadata ?? {});
76
+ return {
77
+ source: String(md.source_name ?? md.src ?? ''),
78
+ target: String(md.target_name ?? md.dst ?? ''),
79
+ relation: String(md.relation ?? 'related_to'),
80
+ description: String(md.description ?? ''),
81
+ };
82
+ });
83
+ const rules = ruleHits.entries.map((e) => {
84
+ const md = (e.metadata ?? {});
85
+ return { rule: String(md.rule ?? e.content.split('\n')[0]) };
86
+ });
87
+ let promotedNodes = 0, promotedEdges = 0, promotedRules = 0;
88
+ /** A batch that REJECTED part of what it was handed did not promote the
89
+ * whole origin, so it cannot be reported as a clean share. Rejections are
90
+ * not in `failures` — they are the caller's payload being refused, not the
91
+ * bridge failing — so they have to be carried across explicitly. */
92
+ const carry = (res, what) => {
93
+ if (res.failures?.length)
94
+ for (const m of res.failures)
95
+ failures.note(m);
96
+ const rejected = (res.nodesRejected ?? 0) + (res.edgesRejected ?? 0);
97
+ if (rejected)
98
+ failures.note(`${what}: ${rejected} item(s) rejected — ${res.rejections?.[0]}`);
99
+ };
100
+ // kgIngest caps a call at 500 nodes / 1000 edges, so a large origin has to
101
+ // be promoted in batches rather than silently truncated. Nodes go first so
102
+ // every edge endpoint already exists when the edges land.
103
+ for (let i = 0; i < nodes.length; i += MAX_NODES_PER_CALL) {
104
+ const res = await kgIngest({
105
+ nodes: nodes.slice(i, i + MAX_NODES_PER_CALL),
106
+ originRef: promotedAs,
107
+ dbPath: options.dbPath,
108
+ });
109
+ promotedNodes += res.nodesAdded + res.nodesMerged;
110
+ carry(res, 'promoted nodes');
111
+ }
112
+ for (let i = 0; i < edges.length; i += MAX_EDGES_PER_CALL) {
113
+ const res = await kgIngest({
114
+ nodes: [],
115
+ edges: edges.slice(i, i + MAX_EDGES_PER_CALL),
116
+ originRef: promotedAs,
117
+ dbPath: options.dbPath,
118
+ });
119
+ promotedEdges += res.edgesAdded + res.edgesMerged;
120
+ carry(res, 'promoted edges');
121
+ }
122
+ for (let i = 0; i < rules.length; i += MAX_RULES_PER_CALL) {
123
+ const res = await kgIngestRules({
124
+ rules: rules.slice(i, i + MAX_RULES_PER_CALL),
125
+ originRef: promotedAs,
126
+ dbPath: options.dbPath,
127
+ });
128
+ promotedRules += res.accepted;
129
+ if (res.failures?.length)
130
+ for (const m of res.failures)
131
+ failures.note(m);
132
+ const invalid = res.verdicts.filter((v) => v.verdict === 'invalid').length;
133
+ if (invalid)
134
+ failures.note(`promoted rules: ${invalid} rejected as invalid`);
135
+ }
136
+ return {
137
+ success: !failures.failed,
138
+ nodes: promotedNodes,
139
+ edges: promotedEdges,
140
+ rules: promotedRules,
141
+ promotedAs,
142
+ ...(failures.failed ? { failures: failures.messages, error: failures.summary() } : {}),
143
+ };
144
+ }
145
+ catch (err) {
146
+ return {
147
+ success: false,
148
+ ...empty,
149
+ promotedAs,
150
+ ...(failures.messages.length ? { failures: failures.messages } : {}),
151
+ error: err instanceof Error ? err.message : String(err),
152
+ };
153
+ }
154
+ }
155
+ /** Entities whose descriptions are stale relative to their connectivity —
156
+ * the LLM half runs in the LIVE agent: it rewrites each candidate's
157
+ * description from the neighborhood facts and resubmits via memory_kg_ingest.
158
+ * A resubmission is a NEW contribution and therefore the current one, so a
159
+ * shorter but better-supported summary now wins; under "longest description
160
+ * wins" a consolidation that tightened the prose was silently discarded.
161
+ * No LLM here (fully local constraint). */
162
+ export async function kgConsolidateCandidates(options) {
163
+ const minEdges = options?.minEdges ?? 3;
164
+ const limit = options?.limit ?? 10;
165
+ const ns = kgNamespaces(options?.scope);
166
+ // Degree index over the FULL edge namespace. Only the first 12 facts per node
167
+ // are kept (that is all the result exposes), so the index costs a bounded
168
+ // amount per node rather than one string per edge.
169
+ const degree = new Map();
170
+ await scanNamespace(ns.edges, options?.dbPath, (page) => {
171
+ for (const e of page) {
172
+ const md = e.metadata;
173
+ for (const end of [String(md.src ?? ''), String(md.dst ?? '')]) {
174
+ if (!end)
175
+ continue;
176
+ const slot = degree.get(end) ?? { count: 0, facts: [] };
177
+ slot.count++;
178
+ if (slot.facts.length < 12)
179
+ slot.facts.push(e.content);
180
+ degree.set(end, slot);
181
+ }
182
+ }
183
+ });
184
+ let candidates = [];
185
+ await scanNamespace(ns.nodes, options?.dbPath, (page) => {
186
+ for (const n of page) {
187
+ const md = n.metadata;
188
+ const slot = degree.get(n.key);
189
+ if (!slot || slot.count < minEdges)
190
+ continue;
191
+ const description = String(md.description ?? '');
192
+ // Cap the growth target at MAX_DESC_LEN — a very-high-degree node whose
193
+ // description is already at the cap can never "grow out" of candidacy and
194
+ // would otherwise permanently occupy a slot.
195
+ if (description.length >= Math.min(40 * slot.count, MAX_DESC_LEN))
196
+ continue;
197
+ candidates.push({
198
+ name: String(md.name ?? n.key),
199
+ type: String(md.type ?? 'entity'),
200
+ description,
201
+ edgeCount: slot.count,
202
+ neighborhood: slot.facts,
203
+ });
204
+ }
205
+ // Ranking is per-node, so keeping only the running top-`limit` after each
206
+ // page gives the same answer as ranking every node at the end.
207
+ candidates.sort((a, b) => b.edgeCount - a.edgeCount);
208
+ candidates = candidates.slice(0, limit);
209
+ });
210
+ return candidates;
211
+ }
212
+ // ── Stats ───────────────────────────────────────────────────────────
213
+ /** Real counts, not page lengths. `bridgeListEntries.total` reports how many
214
+ * rows that one call returned, so the old capped list made a 10,001-node graph
215
+ * report exactly 10,000 forever.
216
+ *
217
+ * Tries a real indexed `SELECT COUNT(*) WHERE namespace = ?` first
218
+ * (`bridgeCountEntries`, K7) — cheap and exact, since every row in a KG
219
+ * namespace is exactly one node/edge/rule (the name index lives in its own
220
+ * namespace). Falls back to the paginated scan — one query per 1,000 rows,
221
+ * still exact — when the loaded bridge predates `bridgeCountEntries`, or a
222
+ * test double doesn't stub it. */
223
+ export async function kgStats(options) {
224
+ const ns = kgNamespaces(options?.scope);
225
+ const count = async (namespace) => {
226
+ try {
227
+ const real = await bridgeCountEntries(namespace, options?.dbPath);
228
+ if (real !== null)
229
+ return real;
230
+ }
231
+ catch {
232
+ /* bridgeCountEntries unavailable on this loaded bridge (or a test
233
+ double that doesn't stub it) — fall back to the exhaustive scan. */
234
+ }
235
+ let n = 0;
236
+ await scanNamespace(namespace, options?.dbPath, (page) => {
237
+ n += page.length;
238
+ });
239
+ return n;
240
+ };
241
+ const [nodes, edges, rules] = await Promise.all([
242
+ count(ns.nodes),
243
+ count(ns.edges),
244
+ count(ns.rules),
245
+ ]);
246
+ return { nodes, edges, rules };
247
+ }
248
+ //# sourceMappingURL=memory-kg-promote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-kg-promote.js","sourceRoot":"","sources":["../../../src/memory/memory-kg-promote.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Memory Knowledge Graph — K7 index rebuild/repair (kgRebuildIndex, with
3
+ * resume and validation against the reference reads) and the graph
4
+ * integrity check. Split out of memory-kg.ts, which re-exports the public
5
+ * symbols.
6
+ */
7
+ import type { KgIndexStatus } from './memory-kg-index.js';
8
+ import type { KgScope } from './memory-kg-model.js';
9
+ export interface KgRebuildResult {
10
+ success: boolean;
11
+ status: KgIndexStatus;
12
+ validation?: {
13
+ sampledEntities: number;
14
+ sampledOrigins: number;
15
+ full: boolean;
16
+ };
17
+ error?: string;
18
+ }
19
+ /** (Re)build a scope's derived index from canonical data — nodes, then
20
+ * edges, then rules, that fixed order, resuming from the last checkpointed
21
+ * `{phase, offset}` rather than restarting when a prior call was
22
+ * interrupted mid-build. Every write here (`addToAdj`/`addToOriginIndex`)
23
+ * is idempotent, so a page reprocessed after an interruption cannot
24
+ * duplicate an entry.
25
+ *
26
+ * A concurrent ingest/rollback during the build is safe, not just tolerated:
27
+ * the dual-write hooks run whenever state is not `absent`/`failed`, so a
28
+ * write made mid-build is captured whether or not the scan has reached that
29
+ * row yet — at worst twice, which idempotency absorbs for free. The one
30
+ * residual race (a row deleted between the scan reading it and the scan's
31
+ * own write landing) can leave a dangling ref in the index; it is never
32
+ * observable as wrong data, because every indexed READ
33
+ * (`kgIndexedEdgesByEndpoint`/`kgIndexedByOrigin`) returns `null` — and the
34
+ * caller falls back to the exhaustive scan — the instant it cannot resolve
35
+ * a ref it holds. This is the backend's real capability (single-row CAS,
36
+ * no cross-row transaction), used honestly rather than claiming atomicity
37
+ * it cannot provide.
38
+ *
39
+ * Ends in `validating`: samples up to `VALIDATE_SAMPLE` of the entities and
40
+ * origins the scan actually saw, and re-reads them through the just-built
41
+ * index, comparing against a FRESH, independent reference read
42
+ * (`kgReferenceEdges`/`collectByOrigin`) — not the in-memory data the build
43
+ * itself computed, which would only prove the build agrees with itself. A
44
+ * write that silently failed, or a concurrent change the dual-write hooks
45
+ * missed, is exactly what this catches before the index is ever trusted. */
46
+ export declare function kgRebuildIndex(options?: {
47
+ scope?: KgScope;
48
+ dbPath?: string;
49
+ }): Promise<KgRebuildResult>;
50
+ export interface KgIntegrityResult {
51
+ success: boolean;
52
+ edges: number;
53
+ /** Edges naming an endpoint that does not exist. Retrieval is node-seeded,
54
+ * so such an edge is a fact unreachable through either of the things it is
55
+ * about — it can only be found by a check like this one. */
56
+ dangling: {
57
+ key: string;
58
+ missing: string[];
59
+ }[];
60
+ /** True when the edge scan did not cover the namespace: absence of a dangling
61
+ * edge here is then not evidence that there is none. */
62
+ truncated?: boolean;
63
+ error?: string;
64
+ }
65
+ /** Verify that every edge's endpoints exist.
66
+ *
67
+ * `kgIngest` now creates missing endpoints before writing an edge and
68
+ * `kgRollback` removes edges whose endpoints it deleted, so a healthy graph
69
+ * reports nothing. This exists for graphs written before either rule, and as
70
+ * the check that says so rather than assuming it. */
71
+ export declare function kgIntegrityCheck(options?: {
72
+ dbPath?: string;
73
+ scope?: KgScope;
74
+ /** Dangling edges to report before stopping (default 100). */
75
+ limit?: number;
76
+ }): Promise<KgIntegrityResult>;
77
+ //# sourceMappingURL=memory-kg-rebuild.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-kg-rebuild.d.ts","sourceRoot":"","sources":["../../../src/memory/memory-kg-rebuild.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAU1D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAoBpD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,CAAC,EAAE;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAcD;;;;;;;;;;;;;;;;;;;;;;;;;;6EA0B6E;AAC7E,wBAAsB,cAAc,CAAC,OAAO,CAAC,EAAE;IAC7C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,eAAe,CAAC,CAqL3B;AAID,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd;;iEAE6D;IAC7D,QAAQ,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC;IAC/C;6DACyD;IACzD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;sDAKsD;AACtD,wBAAsB,gBAAgB,CAAC,OAAO,CAAC,EAAE;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAmD7B"}
@@ -0,0 +1,299 @@
1
+ /**
2
+ * Memory Knowledge Graph — K7 index rebuild/repair (kgRebuildIndex, with
3
+ * resume and validation against the reference reads) and the graph
4
+ * integrity check. Split out of memory-kg.ts, which re-exports the public
5
+ * symbols.
6
+ */
7
+ import { bridgeGetEntry, bridgeListEntries } from './memory-bridge.js';
8
+ import { addToAdj, addToOriginIndex, KG_INDEX_SCHEMA_VERSION, kgIndexedByOrigin, kgIndexedEdgesByEndpoint, readIndexStatus, writeIndexStatus, } from './memory-kg-index.js';
9
+ import { kgNamespaces } from './memory-kg-model.js';
10
+ import { clearNamespace, collectByOrigin, kgReferenceEdges, originsOf, SCAN_PAGE, scanNamespace, } from './memory-kg-scan.js';
11
+ // ── Rebuild (K7): the one function that builds/repairs the derived index ──
12
+ /** Entities/origins sampled for post-build validation. A scan that saw fewer
13
+ * than this many distinct entities AND origins gets FULL validation, not a
14
+ * sample — most real scopes will. `KgRebuildResult.status.validation` says
15
+ * which happened, honestly, rather than letting "validated" imply "all". */
16
+ const VALIDATE_SAMPLE = 200;
17
+ function phaseOrder(phase) {
18
+ return phase === 'edges' ? 1 : phase === 'rules' ? 2 : 0;
19
+ }
20
+ function sameEdgeKeySet(a, b) {
21
+ const ak = new Set(a.map((e) => e.key));
22
+ const bk = new Set(b.map((e) => e.key));
23
+ if (ak.size !== bk.size)
24
+ return false;
25
+ for (const k of ak)
26
+ if (!bk.has(k))
27
+ return false;
28
+ return true;
29
+ }
30
+ /** (Re)build a scope's derived index from canonical data — nodes, then
31
+ * edges, then rules, that fixed order, resuming from the last checkpointed
32
+ * `{phase, offset}` rather than restarting when a prior call was
33
+ * interrupted mid-build. Every write here (`addToAdj`/`addToOriginIndex`)
34
+ * is idempotent, so a page reprocessed after an interruption cannot
35
+ * duplicate an entry.
36
+ *
37
+ * A concurrent ingest/rollback during the build is safe, not just tolerated:
38
+ * the dual-write hooks run whenever state is not `absent`/`failed`, so a
39
+ * write made mid-build is captured whether or not the scan has reached that
40
+ * row yet — at worst twice, which idempotency absorbs for free. The one
41
+ * residual race (a row deleted between the scan reading it and the scan's
42
+ * own write landing) can leave a dangling ref in the index; it is never
43
+ * observable as wrong data, because every indexed READ
44
+ * (`kgIndexedEdgesByEndpoint`/`kgIndexedByOrigin`) returns `null` — and the
45
+ * caller falls back to the exhaustive scan — the instant it cannot resolve
46
+ * a ref it holds. This is the backend's real capability (single-row CAS,
47
+ * no cross-row transaction), used honestly rather than claiming atomicity
48
+ * it cannot provide.
49
+ *
50
+ * Ends in `validating`: samples up to `VALIDATE_SAMPLE` of the entities and
51
+ * origins the scan actually saw, and re-reads them through the just-built
52
+ * index, comparing against a FRESH, independent reference read
53
+ * (`kgReferenceEdges`/`collectByOrigin`) — not the in-memory data the build
54
+ * itself computed, which would only prove the build agrees with itself. A
55
+ * write that silently failed, or a concurrent change the dual-write hooks
56
+ * missed, is exactly what this catches before the index is ever trusted. */
57
+ export async function kgRebuildIndex(options) {
58
+ const ns = kgNamespaces(options?.scope);
59
+ const dbPath = options?.dbPath;
60
+ let status = await readIndexStatus(ns, dbPath);
61
+ // Resume from the checkpointed cursor for an interrupted build or a
62
+ // resumable (build-phase) failure; a fresh scan for everything else —
63
+ // `absent`, `ready` (this call IS the deliberate re-verify), and a
64
+ // validation-phase failure, where something already written was wrong.
65
+ const resume = status.state === 'building' || (status.state === 'failed' && status.resumable);
66
+ if (!resume) {
67
+ status = {
68
+ state: 'building',
69
+ schemaVersion: KG_INDEX_SCHEMA_VERSION,
70
+ cursor: { phase: 'nodes', offset: 0 },
71
+ counts: { nodes: 0, edges: 0, rules: 0 },
72
+ startedAt: Date.now(),
73
+ };
74
+ if (!(await writeIndexStatus(ns, status, dbPath))) {
75
+ return { success: false, status, error: 'could not persist initial build status' };
76
+ }
77
+ }
78
+ const seenEntities = [];
79
+ const seenOrigins = [];
80
+ const noteEntity = (id) => {
81
+ if (id && !seenEntities.includes(id) && seenEntities.length < VALIDATE_SAMPLE) {
82
+ seenEntities.push(id);
83
+ }
84
+ };
85
+ const noteOrigin = (ref) => {
86
+ if (!seenOrigins.includes(ref) && seenOrigins.length < VALIDATE_SAMPLE)
87
+ seenOrigins.push(ref);
88
+ };
89
+ // `addToAdj`/`addToOriginIndex` only APPEND onto whatever is already
90
+ // there. That's exactly right for a RESUME (everything present was
91
+ // written earlier in this same build attempt), but wrong for a FRESH
92
+ // build: a stale or corrupted entry left over from a PRIOR build (e.g.
93
+ // the exact thing a failed validation just caught) would never be
94
+ // cleared, only added to. So a fresh build clears both derived-index
95
+ // namespaces up front, once, before touching any phase — every write for
96
+ // the rest of THIS build attempt, in this call or a later one resuming
97
+ // it, can then safely append, because the namespace is known to hold only
98
+ // rows this attempt wrote.
99
+ if (!resume) {
100
+ const adjCleared = await clearNamespace(ns.adj, dbPath);
101
+ const originCleared = await clearNamespace(ns.originIdx, dbPath);
102
+ if (!adjCleared || !originCleared) {
103
+ status = { ...status, state: 'failed', error: 'could not clear prior index before rebuild' };
104
+ await writeIndexStatus(ns, status, dbPath);
105
+ return { success: false, status, error: status.error };
106
+ }
107
+ }
108
+ const phases = [
109
+ { phase: 'nodes', namespace: ns.nodes },
110
+ { phase: 'edges', namespace: ns.edges },
111
+ { phase: 'rules', namespace: ns.rules },
112
+ ];
113
+ try {
114
+ for (const { phase, namespace } of phases) {
115
+ if (phaseOrder(status.cursor?.phase) > phaseOrder(phase))
116
+ continue; // already scanned
117
+ let offset = status.cursor?.phase === phase ? (status.cursor.offset ?? 0) : 0;
118
+ let count = status.counts?.[phase] ?? 0;
119
+ for (;;) {
120
+ const page = await bridgeListEntries({ namespace, limit: SCAN_PAGE, offset, dbPath });
121
+ if (!page) {
122
+ // The cursor stays exactly where it was: everything indexed before
123
+ // this page is still correct, only incomplete, so a retry resumes.
124
+ status = {
125
+ ...status,
126
+ state: 'failed',
127
+ resumable: true,
128
+ error: `${namespace}: backend unavailable during rebuild`,
129
+ };
130
+ await writeIndexStatus(ns, status, dbPath);
131
+ return { success: false, status, error: status.error };
132
+ }
133
+ for (const e of page.entries) {
134
+ const md = (e.metadata ?? {});
135
+ count++;
136
+ if (phase === 'edges' && md.kg === 'edge') {
137
+ const src = String(md.src ?? '');
138
+ const dst = String(md.dst ?? '');
139
+ if (src) {
140
+ await addToAdj(ns, src, e.key, dbPath);
141
+ noteEntity(src);
142
+ }
143
+ if (dst && dst !== src) {
144
+ await addToAdj(ns, dst, e.key, dbPath);
145
+ noteEntity(dst);
146
+ }
147
+ }
148
+ if (phase === 'nodes')
149
+ noteEntity(e.key);
150
+ for (const originRef of originsOf(e)) {
151
+ await addToOriginIndex(ns, originRef, { ns: namespace, key: e.key }, dbPath);
152
+ noteOrigin(originRef);
153
+ }
154
+ }
155
+ offset += page.entries.length;
156
+ status = {
157
+ ...status,
158
+ cursor: { phase, offset },
159
+ counts: { ...status.counts, [phase]: count },
160
+ };
161
+ await writeIndexStatus(ns, status, dbPath);
162
+ if (page.entries.length < SCAN_PAGE)
163
+ break; // last page of this namespace
164
+ }
165
+ }
166
+ status = { ...status, state: 'validating' };
167
+ await writeIndexStatus(ns, status, dbPath);
168
+ const mismatches = [];
169
+ for (const id of seenEntities) {
170
+ const indexed = await kgIndexedEdgesByEndpoint(ns, id, dbPath);
171
+ const reference = await kgReferenceEdges({ endpointId: id, scope: options?.scope, dbPath });
172
+ if (indexed === null || !reference.success || reference.truncated) {
173
+ mismatches.push(`entity ${id}: reference read incomplete`);
174
+ continue;
175
+ }
176
+ if (!sameEdgeKeySet(indexed, reference.edges))
177
+ mismatches.push(`entity ${id}: adjacency mismatch`);
178
+ }
179
+ for (const originRef of seenOrigins) {
180
+ const indexed = await kgIndexedByOrigin(ns, originRef, dbPath);
181
+ if (indexed === null) {
182
+ mismatches.push(`origin ${originRef}: index unreadable`);
183
+ continue;
184
+ }
185
+ const refA = await collectByOrigin(ns.nodes, originRef, dbPath);
186
+ const refB = await collectByOrigin(ns.edges, originRef, dbPath);
187
+ const refC = await collectByOrigin(ns.rules, originRef, dbPath);
188
+ if (!refA.covered || !refB.covered || !refC.covered) {
189
+ mismatches.push(`origin ${originRef}: reference scan incomplete`);
190
+ continue;
191
+ }
192
+ const expected = new Set([
193
+ ...refA.entries.map((e) => `${ns.nodes}|${e.key}`),
194
+ ...refB.entries.map((e) => `${ns.edges}|${e.key}`),
195
+ ...refC.entries.map((e) => `${ns.rules}|${e.key}`),
196
+ ]);
197
+ const indexedKeys = new Set(indexed.map((e) => `${e.ns}|${e.entry.key}`));
198
+ if (expected.size !== indexedKeys.size || [...expected].some((k) => !indexedKeys.has(k))) {
199
+ mismatches.push(`origin ${originRef}: support-index mismatch`);
200
+ }
201
+ }
202
+ const full = seenEntities.length < VALIDATE_SAMPLE && seenOrigins.length < VALIDATE_SAMPLE;
203
+ const validation = {
204
+ sampledEntities: seenEntities.length,
205
+ sampledOrigins: seenOrigins.length,
206
+ full,
207
+ };
208
+ if (mismatches.length) {
209
+ const summary = mismatches.slice(0, 5).join('; ');
210
+ status = {
211
+ ...status,
212
+ state: 'failed',
213
+ error: `validation failed: ${summary}${mismatches.length > 5 ? ` (+${mismatches.length - 5} more)` : ''}`,
214
+ };
215
+ await writeIndexStatus(ns, status, dbPath);
216
+ return { success: false, status, validation, error: status.error };
217
+ }
218
+ status = { ...status, state: 'ready', error: undefined };
219
+ await writeIndexStatus(ns, status, dbPath);
220
+ return { success: true, status, validation };
221
+ }
222
+ catch (err) {
223
+ status = {
224
+ ...status,
225
+ state: 'failed',
226
+ error: err instanceof Error ? err.message : String(err),
227
+ };
228
+ try {
229
+ await writeIndexStatus(ns, status, dbPath);
230
+ }
231
+ catch {
232
+ /* best-effort — see markIndexFailed */
233
+ }
234
+ return { success: false, status, error: status.error };
235
+ }
236
+ }
237
+ /** Verify that every edge's endpoints exist.
238
+ *
239
+ * `kgIngest` now creates missing endpoints before writing an edge and
240
+ * `kgRollback` removes edges whose endpoints it deleted, so a healthy graph
241
+ * reports nothing. This exists for graphs written before either rule, and as
242
+ * the check that says so rather than assuming it. */
243
+ export async function kgIntegrityCheck(options) {
244
+ const ns = kgNamespaces(options?.scope);
245
+ const limit = options?.limit ?? 100;
246
+ const dangling = [];
247
+ let edges = 0;
248
+ try {
249
+ /** Endpoint id → exists. One keyed lookup per DISTINCT endpoint. */
250
+ const seen = new Map();
251
+ const exists = async (id) => {
252
+ const hit = seen.get(id);
253
+ if (hit !== undefined)
254
+ return hit;
255
+ const res = await bridgeGetEntry({ key: id, namespace: ns.nodes, dbPath: options?.dbPath });
256
+ const found = Boolean(res?.found && res.entry);
257
+ seen.set(id, found);
258
+ return found;
259
+ };
260
+ // Collect first, then probe: the probes are reads, but interleaving many
261
+ // per page would hold the page open far longer than the scan needs.
262
+ const rows = [];
263
+ const covered = await scanNamespace(ns.edges, options?.dbPath, (page) => {
264
+ for (const e of page) {
265
+ const md = (e.metadata ?? {});
266
+ if (md.kg !== 'edge')
267
+ continue;
268
+ edges++;
269
+ rows.push({ key: e.key, src: String(md.src ?? ''), dst: String(md.dst ?? '') });
270
+ }
271
+ });
272
+ for (const row of rows) {
273
+ if (dangling.length >= limit)
274
+ break;
275
+ const missing = [];
276
+ if (!row.src || !(await exists(row.src)))
277
+ missing.push(row.src || '<no src>');
278
+ if (!row.dst || !(await exists(row.dst)))
279
+ missing.push(row.dst || '<no dst>');
280
+ if (missing.length)
281
+ dangling.push({ key: row.key, missing });
282
+ }
283
+ return {
284
+ success: true,
285
+ edges,
286
+ dangling,
287
+ ...(covered && dangling.length < limit ? {} : { truncated: true }),
288
+ };
289
+ }
290
+ catch (err) {
291
+ return {
292
+ success: false,
293
+ edges,
294
+ dangling,
295
+ error: err instanceof Error ? err.message : String(err),
296
+ };
297
+ }
298
+ }
299
+ //# sourceMappingURL=memory-kg-rebuild.js.map