@remnic/core 10.0.4 → 10.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (299) hide show
  1. package/dist/access-admin-ops-surface.js +46 -46
  2. package/dist/access-authorization-probe.js +47 -47
  3. package/dist/access-boundary.js +46 -46
  4. package/dist/access-cli.d.ts.map +1 -1
  5. package/dist/access-cli.js +117 -112
  6. package/dist/access-cli.js.map +1 -1
  7. package/dist/access-extraction-force-flush.js +46 -46
  8. package/dist/access-http-briefing.js +47 -47
  9. package/dist/access-http-query.js +48 -48
  10. package/dist/access-http.d.ts.map +1 -1
  11. package/dist/access-http.js +69 -68
  12. package/dist/access-identity-continuity-surface.js +46 -46
  13. package/dist/access-lcm-surface.js +46 -46
  14. package/dist/access-mcp-correction-tools.d.ts +10 -0
  15. package/dist/access-mcp-correction-tools.d.ts.map +1 -0
  16. package/dist/access-mcp-correction-tools.js +8 -0
  17. package/dist/access-mcp.d.ts.map +1 -1
  18. package/dist/access-mcp.js +60 -59
  19. package/dist/access-namespace-preflight.js +46 -46
  20. package/dist/access-observe-write-category.js +3 -3
  21. package/dist/access-observe-write-surface.js +46 -46
  22. package/dist/access-offline-manifest.js +5 -5
  23. package/dist/access-operations-batch.js +49 -49
  24. package/dist/access-operations.d.ts +1 -0
  25. package/dist/access-operations.d.ts.map +1 -1
  26. package/dist/access-operations.js +56 -56
  27. package/dist/access-recall-concurrency.js +46 -46
  28. package/dist/access-recall-diagnostics.js +2 -2
  29. package/dist/access-recall-response.js +46 -46
  30. package/dist/access-recall-surface.js +46 -46
  31. package/dist/access-service.d.ts.map +1 -1
  32. package/dist/access-service.js +46 -46
  33. package/dist/access-surface-catalog.js +48 -48
  34. package/dist/active-recall.js +22 -22
  35. package/dist/adapters/index.js +4 -4
  36. package/dist/adapters/registry.js +2 -2
  37. package/dist/auto-sync-FN7E3OTO.js +2 -2
  38. package/dist/briefing.js +18 -18
  39. package/dist/buffer.js +1 -1
  40. package/dist/causal-consolidation.js +18 -18
  41. package/dist/{chunk-5YDWSWBU.js → chunk-2CP577K6.js} +2 -2
  42. package/dist/{chunk-ABET5LA5.js → chunk-37HCPM56.js} +23 -23
  43. package/dist/{chunk-5QHTQMRL.js → chunk-4CWUZBPF.js} +8 -6
  44. package/dist/chunk-4CWUZBPF.js.map +1 -0
  45. package/dist/{chunk-H6FA36LC.js → chunk-4K2H4KTR.js} +5 -5
  46. package/dist/{chunk-TSEUVMJL.js → chunk-52CQKST6.js} +39 -39
  47. package/dist/{chunk-H7BZBSP6.js → chunk-52II7PB6.js} +4 -4
  48. package/dist/{chunk-RH6MQ5NG.js → chunk-5BPXMAUP.js} +17 -68
  49. package/dist/chunk-5BPXMAUP.js.map +1 -0
  50. package/dist/{chunk-WLC6XA6C.js → chunk-5BY3IA2U.js} +16 -53
  51. package/dist/chunk-5BY3IA2U.js.map +1 -0
  52. package/dist/{chunk-ABDTBGI2.js → chunk-5CQO6LVM.js} +2 -2
  53. package/dist/{chunk-HSZBALHV.js → chunk-5LNPW7NE.js} +2 -2
  54. package/dist/{chunk-U3LVARGV.js → chunk-5X4ZJESN.js} +2 -2
  55. package/dist/{chunk-SNGNGH53.js → chunk-63UNVGZW.js} +4 -4
  56. package/dist/{chunk-2KB7TTAP.js → chunk-64S6X4IU.js} +4 -4
  57. package/dist/{chunk-3QAIX7TV.js → chunk-6KHF6PAB.js} +2 -2
  58. package/dist/{chunk-MYBCB4AT.js → chunk-6T42L5FI.js} +2 -2
  59. package/dist/{chunk-R6EOFKZG.js → chunk-7LYRFI5A.js} +2 -2
  60. package/dist/{chunk-4NFRYOHT.js → chunk-ANZXWOYD.js} +2 -2
  61. package/dist/{chunk-QDKABMUE.js → chunk-AXC7UTLM.js} +2 -2
  62. package/dist/{chunk-5XXTZ4Y7.js → chunk-B657ZGDH.js} +2 -2
  63. package/dist/{chunk-NSQ3GUVO.js → chunk-CYEK6Z3P.js} +4 -4
  64. package/dist/{chunk-IRYKRBEX.js → chunk-DJMVSUPK.js} +3 -3
  65. package/dist/{chunk-GLS3A4SQ.js → chunk-DST7HRSG.js} +2 -2
  66. package/dist/{chunk-UCCB7RKF.js → chunk-EMVJU7WC.js} +2 -2
  67. package/dist/{chunk-IY7ZISXV.js → chunk-ENNC3RZ6.js} +2 -2
  68. package/dist/{chunk-QLK3SL7Q.js → chunk-ETSJD5IV.js} +131 -12
  69. package/dist/chunk-ETSJD5IV.js.map +1 -0
  70. package/dist/{chunk-PTFL3INS.js → chunk-FC6RCOIU.js} +2 -2
  71. package/dist/{chunk-CQQTEDHS.js → chunk-FLV7M7CT.js} +2 -2
  72. package/dist/{chunk-IXF7TRMQ.js → chunk-FRH2UC7Q.js} +2 -2
  73. package/dist/{chunk-3SL52JKD.js → chunk-FZVROZKC.js} +5 -5
  74. package/dist/{chunk-Z2EVKNZR.js → chunk-GEGUBU3D.js} +2 -2
  75. package/dist/{chunk-LIGP5M2C.js → chunk-GF4H3B3R.js} +8 -8
  76. package/dist/{chunk-7OOW72QA.js → chunk-GVUW5XK5.js} +305 -136
  77. package/dist/chunk-GVUW5XK5.js.map +1 -0
  78. package/dist/{chunk-XTWF5XR6.js → chunk-HPAOMYKM.js} +67 -67
  79. package/dist/{chunk-ZOGZMAGI.js → chunk-I25RINZK.js} +2 -2
  80. package/dist/{chunk-FMIVV5SV.js → chunk-I56MTWE7.js} +2 -2
  81. package/dist/{chunk-EUL3S3LE.js → chunk-J5WI4QRP.js} +4 -4
  82. package/dist/{chunk-436IRJUD.js → chunk-JA54KIYD.js} +2 -2
  83. package/dist/{chunk-QWNBQ2T5.js → chunk-JMF5Q4JY.js} +10 -10
  84. package/dist/{chunk-IDSSDL4W.js → chunk-JXSYWTFK.js} +21 -4
  85. package/dist/{chunk-IDSSDL4W.js.map → chunk-JXSYWTFK.js.map} +1 -1
  86. package/dist/chunk-KIUVEMBI.js +49 -0
  87. package/dist/chunk-KIUVEMBI.js.map +1 -0
  88. package/dist/{chunk-IINXHPCV.js → chunk-KQI2PKYP.js} +2 -2
  89. package/dist/{chunk-RGPPNNDJ.js → chunk-KSUOM3YU.js} +9 -9
  90. package/dist/{chunk-CXG2T7BJ.js → chunk-KZEMFD6E.js} +3 -3
  91. package/dist/{chunk-O57VUN4U.js → chunk-L2VS27PZ.js} +2 -2
  92. package/dist/{chunk-IVGJXS5F.js → chunk-L34W4W4I.js} +2 -2
  93. package/dist/{chunk-MEP3POVW.js → chunk-L3PWXD73.js} +2 -2
  94. package/dist/{chunk-NQHSXHJP.js → chunk-L6GNS5GB.js} +2 -2
  95. package/dist/{chunk-YMXCJ7SE.js → chunk-M47Q6566.js} +2 -2
  96. package/dist/{chunk-DQJCQHII.js → chunk-MQNOIH2C.js} +6 -6
  97. package/dist/{chunk-IDSZNHIP.js → chunk-MULNBSPP.js} +4 -4
  98. package/dist/{chunk-4DXVWBDB.js → chunk-NBQIFCJE.js} +2 -2
  99. package/dist/{chunk-H2XCCUOT.js → chunk-NHSVW7UT.js} +15 -15
  100. package/dist/{chunk-BDHWKFGM.js → chunk-OFEHITAZ.js} +2 -2
  101. package/dist/{chunk-RYN4AIRM.js → chunk-OZABSIOV.js} +4 -4
  102. package/dist/{chunk-Y7CXM7UM.js → chunk-QMFKW4OU.js} +3 -3
  103. package/dist/{chunk-Z63GU5NN.js → chunk-QWWMS4AE.js} +1 -1
  104. package/dist/chunk-QWWMS4AE.js.map +1 -0
  105. package/dist/{chunk-R4O2G6ML.js → chunk-RSMIRLKM.js} +2 -2
  106. package/dist/{chunk-6AH2DDHI.js → chunk-S5TGRZWY.js} +2 -2
  107. package/dist/{chunk-TYOBAFCY.js → chunk-SNXBXYUE.js} +3 -3
  108. package/dist/{chunk-MEMH5NKJ.js → chunk-SUAX5JWY.js} +2 -2
  109. package/dist/{chunk-IHIP7TJ3.js → chunk-SWRN6U7Q.js} +2 -2
  110. package/dist/{chunk-DBA2W6VV.js → chunk-SZXPKUMN.js} +6 -6
  111. package/dist/{chunk-WQUGCOKF.js → chunk-TFA6HPOA.js} +4 -4
  112. package/dist/{chunk-VWCFR4NR.js → chunk-U6OXJQEH.js} +5 -5
  113. package/dist/{chunk-DYRXRQHV.js → chunk-V32NHP2R.js} +2 -2
  114. package/dist/{chunk-ORAL4HJC.js → chunk-WG4TMZJ2.js} +2 -2
  115. package/dist/{chunk-QVBB2CLG.js → chunk-WRICYGYG.js} +27 -26
  116. package/dist/chunk-WRICYGYG.js.map +1 -0
  117. package/dist/{chunk-CV5AMCPX.js → chunk-XPRAOTJY.js} +2 -2
  118. package/dist/{chunk-RZCRXCLI.js → chunk-XQSJXNWC.js} +2 -2
  119. package/dist/{chunk-P22M3DX3.js → chunk-YJAOYEWI.js} +2 -2
  120. package/dist/{chunk-OAFRMLL4.js → chunk-YJEUHGZZ.js} +2 -2
  121. package/dist/cli.js +89 -88
  122. package/dist/coding/export-okf-codegraph.js +16 -16
  123. package/dist/compounding/engine.js +17 -17
  124. package/dist/config.d.ts.map +1 -1
  125. package/dist/config.js +22 -22
  126. package/dist/connectors/codex-materialize-runner.js +17 -17
  127. package/dist/connectors/index.js +17 -17
  128. package/dist/consolidation-provenance-check.js +2 -2
  129. package/dist/contradiction/index.js +7 -7
  130. package/dist/convergence-refresh.js +19 -19
  131. package/dist/conversation-index/backend.js +2 -2
  132. package/dist/corpus-watermark.js +19 -19
  133. package/dist/correction/correction-access-wiring.d.ts +6 -6
  134. package/dist/correction/correction-access-wiring.d.ts.map +1 -1
  135. package/dist/correction/correction-classify.d.ts +25 -0
  136. package/dist/correction/correction-classify.d.ts.map +1 -0
  137. package/dist/correction/correction-config.d.ts +11 -0
  138. package/dist/correction/correction-config.d.ts.map +1 -0
  139. package/dist/correction/correction-contract.d.ts +13 -1
  140. package/dist/correction/correction-contract.d.ts.map +1 -1
  141. package/dist/correction/correction-executor.d.ts +2 -0
  142. package/dist/correction/correction-executor.d.ts.map +1 -1
  143. package/dist/correction/correction-planner.d.ts +24 -3
  144. package/dist/correction/correction-planner.d.ts.map +1 -1
  145. package/dist/entity-retrieval.js +17 -17
  146. package/dist/event-order-recall.js +2 -2
  147. package/dist/explicit-capture.js +2 -2
  148. package/dist/external-wiki-access.js +47 -47
  149. package/dist/extraction-span-materialize.js +2 -2
  150. package/dist/extraction.js +22 -22
  151. package/dist/harmonic-retrieval.js +17 -17
  152. package/dist/index.js +189 -188
  153. package/dist/lcm/index.js +3 -3
  154. package/dist/local-llm.d.ts.map +1 -1
  155. package/dist/local-llm.js +1 -1
  156. package/dist/location/index.js +19 -19
  157. package/dist/maintenance/memory-governance.js +17 -17
  158. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +17 -17
  159. package/dist/maintenance/rebuild-memory-projection-runner.js +19 -19
  160. package/dist/maintenance/rebuild-memory-projection.js +18 -18
  161. package/dist/memory-browse-operations.js +47 -47
  162. package/dist/memory-browse.js +1 -1
  163. package/dist/memory-subject.js +1 -1
  164. package/dist/namespaces/migrate.js +18 -18
  165. package/dist/namespaces/search.js +6 -6
  166. package/dist/namespaces/storage.js +17 -17
  167. package/dist/operator-doctor-corpus.js +20 -20
  168. package/dist/operator-toolkit.js +32 -32
  169. package/dist/orchestration/maintenance.js +28 -28
  170. package/dist/orchestration/session-context.d.ts.map +1 -1
  171. package/dist/orchestrator.js +113 -112
  172. package/dist/recall-explain-renderer.js +3 -3
  173. package/dist/recall-navigate-access.js +2 -2
  174. package/dist/recall-navigate-disclosure.js +2 -2
  175. package/dist/recall-navigate.js +2 -2
  176. package/dist/recall-navigation-operations.js +47 -47
  177. package/dist/recall-navigation.js +46 -46
  178. package/dist/recall-why-service.js +2 -2
  179. package/dist/recall-xray-cli.js +4 -4
  180. package/dist/recall-xray-renderer.js +3 -3
  181. package/dist/recall-xray.js +2 -2
  182. package/dist/reconcile/manifest.js +3 -3
  183. package/dist/{resolution-RSG4HZTL.js → resolution-TV3F7ZTH.js} +7 -7
  184. package/dist/resolution-TV3F7ZTH.js.map +1 -0
  185. package/dist/resume-bundles.js +23 -23
  186. package/dist/salvage-envelope.js +1 -1
  187. package/dist/search/factory.js +5 -5
  188. package/dist/search/index.js +9 -9
  189. package/dist/semantic-consolidation.js +23 -23
  190. package/dist/semantic-rule-promotion.js +17 -17
  191. package/dist/semantic-rule-verifier.js +17 -17
  192. package/dist/source-agent-qualifier.js +17 -17
  193. package/dist/standup/build.js +17 -17
  194. package/dist/storage.js +16 -16
  195. package/dist/subject-config.js +1 -1
  196. package/dist/summarizer.js +3 -3
  197. package/dist/support-passport/index.js +63 -63
  198. package/dist/transfer/export-okf.js +17 -17
  199. package/dist/types.d.ts +6 -23
  200. package/dist/types.d.ts.map +1 -1
  201. package/dist/types.js +1 -1
  202. package/dist/verified-recall.js +17 -17
  203. package/dist/who-knows-cli.js +18 -18
  204. package/dist/who-knows.js +17 -17
  205. package/dist/write-envelope.js +1 -1
  206. package/package.json +2 -2
  207. package/src/access-cli.ts +4 -0
  208. package/src/access-http.ts +1 -0
  209. package/src/access-mcp-correction-tools.ts +56 -0
  210. package/src/access-mcp.ts +4 -49
  211. package/src/access-operations.ts +3 -0
  212. package/src/access-service.ts +12 -21
  213. package/src/config.test.ts +26 -0
  214. package/src/config.ts +4 -60
  215. package/src/correction/correction-access-wiring.ts +56 -16
  216. package/src/correction/correction-classify.test.ts +185 -0
  217. package/src/correction/correction-classify.ts +157 -0
  218. package/src/correction/correction-config.ts +93 -0
  219. package/src/correction/correction-contract.ts +61 -14
  220. package/src/correction/correction-executor.test.ts +102 -2
  221. package/src/correction/correction-executor.ts +19 -1
  222. package/src/correction/correction-planner.test.ts +141 -0
  223. package/src/correction/correction-planner.ts +117 -11
  224. package/src/correction/correction-surfaces.test.ts +22 -1
  225. package/src/local-llm-qos.test.ts +36 -0
  226. package/src/local-llm.ts +20 -3
  227. package/src/orchestration/session-context.ts +0 -15
  228. package/src/recall-handles-wiring.test.ts +24 -0
  229. package/src/types.ts +6 -23
  230. package/dist/chunk-5QHTQMRL.js.map +0 -1
  231. package/dist/chunk-7OOW72QA.js.map +0 -1
  232. package/dist/chunk-QLK3SL7Q.js.map +0 -1
  233. package/dist/chunk-QVBB2CLG.js.map +0 -1
  234. package/dist/chunk-RH6MQ5NG.js.map +0 -1
  235. package/dist/chunk-WLC6XA6C.js.map +0 -1
  236. package/dist/chunk-Z63GU5NN.js.map +0 -1
  237. /package/dist/{resolution-RSG4HZTL.js.map → access-mcp-correction-tools.js.map} +0 -0
  238. /package/dist/{chunk-5YDWSWBU.js.map → chunk-2CP577K6.js.map} +0 -0
  239. /package/dist/{chunk-ABET5LA5.js.map → chunk-37HCPM56.js.map} +0 -0
  240. /package/dist/{chunk-H6FA36LC.js.map → chunk-4K2H4KTR.js.map} +0 -0
  241. /package/dist/{chunk-TSEUVMJL.js.map → chunk-52CQKST6.js.map} +0 -0
  242. /package/dist/{chunk-H7BZBSP6.js.map → chunk-52II7PB6.js.map} +0 -0
  243. /package/dist/{chunk-ABDTBGI2.js.map → chunk-5CQO6LVM.js.map} +0 -0
  244. /package/dist/{chunk-HSZBALHV.js.map → chunk-5LNPW7NE.js.map} +0 -0
  245. /package/dist/{chunk-U3LVARGV.js.map → chunk-5X4ZJESN.js.map} +0 -0
  246. /package/dist/{chunk-SNGNGH53.js.map → chunk-63UNVGZW.js.map} +0 -0
  247. /package/dist/{chunk-2KB7TTAP.js.map → chunk-64S6X4IU.js.map} +0 -0
  248. /package/dist/{chunk-3QAIX7TV.js.map → chunk-6KHF6PAB.js.map} +0 -0
  249. /package/dist/{chunk-MYBCB4AT.js.map → chunk-6T42L5FI.js.map} +0 -0
  250. /package/dist/{chunk-R6EOFKZG.js.map → chunk-7LYRFI5A.js.map} +0 -0
  251. /package/dist/{chunk-4NFRYOHT.js.map → chunk-ANZXWOYD.js.map} +0 -0
  252. /package/dist/{chunk-QDKABMUE.js.map → chunk-AXC7UTLM.js.map} +0 -0
  253. /package/dist/{chunk-5XXTZ4Y7.js.map → chunk-B657ZGDH.js.map} +0 -0
  254. /package/dist/{chunk-NSQ3GUVO.js.map → chunk-CYEK6Z3P.js.map} +0 -0
  255. /package/dist/{chunk-IRYKRBEX.js.map → chunk-DJMVSUPK.js.map} +0 -0
  256. /package/dist/{chunk-GLS3A4SQ.js.map → chunk-DST7HRSG.js.map} +0 -0
  257. /package/dist/{chunk-UCCB7RKF.js.map → chunk-EMVJU7WC.js.map} +0 -0
  258. /package/dist/{chunk-IY7ZISXV.js.map → chunk-ENNC3RZ6.js.map} +0 -0
  259. /package/dist/{chunk-PTFL3INS.js.map → chunk-FC6RCOIU.js.map} +0 -0
  260. /package/dist/{chunk-CQQTEDHS.js.map → chunk-FLV7M7CT.js.map} +0 -0
  261. /package/dist/{chunk-IXF7TRMQ.js.map → chunk-FRH2UC7Q.js.map} +0 -0
  262. /package/dist/{chunk-3SL52JKD.js.map → chunk-FZVROZKC.js.map} +0 -0
  263. /package/dist/{chunk-Z2EVKNZR.js.map → chunk-GEGUBU3D.js.map} +0 -0
  264. /package/dist/{chunk-LIGP5M2C.js.map → chunk-GF4H3B3R.js.map} +0 -0
  265. /package/dist/{chunk-XTWF5XR6.js.map → chunk-HPAOMYKM.js.map} +0 -0
  266. /package/dist/{chunk-ZOGZMAGI.js.map → chunk-I25RINZK.js.map} +0 -0
  267. /package/dist/{chunk-FMIVV5SV.js.map → chunk-I56MTWE7.js.map} +0 -0
  268. /package/dist/{chunk-EUL3S3LE.js.map → chunk-J5WI4QRP.js.map} +0 -0
  269. /package/dist/{chunk-436IRJUD.js.map → chunk-JA54KIYD.js.map} +0 -0
  270. /package/dist/{chunk-QWNBQ2T5.js.map → chunk-JMF5Q4JY.js.map} +0 -0
  271. /package/dist/{chunk-IINXHPCV.js.map → chunk-KQI2PKYP.js.map} +0 -0
  272. /package/dist/{chunk-RGPPNNDJ.js.map → chunk-KSUOM3YU.js.map} +0 -0
  273. /package/dist/{chunk-CXG2T7BJ.js.map → chunk-KZEMFD6E.js.map} +0 -0
  274. /package/dist/{chunk-O57VUN4U.js.map → chunk-L2VS27PZ.js.map} +0 -0
  275. /package/dist/{chunk-IVGJXS5F.js.map → chunk-L34W4W4I.js.map} +0 -0
  276. /package/dist/{chunk-MEP3POVW.js.map → chunk-L3PWXD73.js.map} +0 -0
  277. /package/dist/{chunk-NQHSXHJP.js.map → chunk-L6GNS5GB.js.map} +0 -0
  278. /package/dist/{chunk-YMXCJ7SE.js.map → chunk-M47Q6566.js.map} +0 -0
  279. /package/dist/{chunk-DQJCQHII.js.map → chunk-MQNOIH2C.js.map} +0 -0
  280. /package/dist/{chunk-IDSZNHIP.js.map → chunk-MULNBSPP.js.map} +0 -0
  281. /package/dist/{chunk-4DXVWBDB.js.map → chunk-NBQIFCJE.js.map} +0 -0
  282. /package/dist/{chunk-H2XCCUOT.js.map → chunk-NHSVW7UT.js.map} +0 -0
  283. /package/dist/{chunk-BDHWKFGM.js.map → chunk-OFEHITAZ.js.map} +0 -0
  284. /package/dist/{chunk-RYN4AIRM.js.map → chunk-OZABSIOV.js.map} +0 -0
  285. /package/dist/{chunk-Y7CXM7UM.js.map → chunk-QMFKW4OU.js.map} +0 -0
  286. /package/dist/{chunk-R4O2G6ML.js.map → chunk-RSMIRLKM.js.map} +0 -0
  287. /package/dist/{chunk-6AH2DDHI.js.map → chunk-S5TGRZWY.js.map} +0 -0
  288. /package/dist/{chunk-TYOBAFCY.js.map → chunk-SNXBXYUE.js.map} +0 -0
  289. /package/dist/{chunk-MEMH5NKJ.js.map → chunk-SUAX5JWY.js.map} +0 -0
  290. /package/dist/{chunk-IHIP7TJ3.js.map → chunk-SWRN6U7Q.js.map} +0 -0
  291. /package/dist/{chunk-DBA2W6VV.js.map → chunk-SZXPKUMN.js.map} +0 -0
  292. /package/dist/{chunk-WQUGCOKF.js.map → chunk-TFA6HPOA.js.map} +0 -0
  293. /package/dist/{chunk-VWCFR4NR.js.map → chunk-U6OXJQEH.js.map} +0 -0
  294. /package/dist/{chunk-DYRXRQHV.js.map → chunk-V32NHP2R.js.map} +0 -0
  295. /package/dist/{chunk-ORAL4HJC.js.map → chunk-WG4TMZJ2.js.map} +0 -0
  296. /package/dist/{chunk-CV5AMCPX.js.map → chunk-XPRAOTJY.js.map} +0 -0
  297. /package/dist/{chunk-RZCRXCLI.js.map → chunk-XQSJXNWC.js.map} +0 -0
  298. /package/dist/{chunk-P22M3DX3.js.map → chunk-YJAOYEWI.js.map} +0 -0
  299. /package/dist/{chunk-OAFRMLL4.js.map → chunk-YJEUHGZZ.js.map} +0 -0
package/src/access-cli.ts CHANGED
@@ -207,6 +207,7 @@ function usage(): string {
207
207
  "Correct options (issue #1580 — one plan/apply pipeline for all corrections):",
208
208
  " --text \"<correction>\" plan a correction from natural language",
209
209
  " --id <memoryId> (repeatable) explicit target memory ids",
210
+ " --duplicate-of <memoryId> winner id; requires exactly one --id (skips the classifier)",
210
211
  " --apply apply a pending plan (requires --plan-id + --confirm)",
211
212
  " --plan-id <id> the plan to apply or discard",
212
213
  " --confirm confirm the apply (safety guard, rule 48)",
@@ -297,6 +298,7 @@ const COMMAND_SPECS: Record<CommandName, CommandSpec> = {
297
298
  valueOptions: new Set([
298
299
  "text",
299
300
  "id",
301
+ "duplicate-of",
300
302
  "plan-id",
301
303
  "namespace",
302
304
  "session-key",
@@ -830,6 +832,7 @@ async function runCorrect(args: ParsedArgs, preferredId?: string): Promise<void>
830
832
  // so schema validation + namespace policy reach this path (same as MCP/HTTP).
831
833
  const text = requireOption(args, "text");
832
834
  const targetIds = getAllOptions(args, "id");
835
+ const duplicateOf = getLastOption(args, "duplicate-of");
833
836
  const planOp = getOperation("memory_correct_plan");
834
837
  if (!planOp) {
835
838
  throw new Error("access-boundary: operation not registered: memory_correct_plan");
@@ -838,6 +841,7 @@ async function runCorrect(args: ParsedArgs, preferredId?: string): Promise<void>
838
841
  {
839
842
  text,
840
843
  ...(targetIds.length > 0 ? { targetIds } : {}),
844
+ ...(duplicateOf ? { duplicateOf } : {}),
841
845
  ...(sessionKey ? { sessionKey } : {}),
842
846
  ...(namespace ? { namespace } : {}),
843
847
  },
@@ -1999,6 +1999,7 @@ export class EngramAccessHttpServer extends ReviewDeckAccessHttpBase {
1999
1999
  const output = (await op.run(this.gatedBodyNamespace(req, body), {
2000
2000
  service: this.service,
2001
2001
  authenticatedPrincipal: this.resolveRequestPrincipal(req),
2002
+ ...(abortSignal ? { abortSignal } : {}),
2002
2003
  })) as { result: unknown };
2003
2004
  this.recordWriteRateLimitHit(req);
2004
2005
  this.respondJson(res, 200, output.result);
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Correction MCP tool descriptors.
3
+ *
4
+ * Extracted from access-mcp.ts (over its fileSizeGrandfather ceiling) so
5
+ * `duplicateOf` can land without growing that file. Aliases are applied by
6
+ * the caller via withToolAliases.
7
+ */
8
+ import type { McpTool } from "./access-mcp.js";
9
+
10
+ export const correctionMcpTools: McpTool[] = [
11
+ {
12
+ name: "engram.memory_correct_plan",
13
+ description:
14
+ "Plan a memory correction from a plain-language statement. Returns a CorrectionPlan with a diff preview; apply via memory_correct_apply. Pass duplicateOf plus one targetIds entry to supersede that duplicate without calling the classifier.",
15
+ inputSchema: {
16
+ type: "object",
17
+ properties: {
18
+ text: {
19
+ type: "string",
20
+ description: 'The natural-language correction (e.g. "we migrated to MySQL in March").',
21
+ },
22
+ targetIds: {
23
+ type: "array",
24
+ items: { type: "string" },
25
+ description:
26
+ "Optional explicit target memory ids. When omitted, the planner searches. With duplicateOf, pass exactly the duplicate id.",
27
+ },
28
+ duplicateOf: {
29
+ type: "string",
30
+ description:
31
+ "Optional winner memory id. Requires targetIds to be exactly the duplicate. Skips classification and drafts one recoverable supersede (no hard delete) linking the duplicate to this id.",
32
+ },
33
+ sessionKey: { type: "string", description: "Session identifier for namespace resolution." },
34
+ namespace: { type: "string", description: "Optional explicit namespace (validated by policy)." },
35
+ },
36
+ required: ["text"],
37
+ additionalProperties: false,
38
+ },
39
+ },
40
+ {
41
+ name: "engram.memory_correct_apply",
42
+ description:
43
+ "Apply a planned memory correction by planId. Requires confirm: true when correction.applyRequiresConfirm is on (default).",
44
+ inputSchema: {
45
+ type: "object",
46
+ properties: {
47
+ planId: { type: "string", description: "The plan id returned by memory_correct_plan." },
48
+ confirm: { type: "boolean", description: "Must be true to apply (safety guard)." },
49
+ sessionKey: { type: "string", description: "Session identifier for namespace resolution." },
50
+ namespace: { type: "string", description: "Optional explicit namespace (validated by policy)." },
51
+ },
52
+ required: ["planId"],
53
+ additionalProperties: false,
54
+ },
55
+ },
56
+ ];
package/src/access-mcp.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { sharedContextMcpTools } from "./access-mcp-shared-context-tools.js";
2
+ import { correctionMcpTools } from "./access-mcp-correction-tools.js";
2
3
  import { randomUUID } from "node:crypto";
3
4
  import {
4
5
  MCP_ADMIN_OPS_MIGRATED_OPERATIONS,
@@ -2133,56 +2134,10 @@ export class EngramMcpServer {
2133
2134
  this.tools = [...this.tools, ...deltaTools];
2134
2135
  }
2135
2136
  if (this.correctionVisible) {
2136
- // Correction Contract (issue #1580) — one plan/apply pipeline for every
2137
- // memory correction. Both tools dispatch through the boundary operations
2138
- // (memory_correct_plan / memory_correct_apply) which delegate to the
2139
- // CorrectionService.
2140
- const planTool = withToolAliases(
2141
- {
2142
- name: "engram.memory_correct_plan",
2143
- description:
2144
- "Plan a memory correction from a plain-language statement (issue #1580). Returns a CorrectionPlan with a diff preview; apply via memory_correct_apply.",
2145
- inputSchema: {
2146
- type: "object",
2147
- properties: {
2148
- text: {
2149
- type: "string",
2150
- description: 'The natural-language correction (e.g. "we migrated to MySQL in March").',
2151
- },
2152
- targetIds: {
2153
- type: "array",
2154
- items: { type: "string" },
2155
- description: "Optional explicit target memory ids. When omitted, the planner searches.",
2156
- },
2157
- sessionKey: { type: "string", description: "Session identifier for namespace resolution." },
2158
- namespace: { type: "string", description: "Optional explicit namespace (validated by policy)." },
2159
- },
2160
- required: ["text"],
2161
- additionalProperties: false,
2162
- },
2163
- },
2164
- this.emitLegacyTools
2165
- );
2166
- const applyTool = withToolAliases(
2167
- {
2168
- name: "engram.memory_correct_apply",
2169
- description:
2170
- "Apply a planned memory correction by planId (issue #1580). Requires confirm: true when correction.applyRequiresConfirm is on (default).",
2171
- inputSchema: {
2172
- type: "object",
2173
- properties: {
2174
- planId: { type: "string", description: "The plan id returned by memory_correct_plan." },
2175
- confirm: { type: "boolean", description: "Must be true to apply (safety guard, rule 48)." },
2176
- sessionKey: { type: "string", description: "Session identifier for namespace resolution." },
2177
- namespace: { type: "string", description: "Optional explicit namespace (validated by policy)." },
2178
- },
2179
- required: ["planId"],
2180
- additionalProperties: false,
2181
- },
2182
- },
2183
- this.emitLegacyTools
2137
+ const correctionTools = correctionMcpTools.flatMap((tool) =>
2138
+ withToolAliases(tool, this.emitLegacyTools),
2184
2139
  );
2185
- this.tools = [...this.tools, ...planTool, ...applyTool];
2140
+ this.tools = [...this.tools, ...correctionTools];
2186
2141
  }
2187
2142
  if (this.chatVisible) {
2188
2143
  const chatTools = withToolAliases(
@@ -384,6 +384,7 @@ const memoryCorrectPlanSchema = z.preprocess(
384
384
  z.object({
385
385
  text: z.string().trim().min(1).max(10_000),
386
386
  targetIds: z.array(z.string().trim().min(1).max(512)).optional(),
387
+ duplicateOf: z.string().trim().min(1).max(512).optional(),
387
388
  sessionKey: z.string().trim().max(512).optional(),
388
389
  namespace: z.string().trim().max(256).optional(),
389
390
  }),
@@ -392,6 +393,7 @@ const memoryCorrectPlanSchema = z.preprocess(
392
393
  export interface MemoryCorrectPlanInput {
393
394
  text: string;
394
395
  targetIds?: string[];
396
+ duplicateOf?: string;
395
397
  sessionKey?: string;
396
398
  namespace?: string;
397
399
  }
@@ -414,6 +416,7 @@ export const memoryCorrectPlanOperation = defineOperation<
414
416
  {
415
417
  text: input.text,
416
418
  ...(input.targetIds ? { targetIds: input.targetIds } : {}),
419
+ ...(input.duplicateOf ? { duplicateOf: input.duplicateOf } : {}),
417
420
  ...(input.sessionKey ? { sessionKey: input.sessionKey } : {}),
418
421
  ...(input.namespace ? { namespace: input.namespace } : {}),
419
422
  ...(ctx.authenticatedPrincipal ? { principal: ctx.authenticatedPrincipal } : {}),
@@ -3349,24 +3349,6 @@ export class EngramAccessService extends SupportPassportAccessServiceBase {
3349
3349
  return Promise.resolve(false);
3350
3350
  }
3351
3351
  },
3352
- // Wire the orchestrator's extraction LLM so classify+draft actually
3353
- // drafts actions instead of always hitting the deterministic fallback
3354
- // (review thread PG5). The planner's classifyAndDraft already falls back
3355
- // on any LLM outage, so returning null (LLM disabled/cooldown) or a
3356
- // thrown error both degrade safely to the deterministic path (rule 13).
3357
- llmComplete: async ({ system, user }) => {
3358
- const result = await this.orchestrator.localLlm.chatCompletion(
3359
- [
3360
- { role: "system", content: system },
3361
- { role: "user", content: user },
3362
- ],
3363
- { operation: "correction-classify", priority: "background" }
3364
- );
3365
- if (!result) {
3366
- throw new Error("correction classify+draft: local LLM unavailable (disabled or in cooldown)");
3367
- }
3368
- return result.content;
3369
- },
3370
3352
  });
3371
3353
  this._correctionService = service;
3372
3354
  return service;
@@ -3389,11 +3371,20 @@ export class EngramAccessService extends SupportPassportAccessServiceBase {
3389
3371
  }
3390
3372
 
3391
3373
  async correctionPlan(request: CorrectionRequest, opts?: { abortSignal?: AbortSignal }): Promise<CorrectionPlan> {
3374
+ let next = request;
3392
3375
  if (request.targetIds?.some((id) => isHandleToken(id))) {
3393
- const targetIds = request.targetIds.map((id) => this.resolveMemoryIdOrHandleInput(id, request.sessionKey));
3394
- return this.correctionService().plan({ ...request, targetIds }, opts);
3376
+ next = {
3377
+ ...next,
3378
+ targetIds: request.targetIds.map((id) => this.resolveMemoryIdOrHandleInput(id, request.sessionKey)),
3379
+ };
3380
+ }
3381
+ if (request.duplicateOf && isHandleToken(request.duplicateOf)) {
3382
+ next = {
3383
+ ...next,
3384
+ duplicateOf: this.resolveMemoryIdOrHandleInput(request.duplicateOf, request.sessionKey),
3385
+ };
3395
3386
  }
3396
- return this.correctionService().plan(request, opts);
3387
+ return this.correctionService().plan(next, opts);
3397
3388
  }
3398
3389
 
3399
3390
  async correctionApply(
@@ -2463,6 +2463,32 @@ test("parseConfig rejects invalid correction.planTtlHours instead of silently de
2463
2463
  assert.equal(parseConfig({}).correctionPlanTtlHours, 24, "absent → documented default");
2464
2464
  });
2465
2465
 
2466
+ test("parseConfig correction.classifyTimeoutMs defaults to 45000 and rejects invalid values", () => {
2467
+ assert.equal(parseConfig({}).correctionClassifyTimeoutMs, 45_000);
2468
+ assert.equal(parseConfig({ correction: { classifyTimeoutMs: 12000 } }).correctionClassifyTimeoutMs, 12_000);
2469
+ assert.equal(
2470
+ parseConfig({
2471
+ correction: { classifyTimeoutMs: 8000 },
2472
+ correctionClassifyTimeoutMs: 1000,
2473
+ }).correctionClassifyTimeoutMs,
2474
+ 8000,
2475
+ "nested correction.classifyTimeoutMs wins",
2476
+ );
2477
+ assert.equal(parseConfig({ correctionClassifyTimeoutMs: 15000 }).correctionClassifyTimeoutMs, 15_000);
2478
+ for (const value of [0, -1, 3.7, "abc", 300_001, true]) {
2479
+ assert.throws(
2480
+ () => parseConfig({ correctionClassifyTimeoutMs: value } as Record<string, unknown>),
2481
+ /Invalid correction\.classifyTimeoutMs/,
2482
+ `correctionClassifyTimeoutMs=${JSON.stringify(value)} should throw`,
2483
+ );
2484
+ assert.throws(
2485
+ () => parseConfig({ correction: { classifyTimeoutMs: value } } as Record<string, unknown>),
2486
+ /Invalid correction\.classifyTimeoutMs/,
2487
+ `nested classifyTimeoutMs=${JSON.stringify(value)} should throw`,
2488
+ );
2489
+ }
2490
+ });
2491
+
2466
2492
  test("parseConfig correction.maxAffected rejects non-integers (Number.isInteger, #1678)", () => {
2467
2493
  // The error message says "integer" — 3.7 must be rejected, not silently floored to 3.
2468
2494
  for (const value of [3.7, 2.5, "1.5", 0.99]) {
package/src/config.ts CHANGED
@@ -28,6 +28,7 @@ import type {
28
28
  import { parseBackgroundGeneration } from "./background-generation-config.js";
29
29
  import { parseSearchBackend } from "./config-search-backend.js";
30
30
  import { parseLocalLlmConfig } from "./local-llm-config.js";
31
+ import { parseCorrectionConfig } from "./correction/correction-config.js";
31
32
  import { parseConvergeConfig } from "./converge-config.js";
32
33
  import { parseExternalWikiRecallGuard } from "./external-wiki-guard.js";
33
34
  import { log } from "./logger.js";
@@ -1855,66 +1856,9 @@ export function parseConfig(
1855
1856
  // (docs kept honest — review: wire resolver before exposing the gate).
1856
1857
  temporalBiTemporal: coerceBool(cfg.temporalBiTemporal) ?? false,
1857
1858
  temporalExpiredInInjection: coerceBool(cfg.temporalExpiredInInjection) ?? false,
1858
- // Correction Contract (issue #1580). Parsed here so operators can actually
1859
- // set the documented toggles/limits (review thread Txp): parseConfig builds
1860
- // an explicit output, so without these lines the raw `correction` block /
1861
- // flat legacy keys are dropped and the runtime always sees defaults. Nested
1862
- // `correction.<key>` wins; flat `correction<Key>` is the legacy fallback.
1863
- correctionEnabled: (() => {
1864
- const nested = (cfg.correction as Record<string, unknown> | undefined)?.enabled;
1865
- const raw = nested !== undefined ? nested : cfg.correctionEnabled;
1866
- if (raw === undefined || raw === null) return true;
1867
- const v = coerceBool(raw);
1868
- if (v === undefined) {
1869
- throw new Error(`Invalid correction.enabled: expected a boolean, got ${JSON.stringify(raw)}`);
1870
- }
1871
- return v;
1872
- })(),
1873
- correctionApplyRequiresConfirm: (() => {
1874
- const nested = (cfg.correction as Record<string, unknown> | undefined)?.applyRequiresConfirm;
1875
- const raw = nested !== undefined ? nested : cfg.correctionApplyRequiresConfirm;
1876
- if (raw === undefined || raw === null) return true;
1877
- const v = coerceBool(raw);
1878
- if (v === undefined) {
1879
- throw new Error(`Invalid correction.applyRequiresConfirm: expected a boolean, got ${JSON.stringify(raw)}`);
1880
- }
1881
- return v;
1882
- })(),
1883
- correctionMaxAffected: (() => {
1884
- const rawNested = (cfg.correction as Record<string, unknown> | undefined)?.maxAffected;
1885
- const raw = rawNested !== undefined ? rawNested : cfg.correctionMaxAffected;
1886
- if (raw === undefined || raw === null) return 10;
1887
- const n = coerceNumber(raw);
1888
- // #1678 (thread Oiup6): the error message says "integer" — enforce it
1889
- // with Number.isInteger so 3.7 is rejected rather than silently floored.
1890
- if (n === undefined || !Number.isFinite(n) || n < 1 || !Number.isInteger(n)) {
1891
- throw new Error(`Invalid correction.maxAffected: expected an integer >= 1, got ${JSON.stringify(raw)}`);
1892
- }
1893
- return n;
1894
- })(),
1895
- correctionPlanTtlHours: (() => {
1896
- const nested = (cfg.correction as Record<string, unknown> | undefined)?.planTtlHours;
1897
- const fromNested = nested !== undefined ? coerceNumber(nested) : undefined;
1898
- if (fromNested !== undefined && fromNested >= 1) return fromNested;
1899
- // #1678 (threads Ohtvi/Ohyvf): reject invalid (0/negative/non-numeric)
1900
- // instead of silently defaulting to 24h — completes the config-reject
1901
- // class already enforced for enabled/applyRequiresConfirm/maxAffected.
1902
- if (nested !== undefined && fromNested === undefined) {
1903
- throw new Error(`Invalid correction.planTtlHours: expected a number >= 1, got ${JSON.stringify(nested)}`);
1904
- }
1905
- if (fromNested !== undefined && fromNested < 1) {
1906
- throw new Error(`Invalid correction.planTtlHours: expected a number >= 1, got ${JSON.stringify(nested)}`);
1907
- }
1908
- const fromFlat = coerceNumber(cfg.correctionPlanTtlHours);
1909
- if (fromFlat !== undefined && fromFlat >= 1) return fromFlat;
1910
- if (cfg.correctionPlanTtlHours !== undefined && fromFlat === undefined) {
1911
- throw new Error(`Invalid correction.planTtlHours: expected a number >= 1, got ${JSON.stringify(cfg.correctionPlanTtlHours)}`);
1912
- }
1913
- if (fromFlat !== undefined && fromFlat < 1) {
1914
- throw new Error(`Invalid correction.planTtlHours: expected a number >= 1, got ${JSON.stringify(cfg.correctionPlanTtlHours)}`);
1915
- }
1916
- return 24;
1917
- })(),
1859
+ // Correction Contract (#1580). Nested `correction.<key>` wins over flat
1860
+ // `correction<Key>`. Parser lives in correction/correction-config.ts.
1861
+ ...parseCorrectionConfig(cfg),
1918
1862
  // Passive correction capture (issue #1581). Parsed from
1919
1863
  // `correctionCapture.<key>` (nested) or flat legacy keys. Default "off" —
1920
1864
  // operators opt in (rule 48). Invalid mode → rejected listing options (rule 51).
@@ -21,7 +21,7 @@
21
21
  */
22
22
 
23
23
  import path from "node:path";
24
- import { throwIfAborted } from "../abort-error.js";
24
+ import { abortError, isAbortError, throwIfAborted } from "../abort-error.js";
25
25
  import { composeMemoryEnvelope, isMemoryCategory } from "../write-envelope.js";
26
26
  import { log } from "../logger.js";
27
27
  import { createHash } from "node:crypto";
@@ -48,6 +48,7 @@ import {
48
48
  } from "./correction-planner.js";
49
49
  import { type ExecutorDeps, type ExecutorMemory } from "./correction-executor.js";
50
50
  import { CorrectionService, type CorrectionServiceDeps } from "./correction-service.js";
51
+ import { completeCorrectionClassify } from "./correction-classify.js";
51
52
  import { resolveRecallAuxiliaryCapabilities } from "../capabilities.js";
52
53
  import { isSupportPassportPrivateMemory } from "../support-passport/card-projection.js";
53
54
 
@@ -81,15 +82,15 @@ export interface CorrectionAccessWiring {
81
82
  principal?: string;
82
83
  }): Promise<boolean>;
83
84
  /**
84
- * Optional LLM-complete callback (Responses API only — gotcha 1). When
85
- * absent, the planner's classify+draft step falls back to deterministic
86
- * mode (rule 13). The access-service wires the orchestrator's extraction
87
- * LLM here once it exposes a public accessor; until then the contract
88
- * ships with the safe fallback.
85
+ * Optional test override for classify+draft. Production leaves this unset
86
+ * and uses completeCorrectionClassify: a short per-attempt timeout, caller
87
+ * abort, then the gateway/fallback model. A caller abort propagates; every
88
+ * other failure becomes the deterministic empty-action plan.
89
89
  */
90
90
  llmComplete?(request: {
91
91
  system: string;
92
92
  user: string;
93
+ abortSignal?: AbortSignal;
93
94
  }): Promise<string>;
94
95
  }
95
96
 
@@ -144,10 +145,12 @@ function makePlannerDeps(
144
145
  searchMemories(wiring, text, namespaces, limit),
145
146
  resolveTargets: async ({ targetIds, namespaces }) =>
146
147
  resolveTargetMemories(wiring, targetIds, namespaces),
148
+ inspectMemory: async ({ memoryId, namespaces }) =>
149
+ inspectCorrectionMemory(wiring, memoryId, namespaces),
147
150
  expandNeighbors: async ({ seedIds, namespaces, limit }) =>
148
151
  expandEntityNeighbors(wiring, seedIds, namespaces, limit),
149
- classifyAndDraft: async ({ text, candidates }) =>
150
- classifyAndDraft(wiring, text, candidates),
152
+ classifyAndDraft: async ({ text, candidates, abortSignal }) =>
153
+ classifyAndDraft(wiring, text, candidates, abortSignal),
151
154
  renderDiff: async ({ candidates, actions }) =>
152
155
  renderCorrectionDiff(wiring, candidates, actions),
153
156
  storageDir: async (namespace) => (await wiring.orchestrator.getStorage(namespace)).dir,
@@ -294,22 +297,54 @@ async function classifyAndDraft(
294
297
  wiring: CorrectionAccessWiring,
295
298
  text: string,
296
299
  candidates: PlannerCandidate[],
300
+ abortSignal?: AbortSignal,
297
301
  ): Promise<LlmClassificationResult> {
298
- // Route through the injected LLM callback (Responses API only — gotcha 1).
299
- // On any failure (or when no callback is wired), return the deterministic
300
- // fallback (rule 13) — the planner never throws on an LLM outage.
302
+ // Injected llmComplete stays as a test override. Production uses
303
+ // completeCorrectionClassify: short timeout, caller abort, gateway fallback.
304
+ // Abort throws. Every other failure is the deterministic empty-action plan.
301
305
  try {
302
- if (!wiring.llmComplete) {
303
- return fallbackClassification(candidates, "no LLM client available");
304
- }
306
+ throwIfAborted(abortSignal, "correction classify aborted");
305
307
  const user = buildClassifyPrompt(text, candidates);
306
- const raw = await wiring.llmComplete({ system: CLASSIFY_SYSTEM_PROMPT, user });
308
+ const raw = wiring.llmComplete
309
+ ? await wiring.llmComplete({ system: CLASSIFY_SYSTEM_PROMPT, user, abortSignal })
310
+ : await completeCorrectionClassify(
311
+ [
312
+ { role: "system", content: CLASSIFY_SYSTEM_PROMPT },
313
+ { role: "user", content: user },
314
+ ],
315
+ { config: wiring.orchestrator.config, localLlm: wiring.orchestrator.localLlm },
316
+ abortSignal,
317
+ );
318
+ if (raw == null) return fallbackClassification(candidates, "correction classify unavailable");
319
+ throwIfAborted(abortSignal, "correction classify aborted");
307
320
  return parseClassifyResponse(raw, candidates);
308
321
  } catch (err) {
322
+ if (isAbortError(err) || abortSignal?.aborted) {
323
+ throw isAbortError(err) ? err : abortError("correction classify aborted");
324
+ }
309
325
  return fallbackClassification(candidates, `LLM unavailable: ${errMsg(err)}`);
310
326
  }
311
327
  }
312
328
 
329
+ async function inspectCorrectionMemory(
330
+ wiring: CorrectionAccessWiring,
331
+ memoryId: string,
332
+ namespaces: readonly string[],
333
+ ): Promise<{ candidate: PlannerCandidate; status: string } | null> {
334
+ for (const ns of namespaces) {
335
+ const storage = await wiring.orchestrator.getStorage(ns);
336
+ const memory = await storage.getMemoryByIdIncludingArchived(memoryId);
337
+ if (!memory || memory.frontmatter.id !== memoryId) continue;
338
+ const candidate = toCandidate(memory, ns, 1);
339
+ if (isSupportPassportPrivateMemory(memory)) return { candidate, status: "ineligible" };
340
+ if (typeof memory.frontmatter.archivedAt === "string" && memory.frontmatter.archivedAt.length > 0) {
341
+ return { candidate, status: "archived" };
342
+ }
343
+ return { candidate, status: memory.frontmatter.status ?? "active" };
344
+ }
345
+ return null;
346
+ }
347
+
313
348
  async function renderCorrectionDiff(
314
349
  _wiring: CorrectionAccessWiring,
315
350
  candidates: PlannerCandidate[],
@@ -339,7 +374,10 @@ async function renderCorrectionDiff(
339
374
  function describeAfterState(action: CorrectionAction): string {
340
375
  switch (action.kind) {
341
376
  case "supersede":
342
- return action.replacement?.content ?? "(superseded without replacement)";
377
+ return action.replacement?.content
378
+ ?? (action.winnerId
379
+ ? `(superseded by ${action.winnerId}; recoverable)`
380
+ : "(superseded without replacement)");
343
381
  case "edit":
344
382
  return action.patch;
345
383
  case "retract":
@@ -899,6 +937,7 @@ function toExecutorMemory(m: MemoryFile): ExecutorMemory {
899
937
  ...(typeof fm.contentHash === "string" && fm.contentHash.length > 0
900
938
  ? { contentHash: fm.contentHash }
901
939
  : {}),
940
+ status: fm.status ?? "active",
902
941
  } satisfies ExecutorMemory;
903
942
  }
904
943
 
@@ -987,6 +1026,7 @@ Given a correction statement and candidate memories, respond with a JSON object:
987
1026
 
988
1027
  Action shapes:
989
1028
  - {"kind":"supersede","loserId":"<id>","replacement":{"content":"<new fact>"}}
1029
+ - {"kind":"supersede","loserId":"<id>","winnerId":"<existing id>"}
990
1030
  - {"kind":"edit","memoryId":"<id>","patch":"<new full content>"}
991
1031
  - {"kind":"retract","memoryId":"<id>"}
992
1032
  - {"kind":"rescope","memoryId":"<id>","toNamespace":"<ns>"}