@remnic/core 9.65.2 → 9.65.4

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 (492) hide show
  1. package/dist/access-admin-ops-surface.d.ts +44 -44
  2. package/dist/access-admin-ops-surface.js +21 -19
  3. package/dist/access-authorization-probe.d.ts +38 -38
  4. package/dist/access-authorization-probe.js +22 -20
  5. package/dist/access-boundary.d.ts +40 -40
  6. package/dist/access-boundary.js +21 -19
  7. package/dist/access-cli.js +62 -60
  8. package/dist/access-cli.js.map +1 -1
  9. package/dist/access-coding-context-resolution.d.ts +3 -1
  10. package/dist/access-extraction-force-flush.d.ts +25 -25
  11. package/dist/access-extraction-force-flush.js +21 -19
  12. package/dist/access-health-types.d.ts +3 -1
  13. package/dist/access-http-lcm-compaction.d.ts +39 -39
  14. package/dist/access-http-lifecycle-flush.d.ts +39 -39
  15. package/dist/access-http-offline-stream.d.ts +25 -25
  16. package/dist/access-http-query.d.ts +4 -2
  17. package/dist/access-http-query.js +23 -21
  18. package/dist/access-http.d.ts +51 -44
  19. package/dist/access-http.js +37 -35
  20. package/dist/access-identity-continuity-surface.d.ts +12 -12
  21. package/dist/access-identity-continuity-surface.js +21 -19
  22. package/dist/access-lcm-surface.d.ts +27 -27
  23. package/dist/access-lcm-surface.js +21 -19
  24. package/dist/access-mcp-admin-tools.d.ts +9 -1
  25. package/dist/access-mcp-admin-tools.js +3 -1
  26. package/dist/access-mcp-output-schemas.js +1 -1
  27. package/dist/access-mcp.d.ts +39 -39
  28. package/dist/access-mcp.js +31 -29
  29. package/dist/access-memory-search-fanout.d.ts +4 -2
  30. package/dist/{access-namespace-preflight-Dhvcl-T0.d.ts → access-namespace-preflight-D_6mo8ms.d.ts} +1 -1
  31. package/dist/access-namespace-preflight.d.ts +5 -3
  32. package/dist/access-namespace-preflight.js +21 -19
  33. package/dist/access-observe-write-surface.d.ts +39 -39
  34. package/dist/access-observe-write-surface.js +21 -19
  35. package/dist/access-offline-manifest.d.ts +12 -12
  36. package/dist/access-offline-manifest.js +3 -3
  37. package/dist/access-operations-batch.js +25 -23
  38. package/dist/access-operations.d.ts +40 -40
  39. package/dist/access-operations.js +28 -26
  40. package/dist/access-recall-concurrency.d.ts +40 -40
  41. package/dist/access-recall-concurrency.js +21 -19
  42. package/dist/access-recall-response.d.ts +24 -24
  43. package/dist/access-recall-response.js +21 -19
  44. package/dist/access-recall-surface.d.ts +24 -24
  45. package/dist/access-recall-surface.js +21 -19
  46. package/dist/access-schema.d.ts +45 -45
  47. package/dist/{access-service-Bke1alZO.d.ts → access-service-DqPa3hy4.d.ts} +219 -75
  48. package/dist/access-service-helpers.d.ts +40 -40
  49. package/dist/access-service.d.ts +47 -47
  50. package/dist/access-service.js +21 -19
  51. package/dist/access-surface-catalog.d.ts +40 -40
  52. package/dist/access-surface-catalog.js +27 -21
  53. package/dist/access-surface-catalog.js.map +1 -1
  54. package/dist/access-wearables-meetings-surface.d.ts +5 -3
  55. package/dist/action-confidence.d.ts +3 -1
  56. package/dist/active-memory-bridge.d.ts +3 -1
  57. package/dist/active-recall.d.ts +3 -1
  58. package/dist/active-recall.js +10 -1
  59. package/dist/active-recall.js.map +1 -1
  60. package/dist/ambient-provenance.d.ts +3 -1
  61. package/dist/artifact-search.d.ts +3 -1
  62. package/dist/{auto-sync-H64ZCNIR.js → auto-sync-XVMLL2RH.js} +5 -5
  63. package/dist/behavior-learner.d.ts +3 -1
  64. package/dist/behavior-signals.d.ts +3 -1
  65. package/dist/bootstrap.d.ts +12 -12
  66. package/dist/briefing-window.d.ts +4 -2
  67. package/dist/briefing.d.ts +4 -2
  68. package/dist/briefing.js +4 -4
  69. package/dist/buffer-surprise-report.d.ts +3 -1
  70. package/dist/buffer-turn-helpers.d.ts +3 -1
  71. package/dist/buffer.d.ts +4 -2
  72. package/dist/bulk-import/index.d.ts +5 -3
  73. package/dist/calibration.d.ts +3 -1
  74. package/dist/capabilities.d.ts +3 -1
  75. package/dist/{catalog-DV6qnbr7.d.ts → catalog-DO_7zfkv.d.ts} +1 -1
  76. package/dist/causal-behavior.d.ts +1 -1
  77. package/dist/causal-consolidation.d.ts +3 -1
  78. package/dist/causal-consolidation.js +12 -9
  79. package/dist/causal-consolidation.js.map +1 -1
  80. package/dist/causal-trajectory-graph.d.ts +1 -1
  81. package/dist/chunk-236PXYG7.js +232 -0
  82. package/dist/chunk-236PXYG7.js.map +1 -0
  83. package/dist/{chunk-YB42WZCY.js → chunk-2IXQSGCU.js} +2 -2
  84. package/dist/{chunk-PE255F4T.js → chunk-2MVTAIL3.js} +2 -2
  85. package/dist/{chunk-LGO6A7GJ.js → chunk-3JZBPTLD.js} +338 -80
  86. package/dist/chunk-3JZBPTLD.js.map +1 -0
  87. package/dist/{chunk-GDFVPUJ5.js → chunk-3NH3VP3U.js} +2 -2
  88. package/dist/{chunk-TBOJ76ER.js → chunk-AB3A7EFH.js} +18 -2
  89. package/dist/{chunk-TBOJ76ER.js.map → chunk-AB3A7EFH.js.map} +1 -1
  90. package/dist/{chunk-GNCCUR6K.js → chunk-AXGFOFNY.js} +2 -2
  91. package/dist/{chunk-SB7D4BT7.js → chunk-AZLLH6YA.js} +1554 -114
  92. package/dist/chunk-AZLLH6YA.js.map +1 -0
  93. package/dist/{chunk-5YQ63T4B.js → chunk-BK5G2MHO.js} +2 -2
  94. package/dist/{chunk-LZH5FR2W.js → chunk-CQBIN77D.js} +2 -2
  95. package/dist/{chunk-35NN3ZFA.js → chunk-CTVWELNK.js} +21 -3
  96. package/dist/chunk-CTVWELNK.js.map +1 -0
  97. package/dist/{chunk-NKKD4ZAU.js → chunk-DORFF5N5.js} +2 -2
  98. package/dist/{chunk-BWLRUMOG.js → chunk-DPNXADEI.js} +441 -2
  99. package/dist/chunk-DPNXADEI.js.map +1 -0
  100. package/dist/{chunk-SQI57UCJ.js → chunk-DUEDOYZD.js} +2 -2
  101. package/dist/{chunk-5NM4OH4P.js → chunk-DUZARALI.js} +3 -3
  102. package/dist/{chunk-2E36UXVW.js → chunk-ECLJ4LA2.js} +2 -2
  103. package/dist/{chunk-TZNQUNKL.js → chunk-FC7TIRFS.js} +15 -1
  104. package/dist/chunk-FC7TIRFS.js.map +1 -0
  105. package/dist/{chunk-IID2CMUU.js → chunk-GHD2LLG4.js} +2 -2
  106. package/dist/{chunk-ZQHI2BZB.js → chunk-HF5BUTI6.js} +2 -2
  107. package/dist/{chunk-3DVBKTSO.js → chunk-HSZMX3ZJ.js} +4 -4
  108. package/dist/{chunk-S2DPMJXH.js → chunk-I23ZHYSL.js} +2 -2
  109. package/dist/{chunk-ODZG724P.js → chunk-I2HTKOOP.js} +2 -2
  110. package/dist/chunk-I32NKXE2.js +879 -0
  111. package/dist/chunk-I32NKXE2.js.map +1 -0
  112. package/dist/{chunk-NTWN6HB2.js → chunk-IURMJBGP.js} +2 -2
  113. package/dist/{chunk-OCZIYAE5.js → chunk-IWKGOCL6.js} +3 -3
  114. package/dist/{chunk-UXO5IMBK.js → chunk-J3ATBB7M.js} +2 -2
  115. package/dist/{chunk-Y7DK7HHJ.js → chunk-JPAKBNTM.js} +2 -2
  116. package/dist/{chunk-SPUJNJJC.js → chunk-KFIOPZ25.js} +2 -2
  117. package/dist/{chunk-JYYBA7TF.js → chunk-KOO37E4Y.js} +2 -2
  118. package/dist/{chunk-OTHZWLUD.js → chunk-KPB2QHJZ.js} +2 -2
  119. package/dist/{chunk-SBDCZ2AX.js → chunk-LBFFNDFM.js} +1 -1
  120. package/dist/chunk-LBFFNDFM.js.map +1 -0
  121. package/dist/{chunk-CT56C22C.js → chunk-LYBIHM4N.js} +4 -4
  122. package/dist/{chunk-3I7ASZN3.js → chunk-MFOSZUIT.js} +2 -2
  123. package/dist/{chunk-DZUJ46DO.js → chunk-NLEH4RTB.js} +2 -2
  124. package/dist/{chunk-ZO6AXLEH.js → chunk-OCCHUEZB.js} +2 -2
  125. package/dist/{chunk-EILZG5VC.js → chunk-OU34IQXV.js} +2 -2
  126. package/dist/{chunk-2XDWWPTN.js → chunk-OZDFB22S.js} +2 -2
  127. package/dist/{chunk-UIN2BWDD.js → chunk-PTZQYCJ4.js} +2 -2
  128. package/dist/{chunk-7BY7V4YX.js → chunk-Q4WONDMJ.js} +4 -3
  129. package/dist/{chunk-7BY7V4YX.js.map → chunk-Q4WONDMJ.js.map} +1 -1
  130. package/dist/{chunk-Z7PBQPJ4.js → chunk-QJW4MZSW.js} +2 -2
  131. package/dist/{chunk-R7JAM2XF.js → chunk-R2MZCYA6.js} +3 -3
  132. package/dist/{chunk-TF77C7SV.js → chunk-SR5LNI6Q.js} +7 -5
  133. package/dist/chunk-SR5LNI6Q.js.map +1 -0
  134. package/dist/{chunk-LBWQ65SX.js → chunk-T42L3S6A.js} +4 -4
  135. package/dist/{chunk-J275IYMG.js → chunk-THVI4Y7X.js} +34 -7
  136. package/dist/chunk-THVI4Y7X.js.map +1 -0
  137. package/dist/{chunk-QOS5LBZN.js → chunk-TJFI3K2O.js} +15 -3
  138. package/dist/chunk-TJFI3K2O.js.map +1 -0
  139. package/dist/{chunk-2YI72KM3.js → chunk-UCKG36HO.js} +2 -2
  140. package/dist/{chunk-SIHSCCUQ.js → chunk-UFR6HX7A.js} +1 -1
  141. package/dist/{chunk-CDUUDBWJ.js → chunk-VFYRYFLL.js} +2 -2
  142. package/dist/{chunk-XRYZRW54.js → chunk-WDXD6ITO.js} +2 -2
  143. package/dist/{chunk-4KYOLI6M.js → chunk-XGM3VQWG.js} +120 -14
  144. package/dist/chunk-XGM3VQWG.js.map +1 -0
  145. package/dist/{chunk-MN4KB2A4.js → chunk-YDKF4MSJ.js} +3 -3
  146. package/dist/{chunk-YLDXWCZP.js → chunk-YHGCT462.js} +14 -9
  147. package/dist/chunk-YHGCT462.js.map +1 -0
  148. package/dist/{chunk-7YQ4IYS2.js → chunk-YOXVZJFM.js} +2 -2
  149. package/dist/{chunk-ZWXJBFZU.js → chunk-YZJM6CLF.js} +8 -8
  150. package/dist/chunk-ZCUTSMR2.js +61 -0
  151. package/dist/chunk-ZCUTSMR2.js.map +1 -0
  152. package/dist/{chunk-LUNJ3WFO.js → chunk-ZK4BFABK.js} +4 -4
  153. package/dist/{chunk-V3MXUL3D.js → chunk-ZPOHEB5Z.js} +329 -653
  154. package/dist/chunk-ZPOHEB5Z.js.map +1 -0
  155. package/dist/{chunk-RDFF2NAU.js → chunk-ZXBTTMGZ.js} +184 -88
  156. package/dist/chunk-ZXBTTMGZ.js.map +1 -0
  157. package/dist/{cli-cShQ13XG.d.ts → cli-DO3i14pM.d.ts} +5 -5
  158. package/dist/cli.d.ts +25 -25
  159. package/dist/cli.js +51 -48
  160. package/dist/coding/pre-action-gate.d.ts +2 -60
  161. package/dist/compounding/engine.d.ts +4 -2
  162. package/dist/compounding/engine.js +4 -4
  163. package/dist/compounding/preference-consolidator.d.ts +3 -1
  164. package/dist/compression-optimizer.d.ts +3 -1
  165. package/dist/config.d.ts +3 -1
  166. package/dist/config.js +10 -1
  167. package/dist/connectors/codex-materialize-runner.d.ts +3 -1
  168. package/dist/connectors/codex-materialize-runner.js +8 -5
  169. package/dist/connectors/codex-materialize.d.ts +16 -1
  170. package/dist/connectors/codex-materialize.js +10 -1
  171. package/dist/connectors/index.d.ts +3 -1
  172. package/dist/connectors/index.js +8 -5
  173. package/dist/consolidation-provenance-check.d.ts +4 -2
  174. package/dist/consolidation-undo.d.ts +4 -2
  175. package/dist/contradiction/index.d.ts +10 -270
  176. package/dist/contradiction/index.js +12 -7
  177. package/dist/{contradiction-review-QKJH5DKD.js → contradiction-review-WRVLRWHS.js} +6 -2
  178. package/dist/{contradiction-scan-VOTQRRSX.js → contradiction-scan-AKUWPX5N.js} +5 -3
  179. package/dist/converge-config.d.ts +3 -1
  180. package/dist/convergence-refresh.d.ts +4 -2
  181. package/dist/convergence-refresh.js +6 -6
  182. package/dist/conversation-index/backend.d.ts +3 -1
  183. package/dist/conversation-index/chunker.d.ts +3 -1
  184. package/dist/conversation-index/faiss-adapter.d.ts +3 -1
  185. package/dist/conversation-index/indexer.d.ts +3 -1
  186. package/dist/conversation-index/search.d.ts +3 -1
  187. package/dist/corpus-watermark.d.ts +3 -1
  188. package/dist/corpus-watermark.js +6 -6
  189. package/dist/cross-lingual-recall.d.ts +3 -1
  190. package/dist/day-summary.d.ts +3 -1
  191. package/dist/delinearize.d.ts +3 -1
  192. package/dist/dependency-propagation-config.d.ts +3 -1
  193. package/dist/{dependency-propagation-delivery-CsGg-VwS.d.ts → dependency-propagation-delivery-D23_x-s5.d.ts} +1 -1
  194. package/dist/direct-answer-wiring.d.ts +3 -1
  195. package/dist/direct-answer.d.ts +3 -1
  196. package/dist/embedding-fallback.d.ts +3 -1
  197. package/dist/enrichment/index.d.ts +3 -1
  198. package/dist/entity-origin-fields.d.ts +3 -1
  199. package/dist/entity-retrieval.d.ts +4 -2
  200. package/dist/entity-retrieval.js +4 -4
  201. package/dist/entity-schema.d.ts +3 -1
  202. package/dist/episodic-context.d.ts +3 -1
  203. package/dist/explicit-capture.d.ts +12 -12
  204. package/dist/explicit-capture.js +1 -1
  205. package/dist/external-wiki-access.d.ts +40 -40
  206. package/dist/external-wiki-access.js +22 -20
  207. package/dist/external-wiki-collection-registration.d.ts +3 -1
  208. package/dist/external-wiki-collection.d.ts +3 -1
  209. package/dist/external-wiki-mcp-tools.d.ts +40 -40
  210. package/dist/extraction-error-classification.d.ts +3 -1
  211. package/dist/extraction-faithfulness.d.ts +3 -1
  212. package/dist/extraction-judge-telemetry.d.ts +3 -1
  213. package/dist/extraction-judge-training.d.ts +3 -1
  214. package/dist/extraction-judge.d.ts +3 -1
  215. package/dist/extraction-judge.js +2 -2
  216. package/dist/extraction-liveness.d.ts +3 -1
  217. package/dist/extraction-normalization.d.ts +3 -1
  218. package/dist/extraction-prompt.d.ts +3 -1
  219. package/dist/extraction-source-grounding-rules.d.ts +3 -1
  220. package/dist/extraction-source-grounding.d.ts +3 -1
  221. package/dist/extraction.d.ts +3 -1
  222. package/dist/extraction.js +9 -7
  223. package/dist/fallback-llm.d.ts +3 -1
  224. package/dist/graph-dashboard-diff.d.ts +3 -1
  225. package/dist/graph-dashboard-key.d.ts +3 -1
  226. package/dist/graph-dashboard-parser.d.ts +3 -1
  227. package/dist/graph-edge-reinforcement.d.ts +3 -1
  228. package/dist/graph-path-reconstruction.d.ts +3 -1
  229. package/dist/graph-path-scoring.d.ts +3 -1
  230. package/dist/graph-snapshot.d.ts +3 -1
  231. package/dist/graph.d.ts +3 -1
  232. package/dist/harmonic-retrieval.js +1 -1
  233. package/dist/importance.d.ts +3 -1
  234. package/dist/importers/index.d.ts +3 -1
  235. package/dist/in-flight-reads.d.ts +3 -1
  236. package/dist/index--QhGIXF2.d.ts +284 -0
  237. package/dist/index.d.ts +314 -45
  238. package/dist/index.js +163 -88
  239. package/dist/intent.d.ts +3 -1
  240. package/dist/lcm/engine.d.ts +3 -1
  241. package/dist/lcm/index.d.ts +3 -1
  242. package/dist/lcm/tools.d.ts +3 -1
  243. package/dist/lifecycle.d.ts +3 -1
  244. package/dist/live-connectors-runner.d.ts +3 -1
  245. package/dist/local-llm.d.ts +3 -1
  246. package/dist/local-model-endpoint.d.ts +3 -1
  247. package/dist/maintenance/memory-governance.d.ts +3 -1
  248. package/dist/maintenance/memory-governance.js +4 -4
  249. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +4 -2
  250. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +4 -4
  251. package/dist/maintenance/rebuild-memory-projection.d.ts +4 -2
  252. package/dist/maintenance/rebuild-memory-projection.js +5 -5
  253. package/dist/{maintenance-jhMpeGne.d.ts → maintenance-PFvY1Pw_.d.ts} +3 -3
  254. package/dist/mcp-memory-inspector-app.d.ts +37 -37
  255. package/dist/memory-action-policy.d.ts +3 -1
  256. package/dist/memory-cache.d.ts +3 -1
  257. package/dist/memory-lifecycle-ledger-utils.d.ts +3 -1
  258. package/dist/memory-projection-store.d.ts +3 -1
  259. package/dist/memory-provenance.d.ts +3 -1
  260. package/dist/memory-snapshot.d.ts +3 -1
  261. package/dist/memory-subject-cli.d.ts +40 -40
  262. package/dist/memory-subject.d.ts +42 -42
  263. package/dist/memory-worth-outcomes.d.ts +4 -2
  264. package/dist/models-json.d.ts +3 -1
  265. package/dist/namespaces/migrate.d.ts +5 -3
  266. package/dist/namespaces/migrate.js +5 -5
  267. package/dist/namespaces/principal.d.ts +3 -1
  268. package/dist/namespaces/search.d.ts +3 -1
  269. package/dist/namespaces/storage.d.ts +5 -3
  270. package/dist/namespaces/storage.js +4 -4
  271. package/dist/native-knowledge.d.ts +3 -1
  272. package/dist/offline-sync-impression-drain.d.ts +3 -1
  273. package/dist/operator-doctor-corpus.d.ts +3 -1
  274. package/dist/operator-doctor-corpus.js +7 -7
  275. package/dist/operator-doctor-replica.d.ts +3 -1
  276. package/dist/operator-toolkit.d.ts +5 -3
  277. package/dist/operator-toolkit.js +19 -13
  278. package/dist/orchestration/compression-guideline-coordinator.d.ts +4 -2
  279. package/dist/orchestration/maintenance.d.ts +6 -4
  280. package/dist/orchestration/maintenance.js +10 -10
  281. package/dist/{orchestrator-DyGUC7re.d.ts → orchestrator-4wzJrPVm.d.ts} +23 -9
  282. package/dist/orchestrator.d.ts +12 -12
  283. package/dist/orchestrator.js +62 -60
  284. package/dist/patterns-cli.d.ts +3 -1
  285. package/dist/{pipeline-C25Oxtp1.d.ts → pipeline-CgXgdIrF.d.ts} +1 -1
  286. package/dist/policy-runtime.d.ts +3 -1
  287. package/dist/proactive-contention.d.ts +3 -1
  288. package/dist/provenance.d.ts +3 -1
  289. package/dist/{public-http-CMe7NQzj.d.ts → public-http-DhIXYBYI.d.ts} +1 -1
  290. package/dist/{qmd-DkDVCbgF.d.ts → qmd-BppGGxsi.d.ts} +1 -1
  291. package/dist/qmd-preflight.d.ts +4 -2
  292. package/dist/qmd-recall-cache.d.ts +3 -1
  293. package/dist/qmd.d.ts +4 -2
  294. package/dist/recall-concurrency-config.d.ts +3 -1
  295. package/dist/recall-disclosure-escalation.d.ts +3 -1
  296. package/dist/recall-explain-renderer.d.ts +3 -1
  297. package/dist/recall-explain-renderer.js +3 -3
  298. package/dist/recall-memory-map.d.ts +3 -1
  299. package/dist/recall-planner-llm.d.ts +3 -1
  300. package/dist/recall-state.d.ts +3 -1
  301. package/dist/recall-tag-filter.d.ts +3 -1
  302. package/dist/recall-timings.d.ts +3 -1
  303. package/dist/recall-xray-cli.d.ts +3 -1
  304. package/dist/recall-xray-cli.js +4 -4
  305. package/dist/recall-xray-renderer.d.ts +3 -1
  306. package/dist/recall-xray-renderer.js +3 -3
  307. package/dist/recall-xray.d.ts +3 -1
  308. package/dist/recall-xray.js +2 -2
  309. package/dist/reconcile/cursor.d.ts +3 -1
  310. package/dist/reconcile/manifest.d.ts +3 -1
  311. package/dist/reconcile/manifest.js +2 -2
  312. package/dist/reconcile/plan.d.ts +3 -1
  313. package/dist/replay/normalizers/chatgpt.d.ts +3 -1
  314. package/dist/replay/normalizers/claude.d.ts +3 -1
  315. package/dist/replay/normalizers/openclaw.d.ts +3 -1
  316. package/dist/replay/normalizers/shared.d.ts +3 -1
  317. package/dist/replay/runner.d.ts +3 -1
  318. package/dist/replay/types.d.ts +3 -1
  319. package/dist/replica-divergence.d.ts +3 -1
  320. package/dist/replica-peers-config.d.ts +3 -1
  321. package/dist/{resolution-MFY72STR.js → resolution-4552BNRV.js} +14 -4
  322. package/dist/resolve-auth-token.d.ts +3 -1
  323. package/dist/resume-bundles.js +8 -2
  324. package/dist/retrieval-agents.d.ts +4 -2
  325. package/dist/retrieval-tiers.d.ts +3 -1
  326. package/dist/routing/engine.d.ts +3 -1
  327. package/dist/routing/store.d.ts +3 -1
  328. package/dist/salvage-envelope.d.ts +3 -1
  329. package/dist/salvage-envelope.js +1 -1
  330. package/dist/schemas.d.ts +44 -44
  331. package/dist/{scope-profiles-B9xMoFO-.d.ts → scope-profiles-ChZUtxDU.d.ts} +1 -1
  332. package/dist/search/embed-helper.d.ts +3 -1
  333. package/dist/search/factory.d.ts +3 -1
  334. package/dist/search/index.d.ts +3 -1
  335. package/dist/search/lancedb-backend.d.ts +3 -1
  336. package/dist/search/meilisearch-backend.d.ts +3 -1
  337. package/dist/search/noop-backend.d.ts +3 -1
  338. package/dist/search/orama-backend.d.ts +3 -1
  339. package/dist/search/port.d.ts +3 -1
  340. package/dist/search/remote-backend.d.ts +3 -1
  341. package/dist/{semantic-TddhF0y7.d.ts → semantic-BalR6EXU.d.ts} +1 -1
  342. package/dist/{semantic-consolidation-C4uykW84.d.ts → semantic-consolidation-mSPwQSmF.d.ts} +1 -1
  343. package/dist/semantic-consolidation.d.ts +4 -2
  344. package/dist/semantic-consolidation.js +9 -6
  345. package/dist/semantic-rule-promotion.js +4 -4
  346. package/dist/semantic-rule-verifier.d.ts +3 -1
  347. package/dist/semantic-rule-verifier.js +4 -4
  348. package/dist/{service-DCZDZNcV.d.ts → service-BICWLwSP.d.ts} +2 -2
  349. package/dist/session-observer-bands.d.ts +3 -1
  350. package/dist/session-observer-state.d.ts +3 -1
  351. package/dist/shared-context/manager.d.ts +3 -1
  352. package/dist/signal.d.ts +3 -1
  353. package/dist/skills-registry.js +4 -56
  354. package/dist/skills-registry.js.map +1 -1
  355. package/dist/source-agent-qualifier.d.ts +3 -1
  356. package/dist/source-agent-qualifier.js +8 -5
  357. package/dist/{storage-CcKmEjL8.d.ts → storage-B7urx1K3.d.ts} +1 -1
  358. package/dist/storage.d.ts +4 -2
  359. package/dist/storage.js +6 -6
  360. package/dist/subject-config.d.ts +3 -1
  361. package/dist/summarizer.d.ts +3 -1
  362. package/dist/summary-snapshot.d.ts +3 -1
  363. package/dist/support-passport/index.d.ts +43 -43
  364. package/dist/support-passport/index.js +24 -22
  365. package/dist/temporal-supersession.d.ts +4 -2
  366. package/dist/temporal-timeline-recall.d.ts +3 -1
  367. package/dist/temporal-validity.d.ts +3 -1
  368. package/dist/threading.d.ts +3 -1
  369. package/dist/tier-migration.d.ts +4 -2
  370. package/dist/tier-routing.d.ts +3 -1
  371. package/dist/topics.d.ts +3 -1
  372. package/dist/transcript.d.ts +3 -1
  373. package/dist/transfer/types.d.ts +20 -20
  374. package/dist/trust-score-stage.d.ts +3 -1
  375. package/dist/trust-score.d.ts +3 -1
  376. package/dist/{types-Pi0lfaEt.d.ts → types-ETU5N6nB.d.ts} +433 -7
  377. package/dist/types.d.ts +3 -1
  378. package/dist/types.js +1 -1
  379. package/dist/utility-runtime.d.ts +3 -1
  380. package/dist/verified-recall.js +4 -4
  381. package/dist/who-knows-cli.d.ts +40 -40
  382. package/dist/who-knows-cli.js +5 -5
  383. package/dist/who-knows.d.ts +42 -42
  384. package/dist/who-knows.js +4 -4
  385. package/dist/write-envelope.d.ts +3 -1
  386. package/dist/write-envelope.js +1 -1
  387. package/package.json +2 -2
  388. package/src/access-boundary.ts +4 -0
  389. package/src/access-http.ts +6 -5
  390. package/src/access-mcp-admin-tools.ts +24 -0
  391. package/src/access-mcp-output-schemas.ts +14 -0
  392. package/src/access-mcp.ts +2 -2
  393. package/src/access-operations-batch.ts +5 -0
  394. package/src/access-service.ts +27 -0
  395. package/src/access-surface-catalog.test.ts +24 -0
  396. package/src/access-surface-catalog.ts +4 -0
  397. package/src/cli/skills-commands.ts +150 -0
  398. package/src/cli.ts +4 -2
  399. package/src/coding/action-gate.test.ts +341 -0
  400. package/src/coding/action-gate.ts +556 -0
  401. package/src/config.ts +9 -2
  402. package/src/connectors/codex-materialize-runner.ts +16 -0
  403. package/src/connectors/codex-materialize-skills.test.ts +141 -0
  404. package/src/connectors/codex-materialize.ts +58 -40
  405. package/src/connectors/materialize-paths.ts +50 -0
  406. package/src/connectors/materialize-skills.ts +127 -0
  407. package/src/contradiction/contradiction-review.ts +50 -4
  408. package/src/contradiction/contradiction-scan.ts +14 -3
  409. package/src/contradiction/resolution.ts +50 -2
  410. package/src/index.ts +9 -13
  411. package/src/orchestration/recall-rerank-coordinator.ts +123 -4
  412. package/src/orchestration/recall-result-formatter.ts +6 -2
  413. package/src/orchestration/recall-search-pipeline.ts +14 -1
  414. package/src/preferences/drift-config.ts +118 -0
  415. package/src/preferences/drift-recall.ts +133 -0
  416. package/src/preferences/drift-types.ts +87 -0
  417. package/src/preferences/index.ts +12 -0
  418. package/src/preferences/preference-drift.test.ts +690 -0
  419. package/src/preferences/preference-drift.ts +724 -0
  420. package/src/procedural/skill-io.test.ts +190 -0
  421. package/src/procedural/skill-io.ts +220 -0
  422. package/src/procedural/skill-projection.test.ts +214 -0
  423. package/src/procedural/skill-projection.ts +356 -0
  424. package/src/review/review-deck-access.test.ts +325 -0
  425. package/src/review/review-deck-http-base.ts +133 -0
  426. package/src/review/review-deck-mutation.test.ts +417 -0
  427. package/src/review/review-deck-mutation.ts +677 -0
  428. package/src/review/review-deck-snapshot.ts +196 -0
  429. package/src/review/review-deck-surface.ts +117 -0
  430. package/src/review/review-deck.test.ts +347 -0
  431. package/src/review/review-deck.ts +311 -0
  432. package/src/storage.ts +4 -6
  433. package/src/types.ts +9 -6
  434. package/dist/chunk-35NN3ZFA.js.map +0 -1
  435. package/dist/chunk-4KYOLI6M.js.map +0 -1
  436. package/dist/chunk-BWLRUMOG.js.map +0 -1
  437. package/dist/chunk-J275IYMG.js.map +0 -1
  438. package/dist/chunk-LGO6A7GJ.js.map +0 -1
  439. package/dist/chunk-QOS5LBZN.js.map +0 -1
  440. package/dist/chunk-RDFF2NAU.js.map +0 -1
  441. package/dist/chunk-SB7D4BT7.js.map +0 -1
  442. package/dist/chunk-SBDCZ2AX.js.map +0 -1
  443. package/dist/chunk-TF77C7SV.js.map +0 -1
  444. package/dist/chunk-TZNQUNKL.js.map +0 -1
  445. package/dist/chunk-V3MXUL3D.js.map +0 -1
  446. package/dist/chunk-XCTXS7VY.js +0 -402
  447. package/dist/chunk-XCTXS7VY.js.map +0 -1
  448. package/dist/chunk-YLDXWCZP.js.map +0 -1
  449. /package/dist/{auto-sync-H64ZCNIR.js.map → auto-sync-XVMLL2RH.js.map} +0 -0
  450. /package/dist/{chunk-YB42WZCY.js.map → chunk-2IXQSGCU.js.map} +0 -0
  451. /package/dist/{chunk-PE255F4T.js.map → chunk-2MVTAIL3.js.map} +0 -0
  452. /package/dist/{chunk-GDFVPUJ5.js.map → chunk-3NH3VP3U.js.map} +0 -0
  453. /package/dist/{chunk-GNCCUR6K.js.map → chunk-AXGFOFNY.js.map} +0 -0
  454. /package/dist/{chunk-5YQ63T4B.js.map → chunk-BK5G2MHO.js.map} +0 -0
  455. /package/dist/{chunk-LZH5FR2W.js.map → chunk-CQBIN77D.js.map} +0 -0
  456. /package/dist/{chunk-NKKD4ZAU.js.map → chunk-DORFF5N5.js.map} +0 -0
  457. /package/dist/{chunk-SQI57UCJ.js.map → chunk-DUEDOYZD.js.map} +0 -0
  458. /package/dist/{chunk-5NM4OH4P.js.map → chunk-DUZARALI.js.map} +0 -0
  459. /package/dist/{chunk-2E36UXVW.js.map → chunk-ECLJ4LA2.js.map} +0 -0
  460. /package/dist/{chunk-IID2CMUU.js.map → chunk-GHD2LLG4.js.map} +0 -0
  461. /package/dist/{chunk-ZQHI2BZB.js.map → chunk-HF5BUTI6.js.map} +0 -0
  462. /package/dist/{chunk-3DVBKTSO.js.map → chunk-HSZMX3ZJ.js.map} +0 -0
  463. /package/dist/{chunk-S2DPMJXH.js.map → chunk-I23ZHYSL.js.map} +0 -0
  464. /package/dist/{chunk-ODZG724P.js.map → chunk-I2HTKOOP.js.map} +0 -0
  465. /package/dist/{chunk-NTWN6HB2.js.map → chunk-IURMJBGP.js.map} +0 -0
  466. /package/dist/{chunk-OCZIYAE5.js.map → chunk-IWKGOCL6.js.map} +0 -0
  467. /package/dist/{chunk-UXO5IMBK.js.map → chunk-J3ATBB7M.js.map} +0 -0
  468. /package/dist/{chunk-Y7DK7HHJ.js.map → chunk-JPAKBNTM.js.map} +0 -0
  469. /package/dist/{chunk-SPUJNJJC.js.map → chunk-KFIOPZ25.js.map} +0 -0
  470. /package/dist/{chunk-JYYBA7TF.js.map → chunk-KOO37E4Y.js.map} +0 -0
  471. /package/dist/{chunk-OTHZWLUD.js.map → chunk-KPB2QHJZ.js.map} +0 -0
  472. /package/dist/{chunk-CT56C22C.js.map → chunk-LYBIHM4N.js.map} +0 -0
  473. /package/dist/{chunk-3I7ASZN3.js.map → chunk-MFOSZUIT.js.map} +0 -0
  474. /package/dist/{chunk-DZUJ46DO.js.map → chunk-NLEH4RTB.js.map} +0 -0
  475. /package/dist/{chunk-ZO6AXLEH.js.map → chunk-OCCHUEZB.js.map} +0 -0
  476. /package/dist/{chunk-EILZG5VC.js.map → chunk-OU34IQXV.js.map} +0 -0
  477. /package/dist/{chunk-2XDWWPTN.js.map → chunk-OZDFB22S.js.map} +0 -0
  478. /package/dist/{chunk-UIN2BWDD.js.map → chunk-PTZQYCJ4.js.map} +0 -0
  479. /package/dist/{chunk-Z7PBQPJ4.js.map → chunk-QJW4MZSW.js.map} +0 -0
  480. /package/dist/{chunk-R7JAM2XF.js.map → chunk-R2MZCYA6.js.map} +0 -0
  481. /package/dist/{chunk-LBWQ65SX.js.map → chunk-T42L3S6A.js.map} +0 -0
  482. /package/dist/{chunk-2YI72KM3.js.map → chunk-UCKG36HO.js.map} +0 -0
  483. /package/dist/{chunk-SIHSCCUQ.js.map → chunk-UFR6HX7A.js.map} +0 -0
  484. /package/dist/{chunk-CDUUDBWJ.js.map → chunk-VFYRYFLL.js.map} +0 -0
  485. /package/dist/{chunk-XRYZRW54.js.map → chunk-WDXD6ITO.js.map} +0 -0
  486. /package/dist/{chunk-MN4KB2A4.js.map → chunk-YDKF4MSJ.js.map} +0 -0
  487. /package/dist/{chunk-7YQ4IYS2.js.map → chunk-YOXVZJFM.js.map} +0 -0
  488. /package/dist/{chunk-ZWXJBFZU.js.map → chunk-YZJM6CLF.js.map} +0 -0
  489. /package/dist/{chunk-LUNJ3WFO.js.map → chunk-ZK4BFABK.js.map} +0 -0
  490. /package/dist/{contradiction-review-QKJH5DKD.js.map → contradiction-review-WRVLRWHS.js.map} +0 -0
  491. /package/dist/{contradiction-scan-VOTQRRSX.js.map → contradiction-scan-AKUWPX5N.js.map} +0 -0
  492. /package/dist/{resolution-MFY72STR.js.map → resolution-4552BNRV.js.map} +0 -0
@@ -0,0 +1,133 @@
1
+ import type { IncomingMessage, ServerResponse } from "node:http";
2
+
3
+ import { EngramAccessInputError } from "../access-service.js";
4
+ import type { OperationName } from "../access-boundary.js";
5
+ import { SupportPassportAccessHttpBase } from "../support-passport/access-http-base.js";
6
+ import type {
7
+ ReviewDeckActionRequest,
8
+ ReviewDeckUndoRequest,
9
+ } from "./review-deck.js";
10
+
11
+ const LIST_PATHS = ["/remnic/v1/review/deck", "/engram/v1/review/deck"] as const;
12
+ const ACTION_PATHS = ["/remnic/v1/review/deck/action", "/engram/v1/review/deck/action"] as const;
13
+ const UNDO_PATHS = ["/remnic/v1/review/deck/undo", "/engram/v1/review/deck/undo"] as const;
14
+ const LIMIT_MIN = 1;
15
+ const LIMIT_MAX = 100;
16
+ const CURSOR_RE = /^[^\s%]{1,2048}$/;
17
+
18
+ function requiredString(body: Record<string, unknown>, field: string): string {
19
+ const value = body[field];
20
+ if (typeof value !== "string" || value.trim().length === 0) {
21
+ throw new EngramAccessInputError(`${field} is required`);
22
+ }
23
+ return value.trim();
24
+ }
25
+
26
+ function parseLimit(raw: string | null): number {
27
+ if (raw === null || raw.length === 0) {
28
+ throw new EngramAccessInputError("limit is required and must be an integer");
29
+ }
30
+ if (!/^(?:0|[1-9]\d*)$/.test(raw)) {
31
+ throw new EngramAccessInputError("limit must be an integer");
32
+ }
33
+ const value = Number(raw);
34
+ if (!Number.isInteger(value) || value < LIMIT_MIN || value > LIMIT_MAX) {
35
+ throw new EngramAccessInputError(`limit must be an integer from ${LIMIT_MIN} to ${LIMIT_MAX}`);
36
+ }
37
+ return value;
38
+ }
39
+
40
+ function parseCursor(raw: string | null): string | undefined {
41
+ if (raw === null) return undefined;
42
+ if (!CURSOR_RE.test(raw)) {
43
+ throw new EngramAccessInputError("cursor is malformed");
44
+ }
45
+ return raw;
46
+ }
47
+
48
+ function parseActionBody(body: Record<string, unknown>): ReviewDeckActionRequest {
49
+ const action = body.action;
50
+ if (action !== "keep" && action !== "not_true" && action !== "prepare_fix") {
51
+ throw new EngramAccessInputError("action must be one of: keep, not_true, prepare_fix");
52
+ }
53
+ const itemId = requiredString(body, "itemId");
54
+ const revision = requiredString(body, "revision");
55
+ const idempotencyKey = requiredString(body, "idempotencyKey");
56
+ if (action === "prepare_fix") {
57
+ const correctionText = requiredString(body, "correctionText");
58
+ return { schemaVersion: 1, itemId, revision, action, correctionText, idempotencyKey };
59
+ }
60
+ return { schemaVersion: 1, itemId, revision, action, idempotencyKey };
61
+ }
62
+
63
+ function parseUndoBody(body: Record<string, unknown>): ReviewDeckUndoRequest {
64
+ return {
65
+ schemaVersion: 1,
66
+ receiptId: requiredString(body, "receiptId"),
67
+ expectedRevision: requiredString(body, "expectedRevision"),
68
+ idempotencyKey: requiredString(body, "idempotencyKey"),
69
+ };
70
+ }
71
+
72
+ export abstract class ReviewDeckAccessHttpBase extends SupportPassportAccessHttpBase {
73
+ protected abstract enforceTokenOp(op: OperationName): void;
74
+ protected abstract resolveNamespace(req: IncomingMessage, bodyNamespace?: string): string | undefined;
75
+ protected abstract readonly maxBodyBytes: number;
76
+
77
+ protected async handleReviewDeckRequest(
78
+ req: IncomingMessage,
79
+ res: ServerResponse,
80
+ pathname: string,
81
+ abortSignal?: AbortSignal,
82
+ ): Promise<boolean> {
83
+ const method = req.method;
84
+ const isList = method === "GET" && (pathname === LIST_PATHS[0] || pathname === LIST_PATHS[1]);
85
+ const isAction = method === "POST" && (pathname === ACTION_PATHS[0] || pathname === ACTION_PATHS[1]);
86
+ const isUndo = method === "POST" && (pathname === UNDO_PATHS[0] || pathname === UNDO_PATHS[1]);
87
+ if (!isList && !isAction && !isUndo) return false;
88
+ if (!this.service.reviewDeckEnabled) {
89
+ this.respondJson(res, 404, { error: "not_found", code: "not_found" });
90
+ return true;
91
+ }
92
+
93
+ const parsed = new URL(req.url ?? "/", "http://127.0.0.1");
94
+ const namespace = this.resolveNamespace(req, parsed.searchParams.get("namespace") ?? undefined);
95
+ const principal = this.resolveRequestPrincipal(req);
96
+
97
+ if (isList) {
98
+ this.enforceTokenOp("review_deck_list");
99
+ const page = await this.service.reviewDeckList({
100
+ namespace,
101
+ principal,
102
+ cursor: parseCursor(parsed.searchParams.get("cursor")),
103
+ limit: parseLimit(parsed.searchParams.get("limit")),
104
+ });
105
+ this.respondJson(res, 200, page);
106
+ return true;
107
+ }
108
+
109
+ if (isAction) this.enforceTokenOp("review_deck_action");
110
+ else this.enforceTokenOp("review_deck_undo");
111
+ const writeQuota = this.reserveWriteRateLimitSlot(req);
112
+ try {
113
+ const body = await this.readJsonBody(req, this.maxBodyBytes);
114
+ const result = isAction
115
+ ? await this.service.reviewDeckAction(parseActionBody(body), {
116
+ namespace,
117
+ principal,
118
+ signal: abortSignal,
119
+ })
120
+ : await this.service.reviewDeckUndo(parseUndoBody(body), {
121
+ namespace,
122
+ principal,
123
+ signal: abortSignal,
124
+ });
125
+ writeQuota.commit();
126
+ this.respondJson(res, 200, result);
127
+ } catch (error) {
128
+ writeQuota.release();
129
+ throw error;
130
+ }
131
+ return true;
132
+ }
133
+ }
@@ -0,0 +1,417 @@
1
+ import assert from "node:assert/strict";
2
+
3
+ import { mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";
4
+ import fs from "node:fs";
5
+ import os from "node:os";
6
+ import path from "node:path";
7
+ import test, { type TestContext } from "node:test";
8
+ import { computeReviewItemRevision } from "./review-deck.js";
9
+ import { readReviewDeckRow } from "./review-deck-snapshot.js";
10
+ import {
11
+ executeReviewDeckAction,
12
+ executeReviewDeckUndo,
13
+ parseReviewLifecycleReceipt,
14
+ ReviewDeckIdempotencyError,
15
+ type ReviewDeckMutationContext,
16
+ type ReviewLifecycleLedgerEvent,
17
+ } from "./review-deck-mutation.js";
18
+
19
+ async function makeMemoryDir(t: TestContext): Promise<string> {
20
+ const dir = await mkdtempSafe(t);
21
+ await mkdir(path.join(dir, "review"), { recursive: true });
22
+ return dir;
23
+ }
24
+
25
+ async function mkdtempSafe(t: TestContext): Promise<string> {
26
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), "remnic-review-deck-"));
27
+ t.after(() => rm(dir, { recursive: true, force: true }));
28
+ return dir;
29
+ }
30
+
31
+ function reviewMarkdown(id: string, extra = ""): string {
32
+ return `---
33
+ id: ${id}
34
+ category: fact
35
+ confidence: 0.4
36
+ confidenceTier: low
37
+ source: test
38
+ created: 2026-05-17T00:00:00.000Z
39
+ reviewReason: low_confidence
40
+ lifecycleState: pending_review
41
+ status: pending_review
42
+ ${extra}---
43
+ Candidate memory.
44
+ `;
45
+ }
46
+
47
+ function makeCtx(
48
+ memoryDir: string,
49
+ events: unknown[],
50
+ extras: Partial<ReviewDeckMutationContext> = {},
51
+ ): ReviewDeckMutationContext {
52
+ return {
53
+ memoryDir,
54
+ namespace: "ns-test",
55
+ principalDigest: "prin-test",
56
+ async appendLifecycleEvents(next) {
57
+ events.push(...next);
58
+ },
59
+ async readLifecycleEvents(memoryId) {
60
+ if (!memoryId) return events;
61
+ return events.filter((row) => {
62
+ if (!row || typeof row !== "object" || !("memoryId" in row)) return false;
63
+ return row.memoryId === memoryId;
64
+ });
65
+ },
66
+ ...extras,
67
+ };
68
+ }
69
+
70
+ async function writeQueueItem(
71
+ memoryDir: string,
72
+ id: string,
73
+ extra = "",
74
+ ): Promise<{ filePath: string; content: string; revision: string }> {
75
+ const filePath = path.join(memoryDir, "review", `${id}.md`);
76
+ const content = reviewMarkdown(id, extra);
77
+ await writeFile(filePath, content, "utf8");
78
+ const row = readReviewDeckRow({ memoryDir, itemId: id });
79
+ assert.ok(row, `expected pending review row ${id}`);
80
+ return { filePath, content, revision: row.revision };
81
+ }
82
+
83
+ function ledgerEvent(value: unknown): ReviewLifecycleLedgerEvent {
84
+ if (!value || typeof value !== "object") throw new Error("expected lifecycle event");
85
+ // Test ledger rows are objects this suite appended.
86
+ return value as ReviewLifecycleLedgerEvent;
87
+ }
88
+
89
+ function todayStamp(): string {
90
+ return new Date().toISOString().split("T")[0];
91
+ }
92
+
93
+ test("keep promotes through performReview and fires tombstone revocation", async (t) => {
94
+ const memoryDir = await makeMemoryDir(t);
95
+ const events: unknown[] = [];
96
+ const hookCalls: Array<[string, string]> = [];
97
+ const item = await writeQueueItem(memoryDir, "keep-blocked", "blockedBy: tomb-1\n");
98
+ const ctx = makeCtx(memoryDir, events, {
99
+ onApproveBlockedMemory(tombstoneId, memoryId) {
100
+ hookCalls.push([tombstoneId, memoryId]);
101
+ },
102
+ });
103
+
104
+ const receipt = await executeReviewDeckAction(ctx, {
105
+ schemaVersion: 1,
106
+ itemId: "keep-blocked",
107
+ revision: item.revision,
108
+ action: "keep",
109
+ idempotencyKey: "keep-1",
110
+ });
111
+
112
+ assert.equal(receipt.outcome, "applied");
113
+ assert.equal(receipt.action, "keep");
114
+ assert.equal(receipt.undoAvailable, true);
115
+ assert.match(receipt.effect, /recalled/);
116
+ assert.deepEqual(hookCalls, [["tomb-1", "keep-blocked"]]);
117
+ await assert.rejects(stat(item.filePath), /ENOENT/);
118
+ const promoted = path.join(memoryDir, "facts", todayStamp(), "keep-blocked.md");
119
+ const promotedText = await readFile(promoted, "utf8");
120
+ assert.match(promotedText, /confidence: 0\.9/);
121
+ const row = ledgerEvent(events[0]);
122
+ assert.equal(row.eventType, "promoted");
123
+ assert.equal(row.actor, "admin-console.review-deck");
124
+ assert.equal(row.reviewReceipt?.action, "approve");
125
+ });
126
+
127
+ test("not true dismisses a queue item", async (t) => {
128
+ const memoryDir = await makeMemoryDir(t);
129
+ const events: unknown[] = [];
130
+ const item = await writeQueueItem(memoryDir, "dismiss-1");
131
+ const receipt = await executeReviewDeckAction(makeCtx(memoryDir, events), {
132
+ schemaVersion: 1,
133
+ itemId: "dismiss-1",
134
+ revision: item.revision,
135
+ action: "not_true",
136
+ idempotencyKey: "dismiss-1",
137
+ });
138
+
139
+ assert.equal(receipt.outcome, "applied");
140
+ assert.equal(receipt.action, "not_true");
141
+ assert.equal(receipt.undoAvailable, true);
142
+ assert.equal(typeof receipt.appliedRevision, "string");
143
+ await assert.rejects(stat(item.filePath), /ENOENT/);
144
+ const row = ledgerEvent(events[0]);
145
+ assert.equal(row.eventType, "rejected");
146
+ assert.equal(row.reviewReceipt?.action, "dismiss");
147
+ const undone = await executeReviewDeckUndo(makeCtx(memoryDir, events), {
148
+ schemaVersion: 1,
149
+ receiptId: receipt.receiptId,
150
+ expectedRevision: receipt.appliedRevision ?? "",
151
+ idempotencyKey: "dismiss-1-undo",
152
+ });
153
+ assert.equal(undone.outcome, "applied");
154
+ assert.equal(await readFile(item.filePath, "utf8"), item.content);
155
+ });
156
+
157
+ test("stale revision returns conflict with no file change", async (t) => {
158
+ const memoryDir = await makeMemoryDir(t);
159
+ const events: unknown[] = [];
160
+ const item = await writeQueueItem(memoryDir, "stale-1");
161
+ const receipt = await executeReviewDeckAction(makeCtx(memoryDir, events), {
162
+ schemaVersion: 1,
163
+ itemId: "stale-1",
164
+ revision: "rv1:deadbeef",
165
+ action: "keep",
166
+ idempotencyKey: "stale-1",
167
+ });
168
+
169
+ assert.equal(receipt.outcome, "conflict");
170
+ assert.equal(receipt.appliedRevision, item.revision);
171
+ assert.equal(receipt.undoAvailable, false);
172
+ assert.equal(await readFile(item.filePath, "utf8"), item.content);
173
+ assert.equal(events.length, 0);
174
+ });
175
+
176
+ test("duplicate idempotency key returns the saved receipt and does not apply twice", async (t) => {
177
+ const memoryDir = await makeMemoryDir(t);
178
+ const events: unknown[] = [];
179
+ const item = await writeQueueItem(memoryDir, "idemp-1");
180
+ const ctx = makeCtx(memoryDir, events);
181
+ const req = {
182
+ schemaVersion: 1 as const,
183
+ itemId: "idemp-1",
184
+ revision: item.revision,
185
+ action: "keep" as const,
186
+ idempotencyKey: "same-key",
187
+ };
188
+ const first = await executeReviewDeckAction(ctx, req);
189
+ const second = await executeReviewDeckAction(ctx, req);
190
+
191
+ assert.equal(first.outcome, "applied");
192
+ assert.equal(second.receiptId, first.receiptId);
193
+ assert.equal(second.outcome, first.outcome);
194
+ assert.equal(second.effect, first.effect);
195
+ assert.equal(events.length, 1);
196
+ const promoted = path.join(memoryDir, "facts", todayStamp(), "idemp-1.md");
197
+ assert.equal(computeReviewItemRevision(await readFile(promoted, "utf8")), first.appliedRevision);
198
+ });
199
+
200
+ test("same key with a different fingerprint is rejected", async (t) => {
201
+ const memoryDir = await makeMemoryDir(t);
202
+ const events: unknown[] = [];
203
+ const firstItem = await writeQueueItem(memoryDir, "fp-a");
204
+ await writeQueueItem(memoryDir, "fp-b");
205
+ const ctx = makeCtx(memoryDir, events);
206
+ await executeReviewDeckAction(ctx, {
207
+ schemaVersion: 1,
208
+ itemId: "fp-a",
209
+ revision: firstItem.revision,
210
+ action: "keep",
211
+ idempotencyKey: "shared-key",
212
+ });
213
+
214
+ await assert.rejects(
215
+ () =>
216
+ executeReviewDeckAction(ctx, {
217
+ schemaVersion: 1,
218
+ itemId: "fp-b",
219
+ revision: computeReviewItemRevision(fs.readFileSync(path.join(memoryDir, "review", "fp-b.md"), "utf8")),
220
+ action: "keep",
221
+ idempotencyKey: "shared-key",
222
+ }),
223
+ ReviewDeckIdempotencyError,
224
+ );
225
+ assert.ok(fs.existsSync(path.join(memoryDir, "review", "fp-b.md")));
226
+ });
227
+
228
+ test("prepare_fix returns a plan id and writes no lifecycle event and no file change", async (t) => {
229
+ const memoryDir = await makeMemoryDir(t);
230
+ const events: unknown[] = [];
231
+ const item = await writeQueueItem(memoryDir, "fix-1");
232
+ const receipt = await executeReviewDeckAction(
233
+ makeCtx(memoryDir, events, {
234
+ async planCorrection(input) {
235
+ return { planId: "plan-fix-1", preview: { itemId: input.itemId } };
236
+ },
237
+ }),
238
+ {
239
+ schemaVersion: 1,
240
+ itemId: "fix-1",
241
+ revision: item.revision,
242
+ action: "prepare_fix",
243
+ correctionText: "Replace the guessed preference.",
244
+ idempotencyKey: "fix-1",
245
+ },
246
+ );
247
+
248
+ assert.equal(receipt.outcome, "planned");
249
+ assert.equal(receipt.correctionPlanId, "plan-fix-1");
250
+ assert.deepEqual(receipt.correctionPreview, { itemId: "fix-1" });
251
+ assert.equal(receipt.undoAvailable, false);
252
+ assert.equal(events.length, 0);
253
+ assert.equal(await readFile(item.filePath, "utf8"), item.content);
254
+ });
255
+
256
+ test("abort before the write leaves the file untouched", async (t) => {
257
+ const memoryDir = await makeMemoryDir(t);
258
+ const events: unknown[] = [];
259
+ const item = await writeQueueItem(memoryDir, "abort-1");
260
+ const controller = new AbortController();
261
+ controller.abort();
262
+ await assert.rejects(
263
+ () =>
264
+ executeReviewDeckAction(makeCtx(memoryDir, events, { signal: controller.signal }), {
265
+ schemaVersion: 1,
266
+ itemId: "abort-1",
267
+ revision: item.revision,
268
+ action: "keep",
269
+ idempotencyKey: "abort-1",
270
+ }),
271
+ (err: Error) => err.name === "AbortError",
272
+ );
273
+ assert.equal(await readFile(item.filePath, "utf8"), item.content);
274
+ assert.equal(events.length, 0);
275
+ });
276
+
277
+ test("undo succeeds with no intervening change", async (t) => {
278
+ const memoryDir = await makeMemoryDir(t);
279
+ const events: unknown[] = [];
280
+ const item = await writeQueueItem(memoryDir, "undo-ok");
281
+ const ctx = makeCtx(memoryDir, events);
282
+ const kept = await executeReviewDeckAction(ctx, {
283
+ schemaVersion: 1,
284
+ itemId: "undo-ok",
285
+ revision: item.revision,
286
+ action: "keep",
287
+ idempotencyKey: "undo-ok",
288
+ });
289
+ const undone = await executeReviewDeckUndo(ctx, {
290
+ schemaVersion: 1,
291
+ receiptId: kept.receiptId,
292
+ expectedRevision: kept.appliedRevision ?? "",
293
+ idempotencyKey: "undo-ok-revert",
294
+ });
295
+
296
+ assert.equal(undone.outcome, "applied");
297
+ assert.equal(undone.action, "undo");
298
+ assert.equal(undone.undoAvailable, false);
299
+ assert.equal(await readFile(item.filePath, "utf8"), item.content);
300
+ await assert.rejects(stat(path.join(memoryDir, "facts", todayStamp(), "undo-ok.md")), /ENOENT/);
301
+ const restored = ledgerEvent(events.at(-1));
302
+ assert.equal(restored.eventType, "restored");
303
+ assert.equal(restored.reviewReceipt?.undoOfReceiptId, kept.receiptId);
304
+ });
305
+
306
+ test("undo after an intervening revision change returns conflict and leaves the memory unchanged", async (t) => {
307
+ const memoryDir = await makeMemoryDir(t);
308
+ const events: unknown[] = [];
309
+ const item = await writeQueueItem(memoryDir, "undo-conflict");
310
+ const ctx = makeCtx(memoryDir, events);
311
+ const kept = await executeReviewDeckAction(ctx, {
312
+ schemaVersion: 1,
313
+ itemId: "undo-conflict",
314
+ revision: item.revision,
315
+ action: "keep",
316
+ idempotencyKey: "undo-conflict",
317
+ });
318
+ const promoted = path.join(memoryDir, "facts", todayStamp(), "undo-conflict.md");
319
+ const edited = `${await readFile(promoted, "utf8")}\nEdited after keep.\n`;
320
+ await writeFile(promoted, edited, "utf8");
321
+
322
+ const undone = await executeReviewDeckUndo(ctx, {
323
+ schemaVersion: 1,
324
+ receiptId: kept.receiptId,
325
+ expectedRevision: kept.appliedRevision ?? "",
326
+ idempotencyKey: "undo-conflict-revert",
327
+ });
328
+
329
+ assert.equal(undone.outcome, "conflict");
330
+ assert.equal(await readFile(promoted, "utf8"), edited);
331
+ await assert.rejects(stat(item.filePath), /ENOENT/);
332
+ });
333
+
334
+ test("a corrupt receipt payload fails closed", async (t) => {
335
+ const memoryDir = await makeMemoryDir(t);
336
+ const events: unknown[] = [
337
+ {
338
+ eventId: "mle-corrupt",
339
+ memoryId: "ghost",
340
+ eventType: "promoted",
341
+ timestamp: "2026-05-17T00:00:00.000Z",
342
+ actor: "admin-console.review-deck",
343
+ ruleVersion: "admin-console.review-deck.v1",
344
+ reviewReceipt: {
345
+ schemaVersion: 1,
346
+ receiptId: "rcp1:corrupt",
347
+ requestFingerprint: "rfp1:x",
348
+ principalDigest: 12,
349
+ itemId: "ghost",
350
+ action: "approve",
351
+ beforeRevision: "rv1:a",
352
+ afterRevision: "rv1:b",
353
+ sourcePath: "review/ghost.md",
354
+ },
355
+ },
356
+ ];
357
+ const item = await writeQueueItem(memoryDir, "ghost");
358
+ const undone = await executeReviewDeckUndo(makeCtx(memoryDir, events), {
359
+ schemaVersion: 1,
360
+ receiptId: "rcp1:corrupt",
361
+ expectedRevision: "rv1:b",
362
+ idempotencyKey: "corrupt-undo",
363
+ });
364
+ assert.equal(undone.outcome, "failed");
365
+ assert.equal(undone.itemId, "");
366
+ assert.equal(await readFile(item.filePath, "utf8"), item.content);
367
+ assert.equal(parseReviewLifecycleReceipt(ledgerEvent(events[0]).reviewReceipt), null);
368
+ });
369
+
370
+ test("parseReviewLifecycleReceipt rejects invalid fields", () => {
371
+ assert.equal(parseReviewLifecycleReceipt(null), null);
372
+ assert.equal(parseReviewLifecycleReceipt("nope"), null);
373
+ assert.equal(
374
+ parseReviewLifecycleReceipt({
375
+ schemaVersion: 2,
376
+ receiptId: "rcp1:x",
377
+ requestFingerprint: "rfp1:x",
378
+ principalDigest: "p",
379
+ itemId: "i",
380
+ action: "approve",
381
+ beforeRevision: "a",
382
+ afterRevision: "b",
383
+ sourcePath: "review/x.md",
384
+ }),
385
+ null,
386
+ );
387
+ assert.equal(
388
+ parseReviewLifecycleReceipt({
389
+ schemaVersion: 1,
390
+ receiptId: "rcp1:x",
391
+ requestFingerprint: "rfp1:x",
392
+ principalDigest: "p",
393
+ itemId: "i",
394
+ action: "approve",
395
+ beforeRevision: "a",
396
+ afterRevision: "b",
397
+ sourcePath: "/abs/review/x.md",
398
+ }),
399
+ null,
400
+ );
401
+ const ok = parseReviewLifecycleReceipt({
402
+ schemaVersion: 1,
403
+ receiptId: "rcp1:x",
404
+ requestFingerprint: "rfp1:x",
405
+ principalDigest: "p",
406
+ itemId: "i",
407
+ action: "dismiss",
408
+ beforeRevision: "a",
409
+ afterRevision: "",
410
+ sourcePath: "review/x.md",
411
+ extra: "ignored",
412
+ });
413
+ assert.ok(ok);
414
+ assert.equal(ok?.action, "dismiss");
415
+ assert.equal(ok?.afterRevision, "");
416
+ });
417
+