nodedex 0.1.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 (469) hide show
  1. package/adapters/claude-code-watcher.mjs +336 -0
  2. package/adapters/hermes-statedb-watcher.mjs +234 -0
  3. package/adapters/nodedex-capture-core.mjs +129 -0
  4. package/adapters/nodedex-capture.mjs +169 -0
  5. package/dist/agent-protocol.d.ts +7 -0
  6. package/dist/agent-protocol.d.ts.map +1 -0
  7. package/dist/agent-protocol.js +38 -0
  8. package/dist/agent-protocol.js.map +1 -0
  9. package/dist/api-server.d.ts +5 -0
  10. package/dist/api-server.d.ts.map +1 -0
  11. package/dist/api-server.js +351 -0
  12. package/dist/api-server.js.map +1 -0
  13. package/dist/boot-env.d.ts +2 -0
  14. package/dist/boot-env.d.ts.map +1 -0
  15. package/dist/boot-env.js +12 -0
  16. package/dist/boot-env.js.map +1 -0
  17. package/dist/engine/__tests__/search-core.test.d.ts +2 -0
  18. package/dist/engine/__tests__/search-core.test.d.ts.map +1 -0
  19. package/dist/engine/__tests__/search-core.test.js +139 -0
  20. package/dist/engine/__tests__/search-core.test.js.map +1 -0
  21. package/dist/engine/ai-provider.d.ts +45 -0
  22. package/dist/engine/ai-provider.d.ts.map +1 -0
  23. package/dist/engine/ai-provider.js +5 -0
  24. package/dist/engine/ai-provider.js.map +1 -0
  25. package/dist/engine/embeddings.d.ts +51 -0
  26. package/dist/engine/embeddings.d.ts.map +1 -0
  27. package/dist/engine/embeddings.js +89 -0
  28. package/dist/engine/embeddings.js.map +1 -0
  29. package/dist/engine/providers/__tests__/failure-policy.test.d.ts +2 -0
  30. package/dist/engine/providers/__tests__/failure-policy.test.d.ts.map +1 -0
  31. package/dist/engine/providers/__tests__/failure-policy.test.js +134 -0
  32. package/dist/engine/providers/__tests__/failure-policy.test.js.map +1 -0
  33. package/dist/engine/providers/__tests__/model-caps.test.d.ts +2 -0
  34. package/dist/engine/providers/__tests__/model-caps.test.d.ts.map +1 -0
  35. package/dist/engine/providers/__tests__/model-caps.test.js +38 -0
  36. package/dist/engine/providers/__tests__/model-caps.test.js.map +1 -0
  37. package/dist/engine/providers/__tests__/openai-structured.test.d.ts +2 -0
  38. package/dist/engine/providers/__tests__/openai-structured.test.d.ts.map +1 -0
  39. package/dist/engine/providers/__tests__/openai-structured.test.js +73 -0
  40. package/dist/engine/providers/__tests__/openai-structured.test.js.map +1 -0
  41. package/dist/engine/providers/__tests__/usage-ledger.test.d.ts +2 -0
  42. package/dist/engine/providers/__tests__/usage-ledger.test.d.ts.map +1 -0
  43. package/dist/engine/providers/__tests__/usage-ledger.test.js +108 -0
  44. package/dist/engine/providers/__tests__/usage-ledger.test.js.map +1 -0
  45. package/dist/engine/providers/anthropic.d.ts +17 -0
  46. package/dist/engine/providers/anthropic.d.ts.map +1 -0
  47. package/dist/engine/providers/anthropic.js +125 -0
  48. package/dist/engine/providers/anthropic.js.map +1 -0
  49. package/dist/engine/providers/failure-policy.d.ts +56 -0
  50. package/dist/engine/providers/failure-policy.d.ts.map +1 -0
  51. package/dist/engine/providers/failure-policy.js +120 -0
  52. package/dist/engine/providers/failure-policy.js.map +1 -0
  53. package/dist/engine/providers/gemini.d.ts +22 -0
  54. package/dist/engine/providers/gemini.d.ts.map +1 -0
  55. package/dist/engine/providers/gemini.js +180 -0
  56. package/dist/engine/providers/gemini.js.map +1 -0
  57. package/dist/engine/providers/index.d.ts +8 -0
  58. package/dist/engine/providers/index.d.ts.map +1 -0
  59. package/dist/engine/providers/index.js +67 -0
  60. package/dist/engine/providers/index.js.map +1 -0
  61. package/dist/engine/providers/local.d.ts +12 -0
  62. package/dist/engine/providers/local.d.ts.map +1 -0
  63. package/dist/engine/providers/local.js +46 -0
  64. package/dist/engine/providers/local.js.map +1 -0
  65. package/dist/engine/providers/model-caps.d.ts +6 -0
  66. package/dist/engine/providers/model-caps.d.ts.map +1 -0
  67. package/dist/engine/providers/model-caps.js +49 -0
  68. package/dist/engine/providers/model-caps.js.map +1 -0
  69. package/dist/engine/providers/openai.d.ts +30 -0
  70. package/dist/engine/providers/openai.d.ts.map +1 -0
  71. package/dist/engine/providers/openai.js +309 -0
  72. package/dist/engine/providers/openai.js.map +1 -0
  73. package/dist/engine/providers/usage-ledger.d.ts +69 -0
  74. package/dist/engine/providers/usage-ledger.d.ts.map +1 -0
  75. package/dist/engine/providers/usage-ledger.js +209 -0
  76. package/dist/engine/providers/usage-ledger.js.map +1 -0
  77. package/dist/engine/search-core.d.ts +40 -0
  78. package/dist/engine/search-core.d.ts.map +1 -0
  79. package/dist/engine/search-core.js +109 -0
  80. package/dist/engine/search-core.js.map +1 -0
  81. package/dist/engine/vector-math.d.ts +5 -0
  82. package/dist/engine/vector-math.d.ts.map +1 -0
  83. package/dist/engine/vector-math.js +25 -0
  84. package/dist/engine/vector-math.js.map +1 -0
  85. package/dist/home-env.d.ts +26 -0
  86. package/dist/home-env.d.ts.map +1 -0
  87. package/dist/home-env.js +87 -0
  88. package/dist/home-env.js.map +1 -0
  89. package/dist/mcp-server.d.ts +13 -0
  90. package/dist/mcp-server.d.ts.map +1 -0
  91. package/dist/mcp-server.js +79 -0
  92. package/dist/mcp-server.js.map +1 -0
  93. package/dist/middleware/auth.d.ts +23 -0
  94. package/dist/middleware/auth.d.ts.map +1 -0
  95. package/dist/middleware/auth.js +104 -0
  96. package/dist/middleware/auth.js.map +1 -0
  97. package/dist/middleware/auto-recall.d.ts +7 -0
  98. package/dist/middleware/auto-recall.d.ts.map +1 -0
  99. package/dist/middleware/auto-recall.js +257 -0
  100. package/dist/middleware/auto-recall.js.map +1 -0
  101. package/dist/middleware/auto-reflect.d.ts +4 -0
  102. package/dist/middleware/auto-reflect.d.ts.map +1 -0
  103. package/dist/middleware/auto-reflect.js +5 -0
  104. package/dist/middleware/auto-reflect.js.map +1 -0
  105. package/dist/middleware/reflect/apply-flag-verdict.d.ts +27 -0
  106. package/dist/middleware/reflect/apply-flag-verdict.d.ts.map +1 -0
  107. package/dist/middleware/reflect/apply-flag-verdict.js +57 -0
  108. package/dist/middleware/reflect/apply-flag-verdict.js.map +1 -0
  109. package/dist/middleware/reflect/arc-entity-resolve.d.ts +29 -0
  110. package/dist/middleware/reflect/arc-entity-resolve.d.ts.map +1 -0
  111. package/dist/middleware/reflect/arc-entity-resolve.js +356 -0
  112. package/dist/middleware/reflect/arc-entity-resolve.js.map +1 -0
  113. package/dist/middleware/reflect/arc-inactivity-timer.d.ts +47 -0
  114. package/dist/middleware/reflect/arc-inactivity-timer.d.ts.map +1 -0
  115. package/dist/middleware/reflect/arc-inactivity-timer.js +175 -0
  116. package/dist/middleware/reflect/arc-inactivity-timer.js.map +1 -0
  117. package/dist/middleware/reflect/arc-pipeline.d.ts +33 -0
  118. package/dist/middleware/reflect/arc-pipeline.d.ts.map +1 -0
  119. package/dist/middleware/reflect/arc-pipeline.js +498 -0
  120. package/dist/middleware/reflect/arc-pipeline.js.map +1 -0
  121. package/dist/middleware/reflect/comprehend-pergroup.d.ts +100 -0
  122. package/dist/middleware/reflect/comprehend-pergroup.d.ts.map +1 -0
  123. package/dist/middleware/reflect/comprehend-pergroup.js +610 -0
  124. package/dist/middleware/reflect/comprehend-pergroup.js.map +1 -0
  125. package/dist/middleware/reflect/comprehend.d.ts +237 -0
  126. package/dist/middleware/reflect/comprehend.d.ts.map +1 -0
  127. package/dist/middleware/reflect/comprehend.js +706 -0
  128. package/dist/middleware/reflect/comprehend.js.map +1 -0
  129. package/dist/middleware/reflect/config.d.ts +34 -0
  130. package/dist/middleware/reflect/config.d.ts.map +1 -0
  131. package/dist/middleware/reflect/config.js +131 -0
  132. package/dist/middleware/reflect/config.js.map +1 -0
  133. package/dist/middleware/reflect/context.d.ts +138 -0
  134. package/dist/middleware/reflect/context.d.ts.map +1 -0
  135. package/dist/middleware/reflect/context.js +619 -0
  136. package/dist/middleware/reflect/context.js.map +1 -0
  137. package/dist/middleware/reflect/cost-breakdown.d.ts +69 -0
  138. package/dist/middleware/reflect/cost-breakdown.d.ts.map +1 -0
  139. package/dist/middleware/reflect/cost-breakdown.js +63 -0
  140. package/dist/middleware/reflect/cost-breakdown.js.map +1 -0
  141. package/dist/middleware/reflect/cost-guard.d.ts +102 -0
  142. package/dist/middleware/reflect/cost-guard.d.ts.map +1 -0
  143. package/dist/middleware/reflect/cost-guard.js +243 -0
  144. package/dist/middleware/reflect/cost-guard.js.map +1 -0
  145. package/dist/middleware/reflect/cost-pricing.d.ts +54 -0
  146. package/dist/middleware/reflect/cost-pricing.d.ts.map +1 -0
  147. package/dist/middleware/reflect/cost-pricing.js +148 -0
  148. package/dist/middleware/reflect/cost-pricing.js.map +1 -0
  149. package/dist/middleware/reflect/cross-group-link.d.ts +61 -0
  150. package/dist/middleware/reflect/cross-group-link.d.ts.map +1 -0
  151. package/dist/middleware/reflect/cross-group-link.js +212 -0
  152. package/dist/middleware/reflect/cross-group-link.js.map +1 -0
  153. package/dist/middleware/reflect/dedup-by-source-and-value.d.ts +70 -0
  154. package/dist/middleware/reflect/dedup-by-source-and-value.d.ts.map +1 -0
  155. package/dist/middleware/reflect/dedup-by-source-and-value.js +0 -0
  156. package/dist/middleware/reflect/dedup-by-source-and-value.js.map +1 -0
  157. package/dist/middleware/reflect/describe-roots.d.ts +58 -0
  158. package/dist/middleware/reflect/describe-roots.d.ts.map +1 -0
  159. package/dist/middleware/reflect/describe-roots.js +266 -0
  160. package/dist/middleware/reflect/describe-roots.js.map +1 -0
  161. package/dist/middleware/reflect/flag-reviewer-startup.d.ts +16 -0
  162. package/dist/middleware/reflect/flag-reviewer-startup.d.ts.map +1 -0
  163. package/dist/middleware/reflect/flag-reviewer-startup.js +107 -0
  164. package/dist/middleware/reflect/flag-reviewer-startup.js.map +1 -0
  165. package/dist/middleware/reflect/flag-reviewer.d.ts +69 -0
  166. package/dist/middleware/reflect/flag-reviewer.d.ts.map +1 -0
  167. package/dist/middleware/reflect/flag-reviewer.js +520 -0
  168. package/dist/middleware/reflect/flag-reviewer.js.map +1 -0
  169. package/dist/middleware/reflect/inline-dedup.d.ts +26 -0
  170. package/dist/middleware/reflect/inline-dedup.d.ts.map +1 -0
  171. package/dist/middleware/reflect/inline-dedup.js +131 -0
  172. package/dist/middleware/reflect/inline-dedup.js.map +1 -0
  173. package/dist/middleware/reflect/justify-decisions.d.ts +37 -0
  174. package/dist/middleware/reflect/justify-decisions.d.ts.map +1 -0
  175. package/dist/middleware/reflect/justify-decisions.js +159 -0
  176. package/dist/middleware/reflect/justify-decisions.js.map +1 -0
  177. package/dist/middleware/reflect/nl-accept.d.ts +35 -0
  178. package/dist/middleware/reflect/nl-accept.d.ts.map +1 -0
  179. package/dist/middleware/reflect/nl-accept.js +167 -0
  180. package/dist/middleware/reflect/nl-accept.js.map +1 -0
  181. package/dist/middleware/reflect/pass0.d.ts +20 -0
  182. package/dist/middleware/reflect/pass0.d.ts.map +1 -0
  183. package/dist/middleware/reflect/pass0.js +423 -0
  184. package/dist/middleware/reflect/pass0.js.map +1 -0
  185. package/dist/middleware/reflect/pass1.d.ts +17 -0
  186. package/dist/middleware/reflect/pass1.d.ts.map +1 -0
  187. package/dist/middleware/reflect/pass1.js +241 -0
  188. package/dist/middleware/reflect/pass1.js.map +1 -0
  189. package/dist/middleware/reflect/pass2-quarantine.d.ts +129 -0
  190. package/dist/middleware/reflect/pass2-quarantine.d.ts.map +1 -0
  191. package/dist/middleware/reflect/pass2-quarantine.js +272 -0
  192. package/dist/middleware/reflect/pass2-quarantine.js.map +1 -0
  193. package/dist/middleware/reflect/pass2-seams.d.ts +205 -0
  194. package/dist/middleware/reflect/pass2-seams.d.ts.map +1 -0
  195. package/dist/middleware/reflect/pass2-seams.js +279 -0
  196. package/dist/middleware/reflect/pass2-seams.js.map +1 -0
  197. package/dist/middleware/reflect/pass2-split-orchestrator.d.ts +37 -0
  198. package/dist/middleware/reflect/pass2-split-orchestrator.d.ts.map +1 -0
  199. package/dist/middleware/reflect/pass2-split-orchestrator.js +531 -0
  200. package/dist/middleware/reflect/pass2-split-orchestrator.js.map +1 -0
  201. package/dist/middleware/reflect/pass2.d.ts +17 -0
  202. package/dist/middleware/reflect/pass2.d.ts.map +1 -0
  203. package/dist/middleware/reflect/pass2.js +324 -0
  204. package/dist/middleware/reflect/pass2.js.map +1 -0
  205. package/dist/middleware/reflect/pass2a.d.ts +141 -0
  206. package/dist/middleware/reflect/pass2a.d.ts.map +1 -0
  207. package/dist/middleware/reflect/pass2a.js +404 -0
  208. package/dist/middleware/reflect/pass2a.js.map +1 -0
  209. package/dist/middleware/reflect/pass2b.d.ts +108 -0
  210. package/dist/middleware/reflect/pass2b.d.ts.map +1 -0
  211. package/dist/middleware/reflect/pass2b.js +480 -0
  212. package/dist/middleware/reflect/pass2b.js.map +1 -0
  213. package/dist/middleware/reflect/pass2c.d.ts +113 -0
  214. package/dist/middleware/reflect/pass2c.d.ts.map +1 -0
  215. package/dist/middleware/reflect/pass2c.js +360 -0
  216. package/dist/middleware/reflect/pass2c.js.map +1 -0
  217. package/dist/middleware/reflect/pass3-batch.d.ts +62 -0
  218. package/dist/middleware/reflect/pass3-batch.d.ts.map +1 -0
  219. package/dist/middleware/reflect/pass3-batch.js +139 -0
  220. package/dist/middleware/reflect/pass3-batch.js.map +1 -0
  221. package/dist/middleware/reflect/pass3.d.ts +23 -0
  222. package/dist/middleware/reflect/pass3.d.ts.map +1 -0
  223. package/dist/middleware/reflect/pass3.js +371 -0
  224. package/dist/middleware/reflect/pass3.js.map +1 -0
  225. package/dist/middleware/reflect/pass4-slice.d.ts +25 -0
  226. package/dist/middleware/reflect/pass4-slice.d.ts.map +1 -0
  227. package/dist/middleware/reflect/pass4-slice.js +315 -0
  228. package/dist/middleware/reflect/pass4-slice.js.map +1 -0
  229. package/dist/middleware/reflect/pass4.d.ts +30 -0
  230. package/dist/middleware/reflect/pass4.d.ts.map +1 -0
  231. package/dist/middleware/reflect/pass4.js +193 -0
  232. package/dist/middleware/reflect/pass4.js.map +1 -0
  233. package/dist/middleware/reflect/pass5.d.ts +22 -0
  234. package/dist/middleware/reflect/pass5.d.ts.map +1 -0
  235. package/dist/middleware/reflect/pass5.js +178 -0
  236. package/dist/middleware/reflect/pass5.js.map +1 -0
  237. package/dist/middleware/reflect/pass_judge.d.ts +44 -0
  238. package/dist/middleware/reflect/pass_judge.d.ts.map +1 -0
  239. package/dist/middleware/reflect/pass_judge.js +263 -0
  240. package/dist/middleware/reflect/pass_judge.js.map +1 -0
  241. package/dist/middleware/reflect/pipeline-flags.d.ts +140 -0
  242. package/dist/middleware/reflect/pipeline-flags.d.ts.map +1 -0
  243. package/dist/middleware/reflect/pipeline-flags.js +314 -0
  244. package/dist/middleware/reflect/pipeline-flags.js.map +1 -0
  245. package/dist/middleware/reflect/pipeline.d.ts +237 -0
  246. package/dist/middleware/reflect/pipeline.d.ts.map +1 -0
  247. package/dist/middleware/reflect/pipeline.js +3114 -0
  248. package/dist/middleware/reflect/pipeline.js.map +1 -0
  249. package/dist/middleware/reflect/promptOverride.d.ts +14 -0
  250. package/dist/middleware/reflect/promptOverride.d.ts.map +1 -0
  251. package/dist/middleware/reflect/promptOverride.js +28 -0
  252. package/dist/middleware/reflect/promptOverride.js.map +1 -0
  253. package/dist/middleware/reflect/provenance-check.d.ts +48 -0
  254. package/dist/middleware/reflect/provenance-check.d.ts.map +1 -0
  255. package/dist/middleware/reflect/provenance-check.js +180 -0
  256. package/dist/middleware/reflect/provenance-check.js.map +1 -0
  257. package/dist/middleware/reflect/provenance-reviewer.d.ts +52 -0
  258. package/dist/middleware/reflect/provenance-reviewer.d.ts.map +1 -0
  259. package/dist/middleware/reflect/provenance-reviewer.js +253 -0
  260. package/dist/middleware/reflect/provenance-reviewer.js.map +1 -0
  261. package/dist/middleware/reflect/prune-collapsed-types.d.ts +11 -0
  262. package/dist/middleware/reflect/prune-collapsed-types.d.ts.map +1 -0
  263. package/dist/middleware/reflect/prune-collapsed-types.js +32 -0
  264. package/dist/middleware/reflect/prune-collapsed-types.js.map +1 -0
  265. package/dist/middleware/reflect/recognize-root.d.ts +75 -0
  266. package/dist/middleware/reflect/recognize-root.d.ts.map +1 -0
  267. package/dist/middleware/reflect/recognize-root.js +204 -0
  268. package/dist/middleware/reflect/recognize-root.js.map +1 -0
  269. package/dist/middleware/reflect/render-agent-flag.d.ts +25 -0
  270. package/dist/middleware/reflect/render-agent-flag.d.ts.map +1 -0
  271. package/dist/middleware/reflect/render-agent-flag.js +39 -0
  272. package/dist/middleware/reflect/render-agent-flag.js.map +1 -0
  273. package/dist/middleware/reflect/retrieve-graph-slice.d.ts +54 -0
  274. package/dist/middleware/reflect/retrieve-graph-slice.d.ts.map +1 -0
  275. package/dist/middleware/reflect/retrieve-graph-slice.js +173 -0
  276. package/dist/middleware/reflect/retrieve-graph-slice.js.map +1 -0
  277. package/dist/middleware/reflect/root-relatedness.d.ts +31 -0
  278. package/dist/middleware/reflect/root-relatedness.d.ts.map +1 -0
  279. package/dist/middleware/reflect/root-relatedness.js +92 -0
  280. package/dist/middleware/reflect/root-relatedness.js.map +1 -0
  281. package/dist/middleware/reflect/schema-heal.d.ts +22 -0
  282. package/dist/middleware/reflect/schema-heal.d.ts.map +1 -0
  283. package/dist/middleware/reflect/schema-heal.js +119 -0
  284. package/dist/middleware/reflect/schema-heal.js.map +1 -0
  285. package/dist/middleware/reflect/schema-validator.d.ts +85 -0
  286. package/dist/middleware/reflect/schema-validator.d.ts.map +1 -0
  287. package/dist/middleware/reflect/schema-validator.js +196 -0
  288. package/dist/middleware/reflect/schema-validator.js.map +1 -0
  289. package/dist/middleware/reflect/stage-audit-graph.d.ts +115 -0
  290. package/dist/middleware/reflect/stage-audit-graph.d.ts.map +1 -0
  291. package/dist/middleware/reflect/stage-audit-graph.js +563 -0
  292. package/dist/middleware/reflect/stage-audit-graph.js.map +1 -0
  293. package/dist/middleware/reflect/stage-d-resolve-graph.d.ts +87 -0
  294. package/dist/middleware/reflect/stage-d-resolve-graph.d.ts.map +1 -0
  295. package/dist/middleware/reflect/stage-d-resolve-graph.js +256 -0
  296. package/dist/middleware/reflect/stage-d-resolve-graph.js.map +1 -0
  297. package/dist/middleware/reflect/synthesizeFromSceneCard.d.ts +15 -0
  298. package/dist/middleware/reflect/synthesizeFromSceneCard.d.ts.map +1 -0
  299. package/dist/middleware/reflect/synthesizeFromSceneCard.js +91 -0
  300. package/dist/middleware/reflect/synthesizeFromSceneCard.js.map +1 -0
  301. package/dist/middleware/reflect/types.d.ts +261 -0
  302. package/dist/middleware/reflect/types.d.ts.map +1 -0
  303. package/dist/middleware/reflect/types.js +3 -0
  304. package/dist/middleware/reflect/types.js.map +1 -0
  305. package/dist/middleware/reflect/v2-integrate.d.ts +120 -0
  306. package/dist/middleware/reflect/v2-integrate.d.ts.map +1 -0
  307. package/dist/middleware/reflect/v2-integrate.js +388 -0
  308. package/dist/middleware/reflect/v2-integrate.js.map +1 -0
  309. package/dist/middleware/reflect/v2-judge.d.ts +44 -0
  310. package/dist/middleware/reflect/v2-judge.d.ts.map +1 -0
  311. package/dist/middleware/reflect/v2-judge.js +191 -0
  312. package/dist/middleware/reflect/v2-judge.js.map +1 -0
  313. package/dist/relation-sets.d.ts +2 -0
  314. package/dist/relation-sets.d.ts.map +1 -0
  315. package/dist/relation-sets.js +35 -0
  316. package/dist/relation-sets.js.map +1 -0
  317. package/dist/routes/__tests__/flags.test.d.ts +2 -0
  318. package/dist/routes/__tests__/flags.test.d.ts.map +1 -0
  319. package/dist/routes/__tests__/flags.test.js +257 -0
  320. package/dist/routes/__tests__/flags.test.js.map +1 -0
  321. package/dist/routes/__tests__/models-catalog.test.d.ts +2 -0
  322. package/dist/routes/__tests__/models-catalog.test.d.ts.map +1 -0
  323. package/dist/routes/__tests__/models-catalog.test.js +130 -0
  324. package/dist/routes/__tests__/models-catalog.test.js.map +1 -0
  325. package/dist/routes/__tests__/reflect-pause-drain.test.d.ts +2 -0
  326. package/dist/routes/__tests__/reflect-pause-drain.test.d.ts.map +1 -0
  327. package/dist/routes/__tests__/reflect-pause-drain.test.js +38 -0
  328. package/dist/routes/__tests__/reflect-pause-drain.test.js.map +1 -0
  329. package/dist/routes/__tests__/spend-pause-drain.test.d.ts +2 -0
  330. package/dist/routes/__tests__/spend-pause-drain.test.d.ts.map +1 -0
  331. package/dist/routes/__tests__/spend-pause-drain.test.js +38 -0
  332. package/dist/routes/__tests__/spend-pause-drain.test.js.map +1 -0
  333. package/dist/routes/admin.d.ts +49 -0
  334. package/dist/routes/admin.d.ts.map +1 -0
  335. package/dist/routes/admin.js +471 -0
  336. package/dist/routes/admin.js.map +1 -0
  337. package/dist/routes/blocks.d.ts +4 -0
  338. package/dist/routes/blocks.d.ts.map +1 -0
  339. package/dist/routes/blocks.js +893 -0
  340. package/dist/routes/blocks.js.map +1 -0
  341. package/dist/routes/chat-proxy.d.ts +5 -0
  342. package/dist/routes/chat-proxy.d.ts.map +1 -0
  343. package/dist/routes/chat-proxy.js +225 -0
  344. package/dist/routes/chat-proxy.js.map +1 -0
  345. package/dist/routes/conversations.d.ts +4 -0
  346. package/dist/routes/conversations.d.ts.map +1 -0
  347. package/dist/routes/conversations.js +139 -0
  348. package/dist/routes/conversations.js.map +1 -0
  349. package/dist/routes/flags.d.ts +4 -0
  350. package/dist/routes/flags.d.ts.map +1 -0
  351. package/dist/routes/flags.js +151 -0
  352. package/dist/routes/flags.js.map +1 -0
  353. package/dist/routes/inject.d.ts +4 -0
  354. package/dist/routes/inject.d.ts.map +1 -0
  355. package/dist/routes/inject.js +183 -0
  356. package/dist/routes/inject.js.map +1 -0
  357. package/dist/routes/mcp-http.d.ts +5 -0
  358. package/dist/routes/mcp-http.d.ts.map +1 -0
  359. package/dist/routes/mcp-http.js +94 -0
  360. package/dist/routes/mcp-http.js.map +1 -0
  361. package/dist/routes/quarantine.d.ts +4 -0
  362. package/dist/routes/quarantine.d.ts.map +1 -0
  363. package/dist/routes/quarantine.js +66 -0
  364. package/dist/routes/quarantine.js.map +1 -0
  365. package/dist/routes/recall.d.ts +5 -0
  366. package/dist/routes/recall.d.ts.map +1 -0
  367. package/dist/routes/recall.js +573 -0
  368. package/dist/routes/recall.js.map +1 -0
  369. package/dist/routes/reflect.d.ts +5 -0
  370. package/dist/routes/reflect.d.ts.map +1 -0
  371. package/dist/routes/reflect.js +231 -0
  372. package/dist/routes/reflect.js.map +1 -0
  373. package/dist/routes/session.d.ts +4 -0
  374. package/dist/routes/session.d.ts.map +1 -0
  375. package/dist/routes/session.js +418 -0
  376. package/dist/routes/session.js.map +1 -0
  377. package/dist/routes/state.d.ts +116 -0
  378. package/dist/routes/state.d.ts.map +1 -0
  379. package/dist/routes/state.js +621 -0
  380. package/dist/routes/state.js.map +1 -0
  381. package/dist/routes/usage.d.ts +3 -0
  382. package/dist/routes/usage.d.ts.map +1 -0
  383. package/dist/routes/usage.js +141 -0
  384. package/dist/routes/usage.js.map +1 -0
  385. package/dist/routes/workspace.d.ts +5 -0
  386. package/dist/routes/workspace.d.ts.map +1 -0
  387. package/dist/routes/workspace.js +435 -0
  388. package/dist/routes/workspace.js.map +1 -0
  389. package/dist/server.d.ts +13 -0
  390. package/dist/server.d.ts.map +1 -0
  391. package/dist/server.js +298 -0
  392. package/dist/server.js.map +1 -0
  393. package/dist/store/__tests__/backup.test.d.ts +2 -0
  394. package/dist/store/__tests__/backup.test.d.ts.map +1 -0
  395. package/dist/store/__tests__/backup.test.js +53 -0
  396. package/dist/store/__tests__/backup.test.js.map +1 -0
  397. package/dist/store/__tests__/quality.test.d.ts +2 -0
  398. package/dist/store/__tests__/quality.test.d.ts.map +1 -0
  399. package/dist/store/__tests__/quality.test.js +75 -0
  400. package/dist/store/__tests__/quality.test.js.map +1 -0
  401. package/dist/store/backup.d.ts +14 -0
  402. package/dist/store/backup.d.ts.map +1 -0
  403. package/dist/store/backup.js +95 -0
  404. package/dist/store/backup.js.map +1 -0
  405. package/dist/store/database.d.ts +407 -0
  406. package/dist/store/database.d.ts.map +1 -0
  407. package/dist/store/database.js +2004 -0
  408. package/dist/store/database.js.map +1 -0
  409. package/dist/store/quality.d.ts +25 -0
  410. package/dist/store/quality.d.ts.map +1 -0
  411. package/dist/store/quality.js +48 -0
  412. package/dist/store/quality.js.map +1 -0
  413. package/dist/tools/__tests__/assemble-block-chains.test.d.ts +2 -0
  414. package/dist/tools/__tests__/assemble-block-chains.test.d.ts.map +1 -0
  415. package/dist/tools/__tests__/assemble-block-chains.test.js +118 -0
  416. package/dist/tools/__tests__/assemble-block-chains.test.js.map +1 -0
  417. package/dist/tools/__tests__/filter-roots-by-concepts.test.d.ts +2 -0
  418. package/dist/tools/__tests__/filter-roots-by-concepts.test.d.ts.map +1 -0
  419. package/dist/tools/__tests__/filter-roots-by-concepts.test.js +68 -0
  420. package/dist/tools/__tests__/filter-roots-by-concepts.test.js.map +1 -0
  421. package/dist/tools/__tests__/flag-surface.test.d.ts +2 -0
  422. package/dist/tools/__tests__/flag-surface.test.d.ts.map +1 -0
  423. package/dist/tools/__tests__/flag-surface.test.js +130 -0
  424. package/dist/tools/__tests__/flag-surface.test.js.map +1 -0
  425. package/dist/tools/core.d.ts +5 -0
  426. package/dist/tools/core.d.ts.map +1 -0
  427. package/dist/tools/core.js +962 -0
  428. package/dist/tools/core.js.map +1 -0
  429. package/dist/tools/derive.d.ts +5 -0
  430. package/dist/tools/derive.d.ts.map +1 -0
  431. package/dist/tools/derive.js +182 -0
  432. package/dist/tools/derive.js.map +1 -0
  433. package/dist/tools/flag-surface.d.ts +26 -0
  434. package/dist/tools/flag-surface.d.ts.map +1 -0
  435. package/dist/tools/flag-surface.js +59 -0
  436. package/dist/tools/flag-surface.js.map +1 -0
  437. package/dist/tools/helpers.d.ts +99 -0
  438. package/dist/tools/helpers.d.ts.map +1 -0
  439. package/dist/tools/helpers.js +243 -0
  440. package/dist/tools/helpers.js.map +1 -0
  441. package/dist/tools/projects.d.ts +5 -0
  442. package/dist/tools/projects.d.ts.map +1 -0
  443. package/dist/tools/projects.js +175 -0
  444. package/dist/tools/projects.js.map +1 -0
  445. package/dist/tools/system.d.ts +5 -0
  446. package/dist/tools/system.d.ts.map +1 -0
  447. package/dist/tools/system.js +1361 -0
  448. package/dist/tools/system.js.map +1 -0
  449. package/dist/tools/tasks.d.ts +5 -0
  450. package/dist/tools/tasks.d.ts.map +1 -0
  451. package/dist/tools/tasks.js +289 -0
  452. package/dist/tools/tasks.js.map +1 -0
  453. package/package.json +69 -0
  454. package/scripts/nodedex-entry.mjs +396 -0
  455. package/tui-dist/App.js +185 -0
  456. package/tui-dist/api.js +197 -0
  457. package/tui-dist/cli.js +53 -0
  458. package/tui-dist/components.js +63 -0
  459. package/tui-dist/config.js +242 -0
  460. package/tui-dist/connect-snippets.js +98 -0
  461. package/tui-dist/feed.js +51 -0
  462. package/tui-dist/health.js +465 -0
  463. package/tui-dist/hooks.js +23 -0
  464. package/tui-dist/memory.js +220 -0
  465. package/tui-dist/onboarding.js +498 -0
  466. package/tui-dist/review.js +193 -0
  467. package/tui-dist/servers.js +556 -0
  468. package/tui-dist/smoke.js +15 -0
  469. package/tui-dist/theme.js +106 -0
@@ -0,0 +1,87 @@
1
+ import type { LLMProvider } from "../../engine/ai-provider.js";
2
+ import type { WorkspaceDB } from "../../store/database.js";
3
+ import type { Pass2Item } from "./types.js";
4
+ import type { RetrievalCandidate, EntityQuery } from "./retrieve-graph-slice.js";
5
+ export declare const STAGE_D_RESOLVE_PROMPT = "You receive ONE entity resolved from a single conversation arc, and a set of\nCANDIDATE blocks already in the graph that a retrieval step found potentially\nrelated. For each candidate, decide whether the arc entity is the SAME entity\nalready present, or a NEW entity to record separately.\n\n\u2500\u2500 STATE CONVENTION \u2500\u2500\n\"State\" = the arc entity and the candidate blocks shown below. Your training\nknowledge and what is \"commonly true\" about any domain are NOT state. An entity\nexists in the graph ONLY if a candidate block shows it. Familiarity is not record.\n\n\u2500\u2500 SCOPE BOUNDARY \u2500\u2500\nYou decide MATCH-or-NEW only. You do not name, wire relations, merge, or write.\nYour output is a resolution judgment the naming step consumes.\n\n\u2500\u2500 TWO INDEPENDENT QUESTIONS (answer SEPARATELY \u2014 collapsing them is the failure mode) \u2500\u2500\n\nQ1 \u2014 IDENTITY: Do the arc entity and the candidate describe the same underlying\nthing, or two different things that merely share a name or topic?\n Inspect the identity-bearing content \u2014 the specific recorded values and claims,\n not the label. A shared label with divergent content is NOT identity. Divergent\n labels carrying the same specific content IS identity.\n\nQ2 \u2014 SCOPE: If Q1 is yes \u2014 is this the same instance under the same owner/context,\nor the same KIND of thing under a DIFFERENT owner/context?\n Inspect the scope evidence each carries (its parent/owner, the surrounding\n context that places it). Ask whether the scope difference reflects a genuinely\n different owner, or whether both could be one thing recorded under two\n organizational labels. Do not treat a difference in the scope field as decisive\n by itself \u2014 reason about what the scope MEANS from the evidence shown. A scope\n marked as a catch-all / unspecified bucket is owner-UNKNOWN, not owner-different.\n\n\u2500\u2500 COST ASYMMETRY AND DEFAULT \u2500\u2500\nA false MATCH fuses two distinct things into one node \u2014 it mixes owners and is\ncostly to reverse. A false NEW leaves a duplicate a later audit can still merge.\nThe directions are NOT equal. Therefore: when Q1 or Q2 cannot be answered from the\ncontent shown, default to NEW. Treat \"same entity\" as a claim you must EARN from\nthe evidence, not assume from resemblance.\n\n\u2500\u2500 FALSIFIABILITY \u2500\u2500\nEvery \"same entity\" or \"same scope\" judgment must cite the SPECIFIC content that\nsupports it \u2014 the overlapping value, the specific shared claim, the scope evidence.\nA judgment that says only \"they seem related\" without citing what overlapped fails.\n\n\u2500\u2500 DECISION \u2500\u2500\n Q1 yes + Q2 same-scope -> match_existing (reuse the candidate's identity)\n Q1 yes + Q2 different-scope -> new_entity (same kind, different owner)\n Q1 yes + Q2 owner-unknown -> match_existing (let the naming step / review decide ownership)\n Q1 no -> new_entity\n Q1 or Q2 unanswerable -> new_entity (the conservative default above)\n\n\u2500\u2500 OUTPUT \u2500\u2500\nReturn JSON matching the schema: your two-axis judgment and the verdict, each with\nthe specific evidence that supports it.";
6
+ export type StageDDecision = "attach_existing" | "new_entity" | "flag_for_review";
7
+ export interface StageDEntityResult {
8
+ canonical_name: string;
9
+ decision: StageDDecision;
10
+ /** Set when decision='attach_existing' — the graph block to reuse. */
11
+ matched_block_id?: string;
12
+ matched_block_label?: string;
13
+ /** How the decision was reached — CODE (exact identity) or LLM (judgment). */
14
+ resolved_by: "code_exact" | "llm" | "no_candidates";
15
+ /** Why — falsifiability/audit trail. */
16
+ reasoning: string;
17
+ /** When flagged: the scope situation that triggered review. */
18
+ flag_reason?: string;
19
+ }
20
+ export declare function buildStageDInput(entity: EntityQuery, candidate: RetrievalCandidate): string;
21
+ interface ResolverLLMOutput {
22
+ same_entity: boolean;
23
+ identity_evidence: string;
24
+ same_scope: "same" | "different" | "owner_unknown";
25
+ scope_evidence: string;
26
+ verdict: "match_existing" | "new_entity";
27
+ reasoning: string;
28
+ }
29
+ export declare function callStageDResolver(provider: LLMProvider, entity: EntityQuery, candidate: RetrievalCandidate): Promise<{
30
+ result: ResolverLLMOutput | null;
31
+ model?: string;
32
+ rateLimited: boolean;
33
+ }>;
34
+ export declare function decideFromResolution(same_entity: boolean, same_scope: "same" | "different" | "owner_unknown", candidate: RetrievalCandidate): {
35
+ decision: StageDDecision;
36
+ flag_reason?: string;
37
+ };
38
+ export interface ResolveEntityOpts {
39
+ db: WorkspaceDB;
40
+ provider: LLMProvider;
41
+ entity: EntityQuery;
42
+ /** The arc entity's own scope (the project it's being filed under this arc) —
43
+ * used to decide same/different when resolving in code. */
44
+ arc_scope?: string;
45
+ k?: number;
46
+ /** When true, never call the LLM (verify harness / cost-free dry run). The
47
+ * code-exact path still resolves; ambiguous cases return 'new_entity' with
48
+ * resolved_by='code_exact' note. */
49
+ codeOnly?: boolean;
50
+ /** COST GATE: only spend an LLM call when the top candidate's identity_score
51
+ * is at least this. Below it, there's no plausible duplicate worth judging →
52
+ * return new_entity for free. Bounds cost to items that actually have a
53
+ * candidate. Default 0.5 (a partial token-overlap ≥0.5, or any exact match). */
54
+ minIdentityForLLM?: number;
55
+ }
56
+ export declare function resolveArcEntity(opts: ResolveEntityOpts): Promise<StageDEntityResult>;
57
+ export interface BatchResolveOpts {
58
+ db: WorkspaceDB;
59
+ provider: LLMProvider;
60
+ items: Pass2Item[];
61
+ /** Exclude items whose own (about-to-be-created) labels would self-match.
62
+ * Pass the set of this-arc item labels so retrieval doesn't flag an item
63
+ * against its own freshly-written sibling. */
64
+ thisArcItemValues?: Set<string>;
65
+ k?: number;
66
+ minIdentityForLLM?: number;
67
+ codeOnly?: boolean;
68
+ }
69
+ export interface BatchResolveEntry {
70
+ item_id: string;
71
+ decision: StageDDecision;
72
+ matched_block_id?: string;
73
+ matched_block_label?: string;
74
+ resolved_by: "code_exact" | "llm" | "no_candidates";
75
+ reasoning: string;
76
+ flag_reason?: string;
77
+ }
78
+ export interface BatchResolveResult {
79
+ entries: BatchResolveEntry[];
80
+ items_resolved: number;
81
+ llm_calls: number;
82
+ attached: number;
83
+ flagged: number;
84
+ }
85
+ export declare function resolveArcEntitiesForItems(opts: BatchResolveOpts): Promise<BatchResolveResult>;
86
+ export {};
87
+ //# sourceMappingURL=stage-d-resolve-graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stage-d-resolve-graph.d.ts","sourceRoot":"","sources":["../../../src/middleware/reflect/stage-d-resolve-graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,256 @@
1
+ // ═══════════════════════════════════════════════════════════════════════════════
2
+ // DEBT 5 Slice 3 (Stage D) — Part 2: RESOLVE + Part 3: DECIDE
3
+ // ═══════════════════════════════════════════════════════════════════════════════
4
+ //
5
+ // For each arc entity (post Stage C), decide: does it already EXIST in the graph
6
+ // (attach), is it a NEW thing (create), or is it AMBIGUOUS (flag for review)?
7
+ //
8
+ // Two orthogonal axes — kept SEPARATE (the flag-reviewer Finding-C lesson: a
9
+ // single blunt "different scope = leave" rule collapsed them and mis-fired):
10
+ // Q1 IDENTITY — same underlying thing? (judged on unique{} content, not label)
11
+ // Q2 SCOPE — same owner, or same KIND under a DIFFERENT owner?
12
+ //
13
+ // Match-to-competence (Rule 3):
14
+ // - EXACT identity (normalized unique{} primary value equal) + decidable scope
15
+ // → resolved in CODE, no LLM (the "only call the model when ambiguous" saver).
16
+ // - Otherwise → the LLM resolver (spike-validated prompt, docs/PIPELINE-STAGE-D-
17
+ // SPIKE-DESIGN.md §3 — 5/6 real pairs correct).
18
+ //
19
+ // Catch-all scope (spike pair-5 lesson): a candidate under a catch-all dump
20
+ // (scope.is_catch_all, detected STRUCTURALLY in retrieve-graph-slice.ts) is
21
+ // "owner UNKNOWN", not "owner different" → DECIDE routes same-identity + catch-all
22
+ // to FLAG, never auto-NEW.
23
+ //
24
+ // This module RESOLVES + DECIDES only. It does not name, write, or mutate the
25
+ // graph — its output is consumed by the Pass 3 seam (Part 4 wiring) + the flag
26
+ // table. (Mirrors flag-reviewer.ts's structure: input builder → LLM call →
27
+ // telemetry → orchestrator; here the orchestrator also holds the code-first gate.)
28
+ import { retrieveGraphSlice, normalizePrimaryValue, scopeSegmentOfLabel } from "./retrieve-graph-slice.js";
29
+ import { extractPrimaryValue, extractPrimaryValueFromUnique } from "./dedup-by-source-and-value.js";
30
+ import { reflectTokenStats } from "./context.js";
31
+ import { getThinkingBudget } from "./config.js";
32
+ const STAGE_D_MODEL_OVERRIDE = process.env.NODEDEX_STAGE_D_MODEL ?? null;
33
+ // ─── The resolver prompt (docs/PIPELINE-STAGE-D-SPIKE-DESIGN.md §3, spike-validated) ──
34
+ export const STAGE_D_RESOLVE_PROMPT = `You receive ONE entity resolved from a single conversation arc, and a set of
35
+ CANDIDATE blocks already in the graph that a retrieval step found potentially
36
+ related. For each candidate, decide whether the arc entity is the SAME entity
37
+ already present, or a NEW entity to record separately.
38
+
39
+ ── STATE CONVENTION ──
40
+ "State" = the arc entity and the candidate blocks shown below. Your training
41
+ knowledge and what is "commonly true" about any domain are NOT state. An entity
42
+ exists in the graph ONLY if a candidate block shows it. Familiarity is not record.
43
+
44
+ ── SCOPE BOUNDARY ──
45
+ You decide MATCH-or-NEW only. You do not name, wire relations, merge, or write.
46
+ Your output is a resolution judgment the naming step consumes.
47
+
48
+ ── TWO INDEPENDENT QUESTIONS (answer SEPARATELY — collapsing them is the failure mode) ──
49
+
50
+ Q1 — IDENTITY: Do the arc entity and the candidate describe the same underlying
51
+ thing, or two different things that merely share a name or topic?
52
+ Inspect the identity-bearing content — the specific recorded values and claims,
53
+ not the label. A shared label with divergent content is NOT identity. Divergent
54
+ labels carrying the same specific content IS identity.
55
+
56
+ Q2 — SCOPE: If Q1 is yes — is this the same instance under the same owner/context,
57
+ or the same KIND of thing under a DIFFERENT owner/context?
58
+ Inspect the scope evidence each carries (its parent/owner, the surrounding
59
+ context that places it). Ask whether the scope difference reflects a genuinely
60
+ different owner, or whether both could be one thing recorded under two
61
+ organizational labels. Do not treat a difference in the scope field as decisive
62
+ by itself — reason about what the scope MEANS from the evidence shown. A scope
63
+ marked as a catch-all / unspecified bucket is owner-UNKNOWN, not owner-different.
64
+
65
+ ── COST ASYMMETRY AND DEFAULT ──
66
+ A false MATCH fuses two distinct things into one node — it mixes owners and is
67
+ costly to reverse. A false NEW leaves a duplicate a later audit can still merge.
68
+ The directions are NOT equal. Therefore: when Q1 or Q2 cannot be answered from the
69
+ content shown, default to NEW. Treat "same entity" as a claim you must EARN from
70
+ the evidence, not assume from resemblance.
71
+
72
+ ── FALSIFIABILITY ──
73
+ Every "same entity" or "same scope" judgment must cite the SPECIFIC content that
74
+ supports it — the overlapping value, the specific shared claim, the scope evidence.
75
+ A judgment that says only "they seem related" without citing what overlapped fails.
76
+
77
+ ── DECISION ──
78
+ Q1 yes + Q2 same-scope -> match_existing (reuse the candidate's identity)
79
+ Q1 yes + Q2 different-scope -> new_entity (same kind, different owner)
80
+ Q1 yes + Q2 owner-unknown -> match_existing (let the naming step / review decide ownership)
81
+ Q1 no -> new_entity
82
+ Q1 or Q2 unanswerable -> new_entity (the conservative default above)
83
+
84
+ ── OUTPUT ──
85
+ Return JSON matching the schema: your two-axis judgment and the verdict, each with
86
+ the specific evidence that supports it.`;
87
+ const STAGE_D_RESOLVE_SCHEMA = {
88
+ type: "object",
89
+ properties: {
90
+ same_entity: { type: "boolean" },
91
+ identity_evidence: { type: "string" },
92
+ same_scope: { type: "string", enum: ["same", "different", "owner_unknown"] },
93
+ scope_evidence: { type: "string" },
94
+ verdict: { type: "string", enum: ["match_existing", "new_entity"] },
95
+ reasoning: { type: "string" },
96
+ },
97
+ required: ["same_entity", "identity_evidence", "same_scope", "scope_evidence", "verdict", "reasoning"],
98
+ };
99
+ // ─── Input builder (mirrors flag-reviewer.buildReviewerInput) ──────────────────
100
+ function formatCandidate(c) {
101
+ const b = c.block;
102
+ let primaryVal = "";
103
+ try {
104
+ const content = typeof b.content === "string" ? JSON.parse(b.content) : (b.content || {});
105
+ primaryVal = extractPrimaryValueFromUnique(b.type, content.unique || {});
106
+ }
107
+ catch { /* leave blank */ }
108
+ return [
109
+ ` candidate_block_id: ${b.id}`,
110
+ ` label: ${b.label}`,
111
+ ` type: ${b.type}`,
112
+ ` identity_value (unique{}): ${primaryVal || "(none)"}`,
113
+ ` essence: ${b.essence}`,
114
+ ` scope/owner: ${c.scope.value}${c.scope.is_catch_all ? " [CATCH-ALL — owner unknown, not a distinct owner]" : ""}`,
115
+ ` source_excerpt (evidence only): ${b.source_excerpt ?? "(none)"}`,
116
+ ].join("\n");
117
+ }
118
+ export function buildStageDInput(entity, candidate) {
119
+ return `── ARC ENTITY (newly resolved, seeking match) ──
120
+ canonical_name: ${entity.canonical_name}
121
+ identity_value(s) (unique{}): ${entity.primary_values.join(" | ") || "(none)"}
122
+ concepts: [${entity.concepts.join(", ")}]
123
+
124
+ ── CANDIDATE (already in graph) ──
125
+ ${formatCandidate(candidate)}
126
+
127
+ Resolve per the two questions (identity, then scope). Cite specific overlap.`;
128
+ }
129
+ export async function callStageDResolver(provider, entity, candidate) {
130
+ const userInput = buildStageDInput(entity, candidate);
131
+ const r = await provider.generateStructured(STAGE_D_RESOLVE_PROMPT, userInput, STAGE_D_RESOLVE_SCHEMA, { thinkingBudget: getThinkingBudget(1024), maxOutputTokens: 2048, modelOverride: STAGE_D_MODEL_OVERRIDE ?? undefined });
132
+ if (r.usage) {
133
+ reflectTokenStats.pass_d_resolve.input += r.usage.input ?? 0;
134
+ reflectTokenStats.pass_d_resolve.thinking += r.usage.thinking ?? 0;
135
+ reflectTokenStats.pass_d_resolve.output += r.usage.output ?? 0;
136
+ }
137
+ reflectTokenStats.pass_d_resolve.calls += 1;
138
+ return { result: r.result, model: r.model, rateLimited: r.rateLimited };
139
+ }
140
+ // ─── DECIDE (Part 3) — map (identity, scope) → one outcome ─────────────────────
141
+ //
142
+ // The 3-way rule. Pure given the resolver output (or the code-exact path).
143
+ // Catch-all scope is the load-bearing branch: same-identity under a catch-all is
144
+ // "owner unknown" → FLAG (let review/naming decide), never auto-NEW (would
145
+ // duplicate) and never silent-attach (would guess the owner).
146
+ export function decideFromResolution(same_entity, same_scope, candidate) {
147
+ if (!same_entity)
148
+ return { decision: "new_entity" };
149
+ // same_entity === true below
150
+ if (same_scope === "same")
151
+ return { decision: "attach_existing" };
152
+ if (same_scope === "different")
153
+ return { decision: "new_entity" };
154
+ // owner_unknown (incl. catch-all candidate): don't guess — flag for review.
155
+ return {
156
+ decision: "flag_for_review",
157
+ flag_reason: candidate.scope.is_catch_all
158
+ ? `Same identity as ${candidate.block.label}, but its scope is a catch-all (owner unknown) — needs review to assign the real owner.`
159
+ : `Same identity as ${candidate.block.label}, but scope ownership is undetermined — needs review.`,
160
+ };
161
+ }
162
+ export async function resolveArcEntity(opts) {
163
+ const { db, provider, entity } = opts;
164
+ const candidates = retrieveGraphSlice(db, entity, { k: opts.k ?? 20 });
165
+ if (candidates.length === 0) {
166
+ return { canonical_name: entity.canonical_name, decision: "new_entity", resolved_by: "no_candidates",
167
+ reasoning: "No candidate blocks retrieved — this entity is new to the graph." };
168
+ }
169
+ const top = candidates[0];
170
+ const normEntityValues = entity.primary_values.map(normalizePrimaryValue).filter(Boolean);
171
+ // ── Code-first gate: exact identity + decidable real-owner scope ──
172
+ if (top.identity_score >= 1.0 && !top.scope.is_catch_all && opts.arc_scope) {
173
+ const sameScope = top.scope.value === opts.arc_scope;
174
+ return {
175
+ canonical_name: entity.canonical_name,
176
+ decision: sameScope ? "attach_existing" : "new_entity",
177
+ matched_block_id: sameScope ? top.block.id : undefined,
178
+ matched_block_label: sameScope ? top.block.label : undefined,
179
+ resolved_by: "code_exact",
180
+ reasoning: `Exact unique{} identity match with ${top.block.label}; scope ${sameScope ? `same (${opts.arc_scope})` : `differs (${opts.arc_scope} vs ${top.scope.value})`} — resolved without LLM.`,
181
+ };
182
+ }
183
+ // ── COST GATE: no plausible duplicate → new_entity for free, no LLM ──
184
+ const minForLLM = opts.minIdentityForLLM ?? 0.5;
185
+ if (top.identity_score < minForLLM) {
186
+ return { canonical_name: entity.canonical_name, decision: "new_entity", resolved_by: "no_candidates",
187
+ reasoning: `Top candidate ${top.block.label} identity_score ${top.identity_score.toFixed(2)} < ${minForLLM} — no plausible duplicate; new_entity without LLM.` };
188
+ }
189
+ // ── Ambiguous → LLM resolver (unless codeOnly) ──
190
+ if (opts.codeOnly) {
191
+ return { canonical_name: entity.canonical_name, decision: "new_entity", resolved_by: "code_exact",
192
+ reasoning: `codeOnly: top candidate ${top.block.label} not an exact-identity+real-scope match (identity=${top.identity_score.toFixed(2)}, catch_all=${top.scope.is_catch_all}); deferred to new_entity.` };
193
+ }
194
+ const r = await callStageDResolver(provider, entity, top);
195
+ if (!r.result) {
196
+ return { canonical_name: entity.canonical_name, decision: "new_entity", resolved_by: "llm",
197
+ reasoning: `Resolver ${r.rateLimited ? "rate-limited" : "failed"} — conservative default new_entity (false-NEW is recoverable, false-MATCH is not).` };
198
+ }
199
+ const { decision, flag_reason } = decideFromResolution(r.result.same_entity, r.result.same_scope, top);
200
+ // Carry the matched candidate for BOTH attach AND flag — in both, top.block is the
201
+ // existing block this item resolved against. attach_existing → the block to reuse;
202
+ // flag_for_review → the ambiguous match the agent/reviewer must adjudicate. Only
203
+ // new_entity has no meaningful match (left undefined). Before this, flag_for_review
204
+ // dropped the match → Touchpoint B wrote block_id_b=null → the flag was un-actionable
205
+ // (reviewer/agent had nothing to compare the new block against).
206
+ const matched = decision === "attach_existing" || decision === "flag_for_review";
207
+ return {
208
+ canonical_name: entity.canonical_name,
209
+ decision,
210
+ matched_block_id: matched ? top.block.id : undefined,
211
+ matched_block_label: matched ? top.block.label : undefined,
212
+ resolved_by: "llm",
213
+ reasoning: r.result.reasoning,
214
+ flag_reason,
215
+ };
216
+ }
217
+ export async function resolveArcEntitiesForItems(opts) {
218
+ const result = { entries: [], items_resolved: 0, llm_calls: 0, attached: 0, flagged: 0 };
219
+ const callsBefore = reflectTokenStats.pass_d_resolve.calls;
220
+ for (const item of opts.items) {
221
+ result.items_resolved += 1;
222
+ const primaryVal = extractPrimaryValue(item);
223
+ if (!primaryVal)
224
+ continue; // no identity value → nothing to resolve (e.g. project rows)
225
+ const arcScope = item.project ? scopeSegmentOfLabel(`${item.project}_x_y`) : undefined; // {project} as discrete owner
226
+ const entity = {
227
+ canonical_name: item.project ?? "",
228
+ primary_values: [primaryVal],
229
+ // Concepts for the FINDING step: cheap token set from the item text + value.
230
+ concepts: Array.from(new Set(`${item.project ?? ""} ${primaryVal}`.toLowerCase().split(/[^a-z0-9]+/).filter(t => t.length > 3))).slice(0, 12),
231
+ };
232
+ const res = await resolveArcEntity({
233
+ db: opts.db, provider: opts.provider, entity, arc_scope: arcScope,
234
+ k: opts.k, minIdentityForLLM: opts.minIdentityForLLM, codeOnly: opts.codeOnly,
235
+ });
236
+ // Only attach/flag outcomes produce a flag at Touchpoint B; new_entity is the no-op default.
237
+ if (res.decision === "attach_existing" || res.decision === "flag_for_review") {
238
+ result.entries.push({
239
+ item_id: item.id,
240
+ decision: res.decision,
241
+ matched_block_id: res.matched_block_id,
242
+ matched_block_label: res.matched_block_label,
243
+ resolved_by: res.resolved_by,
244
+ reasoning: res.reasoning,
245
+ flag_reason: res.flag_reason,
246
+ });
247
+ if (res.decision === "attach_existing")
248
+ result.attached += 1;
249
+ else
250
+ result.flagged += 1;
251
+ }
252
+ }
253
+ result.llm_calls = reflectTokenStats.pass_d_resolve.calls - callsBefore;
254
+ return result;
255
+ }
256
+ //# sourceMappingURL=stage-d-resolve-graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stage-d-resolve-graph.js","sourceRoot":"","sources":["../../../src/middleware/reflect/stage-d-resolve-graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { Pass0Result, Pass1Item } from "./types.js";
2
+ export interface SynthesizeOptions {
3
+ /** ID prefix — defaults to "syn" so synthesized items are traceable in logs. */
4
+ idPrefix?: string;
5
+ }
6
+ /**
7
+ * Translate each Pass 0 `replacements[]` entry into one synthesized `dead_end`
8
+ * Pass-1 item — the half the LLM drops.
9
+ *
10
+ * Deterministic. No LLM. Output is a flat array; caller merges it with the LLM's
11
+ * Pass 1 items into a single Pass1Result before handing to Pass 2. The matching
12
+ * `decision` is left entirely to the LLM, so the two producers never overlap.
13
+ */
14
+ export declare function synthesizeFromSceneCard(sceneCard: Pass0Result, agentOutput: string, opts?: SynthesizeOptions): Pass1Item[];
15
+ //# sourceMappingURL=synthesizeFromSceneCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synthesizeFromSceneCard.d.ts","sourceRoot":"","sources":["../../../src/middleware/reflect/synthesizeFromSceneCard.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AA2CzD,MAAM,WAAW,iBAAiB;IAChC,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,WAAW,EACtB,WAAW,EAAE,MAAM,EACnB,IAAI,GAAE,iBAAsB,GAC3B,SAAS,EAAE,CAwBb"}
@@ -0,0 +1,91 @@
1
+ // Code-synthesis of the one Pass-1 item the LLM provably cannot produce reliably:
2
+ // the dead_end half of a replacement.
3
+ //
4
+ // THE PROBLEM. "I went with PostgreSQL, replacing SQLite" is one sentence but two
5
+ // events — a choice made (decision) AND a path abandoned (dead_end). Pass 1's
6
+ // per-sentence chunking emits one item and drops the dead_end (observed
7
+ // 2026-05-21, SQLite case). A prompt rule cannot beat chunking.
8
+ //
9
+ // THE SCOPE — deliberately one job. The LLM reliably extracts the *decision* half
10
+ // of a replacement (an affirmative, single-chunk statement) and reliably *finds*
11
+ // in-progress work. Its single proven blind spot is the dead_end half. So this
12
+ // module synthesizes ONLY that:
13
+ //
14
+ // each replacements[] entry → exactly one dead_end item
15
+ //
16
+ // It does NOT emit the decision (the LLM owns that) and does NOT emit tasks from
17
+ // in_flight[] (the LLM finds those; Pass 2 re-verifies their type). Keeping the
18
+ // synthesizer and the LLM on disjoint jobs is what makes duplication structurally
19
+ // impossible — see docs/PIPELINE-REBUILD-PLAN.md, the seam-contract section.
20
+ //
21
+ // HONEST LIMIT. This is deterministic, but its input is not: replacements[] is
22
+ // produced by Pass 0, an LLM. If Pass 0 mislabels an in-place update (e.g. a doc
23
+ // revision) as a replacement, this module faithfully emits a nonsense dead_end.
24
+ // Determinism bounds the transform, never the result. That residual is the
25
+ // Pass 0 → synthesizer seam and is fixed upstream, not here.
26
+ const EXCERPT_WINDOW = 150;
27
+ const EXCERPT_PAD = Math.floor((EXCERPT_WINDOW - 60) / 2); // leave room for the matched term itself
28
+ /**
29
+ * Find a ~150-char window of `agentOutput` that contains `needle` (case-insensitive).
30
+ * Returns the verbatim slice from the original casing. Falls back to "" if no match
31
+ * — acceptable per Pass1Item schema, and downstream still gets correct text/type.
32
+ */
33
+ function liftExcerpt(agentOutput, needle) {
34
+ if (!agentOutput || !needle)
35
+ return "";
36
+ const hay = agentOutput.toLowerCase();
37
+ const n = needle.toLowerCase().trim();
38
+ if (n.length === 0)
39
+ return "";
40
+ const idx = hay.indexOf(n);
41
+ if (idx === -1)
42
+ return "";
43
+ const start = Math.max(0, idx - EXCERPT_PAD);
44
+ const end = Math.min(agentOutput.length, idx + n.length + EXCERPT_PAD);
45
+ let slice = agentOutput.slice(start, end);
46
+ if (slice.length > EXCERPT_WINDOW)
47
+ slice = slice.slice(0, EXCERPT_WINDOW);
48
+ return slice.trim();
49
+ }
50
+ /**
51
+ * Pick the most-likely-to-match needle for a replacements[] entry.
52
+ * Prefer the predecessor name (the abandoned thing this dead_end is about),
53
+ * then fall back to the replacement, then the function string.
54
+ */
55
+ function pickReplacementExcerpt(agentOutput, predecessor, replacement, func) {
56
+ return (liftExcerpt(agentOutput, predecessor) ||
57
+ liftExcerpt(agentOutput, replacement) ||
58
+ liftExcerpt(agentOutput, func) ||
59
+ "");
60
+ }
61
+ /**
62
+ * Translate each Pass 0 `replacements[]` entry into one synthesized `dead_end`
63
+ * Pass-1 item — the half the LLM drops.
64
+ *
65
+ * Deterministic. No LLM. Output is a flat array; caller merges it with the LLM's
66
+ * Pass 1 items into a single Pass1Result before handing to Pass 2. The matching
67
+ * `decision` is left entirely to the LLM, so the two producers never overlap.
68
+ */
69
+ export function synthesizeFromSceneCard(sceneCard, agentOutput, opts = {}) {
70
+ const items = [];
71
+ const prefix = opts.idPrefix ?? "syn";
72
+ let seq = 1;
73
+ // ── REPLACEMENTS → one dead_end each ────────────────────────────────────────
74
+ // The decision half is the LLM's job (it never misses it). Emitting it here too
75
+ // would duplicate. The dead_end is the LLM's blind spot — so it is ours, alone.
76
+ for (const r of sceneCard.replacements ?? []) {
77
+ if (!r?.predecessor || !r?.replacement || !r?.function)
78
+ continue;
79
+ const { predecessor, replacement, function: func } = r;
80
+ items.push({
81
+ id: `${prefix}_${seq++}`,
82
+ text: `${predecessor} was abandoned as the ${func}, replaced by ${replacement}`,
83
+ source: "output",
84
+ excerpt: pickReplacementExcerpt(agentOutput, predecessor, replacement, func),
85
+ provisional_type: "dead_end",
86
+ extraction_reasoning: "Synthesized from scene card replacements[] entry (predecessor abandoned in real use).",
87
+ });
88
+ }
89
+ return items;
90
+ }
91
+ //# sourceMappingURL=synthesizeFromSceneCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synthesizeFromSceneCard.js","sourceRoot":"","sources":["../../../src/middleware/reflect/synthesizeFromSceneCard.ts"],"names":[],"mappings":"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"}