@remnic/core 9.65.1 → 9.65.3

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 (576) hide show
  1. package/dist/access-admin-ops-surface.d.ts +44 -44
  2. package/dist/access-admin-ops-surface.js +36 -35
  3. package/dist/access-authorization-probe.d.ts +39 -40
  4. package/dist/access-authorization-probe.js +37 -36
  5. package/dist/access-boundary.d.ts +41 -185
  6. package/dist/access-boundary.js +36 -35
  7. package/dist/access-cli.js +110 -107
  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 +36 -35
  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 +40 -41
  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 +38 -37
  18. package/dist/access-http.d.ts +51 -44
  19. package/dist/access-http.js +57 -56
  20. package/dist/access-identity-continuity-surface.d.ts +12 -12
  21. package/dist/access-identity-continuity-surface.js +36 -35
  22. package/dist/access-lcm-surface.d.ts +27 -27
  23. package/dist/access-lcm-surface.js +36 -35
  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 +50 -47
  29. package/dist/access-memory-search-fanout.d.ts +4 -2
  30. package/dist/{access-namespace-preflight-BKUnKsBv.d.ts → access-namespace-preflight-B7Usyz-K.d.ts} +1 -1
  31. package/dist/access-namespace-preflight.d.ts +5 -3
  32. package/dist/access-namespace-preflight.js +36 -35
  33. package/dist/access-observe-write-surface.d.ts +39 -39
  34. package/dist/access-observe-write-surface.js +36 -35
  35. package/dist/access-offline-manifest.d.ts +12 -12
  36. package/dist/access-offline-manifest.js +5 -5
  37. package/dist/access-operations-batch.js +41 -40
  38. package/dist/access-operations.d.ts +46 -47
  39. package/dist/access-operations.js +44 -43
  40. package/dist/access-recall-concurrency.d.ts +40 -40
  41. package/dist/access-recall-concurrency.js +36 -35
  42. package/dist/access-recall-response.d.ts +24 -24
  43. package/dist/access-recall-response.js +36 -35
  44. package/dist/access-recall-surface.d.ts +24 -24
  45. package/dist/access-recall-surface.js +36 -35
  46. package/dist/access-schema.d.ts +139 -139
  47. package/dist/access-schema.js +3 -3
  48. package/dist/{access-service-B1Lbb-nQ.d.ts → access-service-DkaIG3n8.d.ts} +688 -140
  49. package/dist/access-service-helpers.d.ts +40 -40
  50. package/dist/access-service.d.ts +47 -47
  51. package/dist/access-service.js +36 -35
  52. package/dist/access-surface-catalog.d.ts +41 -42
  53. package/dist/access-surface-catalog.js +44 -37
  54. package/dist/access-surface-catalog.js.map +1 -1
  55. package/dist/access-wearables-meetings-surface.d.ts +5 -3
  56. package/dist/action-confidence.d.ts +3 -1
  57. package/dist/active-memory-bridge.d.ts +3 -1
  58. package/dist/active-recall.d.ts +3 -1
  59. package/dist/active-recall.js +11 -1
  60. package/dist/active-recall.js.map +1 -1
  61. package/dist/adapters/index.js +4 -4
  62. package/dist/adapters/registry.js +2 -2
  63. package/dist/ambient-provenance.d.ts +3 -1
  64. package/dist/artifact-search.d.ts +3 -1
  65. package/dist/{auto-sync-5L7EUZ27.js → auto-sync-H64ZCNIR.js} +13 -5
  66. package/dist/{auto-sync-5L7EUZ27.js.map → auto-sync-H64ZCNIR.js.map} +1 -1
  67. package/dist/behavior-learner.d.ts +3 -1
  68. package/dist/behavior-signals.d.ts +3 -1
  69. package/dist/bootstrap.d.ts +12 -12
  70. package/dist/briefing-window.d.ts +4 -2
  71. package/dist/briefing.d.ts +4 -2
  72. package/dist/briefing.js +16 -15
  73. package/dist/buffer-surprise-report.d.ts +3 -1
  74. package/dist/buffer-turn-helpers.d.ts +3 -1
  75. package/dist/buffer.d.ts +4 -2
  76. package/dist/buffer.js +4 -4
  77. package/dist/bulk-import/index.d.ts +5 -3
  78. package/dist/calibration.d.ts +3 -1
  79. package/dist/calibration.js +1 -1
  80. package/dist/capabilities.d.ts +3 -1
  81. package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-YO5QJ6L3.js} +2 -2
  82. package/dist/{catalog-DjVhJoRM.d.ts → catalog-CX2BZEJh.d.ts} +1 -1
  83. package/dist/causal-behavior.d.ts +1 -1
  84. package/dist/causal-consolidation.d.ts +3 -1
  85. package/dist/causal-consolidation.js +20 -19
  86. package/dist/causal-consolidation.js.map +1 -1
  87. package/dist/causal-trajectory-graph.d.ts +1 -1
  88. package/dist/{chunk-MIBKEW7A.js → chunk-2VXWFYJE.js} +3 -3
  89. package/dist/{chunk-3YTTAGPB.js → chunk-3DVBKTSO.js} +2 -2
  90. package/dist/{chunk-EIR5VLIH.js → chunk-4K7IW3F7.js} +2 -2
  91. package/dist/chunk-4K7IW3F7.js.map +1 -0
  92. package/dist/{chunk-JTSVMJHV.js → chunk-4XDGYCZI.js} +3 -3
  93. package/dist/chunk-573TEZCD.js +88 -0
  94. package/dist/chunk-573TEZCD.js.map +1 -0
  95. package/dist/{chunk-HQSBYI5X.js → chunk-57HVIG5U.js} +2 -2
  96. package/dist/{chunk-PMVPCZJZ.js → chunk-6433HV72.js} +2 -2
  97. package/dist/{chunk-N6TRHP72.js → chunk-6TAX66IA.js} +2 -2
  98. package/dist/{chunk-AGKIG3YA.js → chunk-6VALIZKG.js} +2 -2
  99. package/dist/{chunk-YQ3CBLL4.js → chunk-76PL4XLG.js} +512 -8
  100. package/dist/chunk-76PL4XLG.js.map +1 -0
  101. package/dist/{chunk-4NZHHGVL.js → chunk-7BDZTALN.js} +4 -1
  102. package/dist/chunk-7BDZTALN.js.map +1 -0
  103. package/dist/{chunk-NS5ETDYD.js → chunk-7BEPVIH3.js} +3 -3
  104. package/dist/{chunk-JG22O53B.js → chunk-7CBKAQIG.js} +2 -1
  105. package/dist/chunk-7CBKAQIG.js.map +1 -0
  106. package/dist/{chunk-LYIZXQYY.js → chunk-7KFIMGMP.js} +2 -2
  107. package/dist/{chunk-LWVO2QZV.js → chunk-7QOO4LGC.js} +56 -56
  108. package/dist/chunk-AAXJNINV.js +55 -0
  109. package/dist/chunk-AAXJNINV.js.map +1 -0
  110. package/dist/{chunk-56BSXSHC.js → chunk-AB3A7EFH.js} +31 -2
  111. package/dist/{chunk-56BSXSHC.js.map → chunk-AB3A7EFH.js.map} +1 -1
  112. package/dist/{chunk-CCTVAVTT.js → chunk-AUO2LJ3K.js} +2 -2
  113. package/dist/{chunk-ALCJRQ72.js → chunk-AYDDB3XI.js} +2 -2
  114. package/dist/{chunk-3TMYV3LP.js → chunk-AYYGRVRP.js} +5 -5
  115. package/dist/{chunk-W6TSGWYS.js → chunk-AZAA5DNP.js} +2 -2
  116. package/dist/{chunk-WTOE7CW4.js → chunk-BKYPJUQL.js} +122 -16
  117. package/dist/chunk-BKYPJUQL.js.map +1 -0
  118. package/dist/{chunk-6JJT5AKI.js → chunk-BQUEAVNW.js} +2 -2
  119. package/dist/{chunk-2NLLXCJG.js → chunk-BXLOS5AJ.js} +2 -2
  120. package/dist/{chunk-CEH2AFXG.js → chunk-C24UZSFW.js} +6 -6
  121. package/dist/{chunk-ZPN7W3OP.js → chunk-CDUUDBWJ.js} +3 -3
  122. package/dist/{chunk-35NN3ZFA.js → chunk-CTVWELNK.js} +21 -3
  123. package/dist/chunk-CTVWELNK.js.map +1 -0
  124. package/dist/{chunk-Y23B2QXP.js → chunk-D27J626P.js} +2 -2
  125. package/dist/{chunk-2572MRP2.js → chunk-DHTQP334.js} +2 -2
  126. package/dist/{chunk-HJQZQUPC.js → chunk-DJZWNKFO.js} +5 -5
  127. package/dist/{chunk-X7Y7WX73.js → chunk-DQEMWVMT.js} +1 -1
  128. package/dist/{chunk-VJ6ECBIP.js → chunk-E4MVQQVX.js} +2 -2
  129. package/dist/{chunk-SYJ6EKKE.js → chunk-EIVIB73I.js} +2 -2
  130. package/dist/{chunk-HUNSEO5U.js → chunk-EV3YFLCB.js} +2 -2
  131. package/dist/{chunk-GEULB2VI.js → chunk-FC7TIRFS.js} +21 -1
  132. package/dist/chunk-FC7TIRFS.js.map +1 -0
  133. package/dist/{chunk-VPGRXEAB.js → chunk-G57LQRP6.js} +2 -2
  134. package/dist/{chunk-BC4QD3FM.js → chunk-GN55KU2P.js} +2 -2
  135. package/dist/{chunk-4W6INNXO.js → chunk-GUXS322H.js} +2 -2
  136. package/dist/{chunk-DBXZZIDU.js → chunk-H5FW4S5Q.js} +434 -693
  137. package/dist/chunk-H5FW4S5Q.js.map +1 -0
  138. package/dist/chunk-I32NKXE2.js +879 -0
  139. package/dist/chunk-I32NKXE2.js.map +1 -0
  140. package/dist/{chunk-3MADV4YC.js → chunk-IQSC3V2E.js} +2 -2
  141. package/dist/{chunk-UYCIS6V5.js → chunk-JCWY73FK.js} +2 -2
  142. package/dist/{chunk-T42L3S6A.js → chunk-LBWQ65SX.js} +4 -4
  143. package/dist/{chunk-MSTNSVXI.js → chunk-LDBFXD4F.js} +2 -1
  144. package/dist/chunk-LDBFXD4F.js.map +1 -0
  145. package/dist/{chunk-CEQF6L5K.js → chunk-LUNJ3WFO.js} +9 -7
  146. package/dist/chunk-LUNJ3WFO.js.map +1 -0
  147. package/dist/{chunk-256FBCVX.js → chunk-M4AHBM72.js} +7 -7
  148. package/dist/{chunk-YEQEGSJA.js → chunk-MBDJJTAT.js} +3 -3
  149. package/dist/{chunk-IAY7YBXS.js → chunk-MRTUN665.js} +2 -2
  150. package/dist/{chunk-JFJ3MHGV.js → chunk-NXKJHSDN.js} +1 -1
  151. package/dist/chunk-NXKJHSDN.js.map +1 -0
  152. package/dist/{chunk-R3AAOKR2.js → chunk-NZWEEALH.js} +2 -2
  153. package/dist/{chunk-I2HTKOOP.js → chunk-ODZG724P.js} +2 -2
  154. package/dist/{chunk-7QFBLYFP.js → chunk-OJD4WS2E.js} +3 -3
  155. package/dist/{chunk-CUS6S7PN.js → chunk-OLWTCWQ2.js} +9 -9
  156. package/dist/chunk-OLWTCWQ2.js.map +1 -0
  157. package/dist/{chunk-53ENM6F6.js → chunk-P4DHENRE.js} +2 -2
  158. package/dist/{chunk-DEFI2QBT.js → chunk-PAYGC3BD.js} +52 -22
  159. package/dist/chunk-PAYGC3BD.js.map +1 -0
  160. package/dist/{chunk-KPBLJCCV.js → chunk-PDVQ5JU3.js} +2 -2
  161. package/dist/{chunk-7BY7V4YX.js → chunk-Q4WONDMJ.js} +4 -3
  162. package/dist/{chunk-7BY7V4YX.js.map → chunk-Q4WONDMJ.js.map} +1 -1
  163. package/dist/{chunk-ESCQ6LY7.js → chunk-QFMO32TO.js} +3 -3
  164. package/dist/{chunk-HQSPXTQO.js → chunk-QXIQPCCN.js} +1 -1
  165. package/dist/{chunk-CFRBTATE.js → chunk-R47WINCY.js} +3 -3
  166. package/dist/{chunk-G72IPMR7.js → chunk-R4OCGPSH.js} +2 -2
  167. package/dist/{chunk-LCU5R6TQ.js → chunk-RAIUTAZZ.js} +22 -3
  168. package/dist/chunk-RAIUTAZZ.js.map +1 -0
  169. package/dist/chunk-RIAM7DND.js +167 -0
  170. package/dist/chunk-RIAM7DND.js.map +1 -0
  171. package/dist/{chunk-VZVP2W4O.js → chunk-RK4WXUI2.js} +2 -2
  172. package/dist/{chunk-JBPKEARU.js → chunk-RKNJBZ55.js} +4 -4
  173. package/dist/{chunk-6L27N6YI.js → chunk-S7Q5CM7E.js} +2 -2
  174. package/dist/{chunk-CTQRPANJ.js → chunk-SVSRPG6M.js} +2 -2
  175. package/dist/{chunk-GXWDWOWP.js → chunk-TDKSCV62.js} +2 -2
  176. package/dist/{chunk-S2VBSTTA.js → chunk-THG4GYIE.js} +2 -2
  177. package/dist/{chunk-IXRC7EQG.js → chunk-TR7DGXGI.js} +2 -2
  178. package/dist/{chunk-63FHSH7E.js → chunk-TYUS5TLG.js} +4 -4
  179. package/dist/{chunk-7PWWGYGO.js → chunk-URHCUXKI.js} +2 -2
  180. package/dist/{chunk-Z54TXZ2F.js → chunk-VA5KMSAE.js} +16 -7
  181. package/dist/chunk-VA5KMSAE.js.map +1 -0
  182. package/dist/{chunk-KQAFEZQX.js → chunk-VDX2J7OX.js} +2 -2
  183. package/dist/{chunk-MUJ4QFUQ.js → chunk-W4BMEGQA.js} +4 -4
  184. package/dist/{chunk-5HK3CJAR.js → chunk-W675UJCZ.js} +2 -2
  185. package/dist/{chunk-3PXVYJMC.js → chunk-WN5FSGLE.js} +2077 -215
  186. package/dist/chunk-WN5FSGLE.js.map +1 -0
  187. package/dist/{chunk-3RHFGGI5.js → chunk-YF6UHWOV.js} +30 -10
  188. package/dist/chunk-YF6UHWOV.js.map +1 -0
  189. package/dist/{chunk-X5SDZMO7.js → chunk-YHCBJULX.js} +2 -2
  190. package/dist/{chunk-5UYSCYR7.js → chunk-Z4RPXHJH.js} +4 -4
  191. package/dist/{cli-Pulnz-qm.d.ts → cli-ChKeYMZv.d.ts} +5 -5
  192. package/dist/cli.d.ts +25 -25
  193. package/dist/cli.js +81 -78
  194. package/dist/coding/pre-action-gate.d.ts +2 -60
  195. package/dist/compounding/engine.d.ts +4 -2
  196. package/dist/compounding/engine.js +17 -16
  197. package/dist/compounding/preference-consolidator.d.ts +3 -1
  198. package/dist/compression-optimizer.d.ts +3 -1
  199. package/dist/config.d.ts +3 -1
  200. package/dist/config.js +11 -1
  201. package/dist/connectors/codex-materialize-runner.d.ts +3 -1
  202. package/dist/connectors/codex-materialize-runner.js +16 -15
  203. package/dist/connectors/codex-materialize.d.ts +3 -1
  204. package/dist/connectors/index.d.ts +3 -1
  205. package/dist/connectors/index.js +16 -15
  206. package/dist/consolidation-provenance-check.d.ts +4 -2
  207. package/dist/consolidation-undo.d.ts +4 -2
  208. package/dist/contradiction/index.d.ts +10 -270
  209. package/dist/contradiction/index.js +20 -7
  210. package/dist/{contradiction-review-QKJH5DKD.js → contradiction-review-WRVLRWHS.js} +6 -2
  211. package/dist/{contradiction-scan-VOTQRRSX.js → contradiction-scan-AKUWPX5N.js} +5 -3
  212. package/dist/converge-config.d.ts +3 -1
  213. package/dist/convergence-refresh.d.ts +4 -2
  214. package/dist/convergence-refresh.js +18 -17
  215. package/dist/conversation-index/backend.d.ts +3 -1
  216. package/dist/conversation-index/chunker.d.ts +3 -1
  217. package/dist/conversation-index/faiss-adapter.d.ts +3 -1
  218. package/dist/conversation-index/indexer.d.ts +3 -1
  219. package/dist/conversation-index/search.d.ts +3 -1
  220. package/dist/corpus-watermark.d.ts +3 -1
  221. package/dist/corpus-watermark.js +18 -17
  222. package/dist/cross-lingual-recall.d.ts +3 -1
  223. package/dist/day-summary.d.ts +3 -1
  224. package/dist/delinearize.d.ts +3 -1
  225. package/dist/dependency-propagation-config.d.ts +3 -1
  226. package/dist/{dependency-propagation-delivery-Co17gxYb.d.ts → dependency-propagation-delivery-B8ZMBBCY.d.ts} +1 -1
  227. package/dist/direct-answer-wiring.d.ts +3 -1
  228. package/dist/direct-answer.d.ts +3 -1
  229. package/dist/embedding-fallback.d.ts +3 -1
  230. package/dist/enrichment/index.d.ts +3 -1
  231. package/dist/entity-origin-fields.d.ts +3 -1
  232. package/dist/entity-retrieval.d.ts +4 -2
  233. package/dist/entity-retrieval.js +16 -15
  234. package/dist/entity-schema.d.ts +3 -1
  235. package/dist/episodic-context.d.ts +3 -1
  236. package/dist/explicit-capture.d.ts +12 -12
  237. package/dist/explicit-capture.js +7 -6
  238. package/dist/external-wiki-access.d.ts +41 -42
  239. package/dist/external-wiki-access.js +37 -36
  240. package/dist/external-wiki-collection-registration.d.ts +3 -1
  241. package/dist/external-wiki-collection.d.ts +3 -1
  242. package/dist/external-wiki-mcp-tools.d.ts +40 -40
  243. package/dist/extraction-error-classification.d.ts +3 -1
  244. package/dist/extraction-faithfulness.d.ts +3 -1
  245. package/dist/extraction-judge-telemetry.d.ts +3 -1
  246. package/dist/extraction-judge-training.d.ts +3 -1
  247. package/dist/extraction-judge.d.ts +3 -1
  248. package/dist/extraction-judge.js +2 -2
  249. package/dist/extraction-liveness.d.ts +3 -1
  250. package/dist/extraction-normalization.d.ts +3 -1
  251. package/dist/extraction-normalization.js +2 -2
  252. package/dist/extraction-prompt.d.ts +4 -2
  253. package/dist/extraction-prompt.js +1 -1
  254. package/dist/extraction-source-grounding-rules.d.ts +3 -1
  255. package/dist/extraction-source-grounding.d.ts +3 -1
  256. package/dist/extraction.d.ts +3 -1
  257. package/dist/extraction.js +22 -21
  258. package/dist/fallback-llm.d.ts +3 -1
  259. package/dist/graph-dashboard-diff.d.ts +3 -1
  260. package/dist/graph-dashboard-key.d.ts +3 -1
  261. package/dist/graph-dashboard-parser.d.ts +3 -1
  262. package/dist/graph-edge-reinforcement.d.ts +3 -1
  263. package/dist/graph-path-reconstruction.d.ts +3 -1
  264. package/dist/graph-path-scoring.d.ts +3 -1
  265. package/dist/graph-snapshot.d.ts +3 -1
  266. package/dist/graph.d.ts +3 -1
  267. package/dist/harmonic-retrieval.js +1 -1
  268. package/dist/importance.d.ts +3 -1
  269. package/dist/importers/index.d.ts +3 -1
  270. package/dist/in-flight-reads.d.ts +3 -1
  271. package/dist/index-CexDrJzC.d.ts +284 -0
  272. package/dist/index.d.ts +946 -707
  273. package/dist/index.js +253 -151
  274. package/dist/intent.d.ts +3 -1
  275. package/dist/lcm/engine.d.ts +3 -1
  276. package/dist/lcm/engine.js +3 -3
  277. package/dist/lcm/index.d.ts +3 -1
  278. package/dist/lcm/index.js +6 -6
  279. package/dist/lcm/tools.d.ts +3 -1
  280. package/dist/lifecycle.d.ts +3 -1
  281. package/dist/live-connectors-runner.d.ts +3 -1
  282. package/dist/local-llm.d.ts +3 -1
  283. package/dist/local-model-endpoint.d.ts +3 -1
  284. package/dist/maintenance/memory-governance.d.ts +3 -1
  285. package/dist/maintenance/memory-governance.js +16 -15
  286. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +4 -2
  287. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +16 -15
  288. package/dist/maintenance/rebuild-memory-projection.d.ts +4 -2
  289. package/dist/maintenance/rebuild-memory-projection.js +17 -16
  290. package/dist/{maintenance-DiSLtVN7.d.ts → maintenance-nkdtSrVr.d.ts} +3 -3
  291. package/dist/mcp-memory-inspector-app.d.ts +37 -37
  292. package/dist/mcp-read-only-tools.js +1 -1
  293. package/dist/memory-action-policy.d.ts +3 -1
  294. package/dist/memory-cache.d.ts +3 -1
  295. package/dist/memory-lifecycle-ledger-utils.d.ts +3 -1
  296. package/dist/memory-projection-store.d.ts +3 -1
  297. package/dist/memory-provenance.d.ts +3 -1
  298. package/dist/memory-snapshot.d.ts +3 -1
  299. package/dist/memory-subject-cli.d.ts +177 -0
  300. package/dist/memory-subject-cli.js +16 -0
  301. package/dist/memory-subject.d.ts +128 -0
  302. package/dist/memory-subject.js +44 -0
  303. package/dist/memory-subject.js.map +1 -0
  304. package/dist/memory-worth-outcomes.d.ts +7 -4
  305. package/dist/memory-worth-outcomes.js +1 -1
  306. package/dist/models-json.d.ts +3 -1
  307. package/dist/namespaces/migrate.d.ts +5 -3
  308. package/dist/namespaces/migrate.js +17 -16
  309. package/dist/namespaces/principal.d.ts +3 -1
  310. package/dist/namespaces/search.d.ts +3 -1
  311. package/dist/namespaces/search.js +6 -6
  312. package/dist/namespaces/storage.d.ts +5 -3
  313. package/dist/namespaces/storage.js +16 -15
  314. package/dist/native-knowledge.d.ts +3 -1
  315. package/dist/offline-sync-impression-drain.d.ts +3 -1
  316. package/dist/operator-doctor-corpus.d.ts +3 -1
  317. package/dist/operator-doctor-corpus.js +19 -18
  318. package/dist/operator-doctor-replica.d.ts +3 -1
  319. package/dist/operator-toolkit.d.ts +5 -3
  320. package/dist/operator-toolkit.js +29 -24
  321. package/dist/orchestration/compression-guideline-coordinator.d.ts +4 -2
  322. package/dist/orchestration/maintenance.d.ts +6 -4
  323. package/dist/orchestration/maintenance.js +22 -21
  324. package/dist/{orchestrator-DzCaxNS4.d.ts → orchestrator-Bvq1-RQs.d.ts} +23 -9
  325. package/dist/orchestrator.d.ts +12 -12
  326. package/dist/orchestrator.js +111 -108
  327. package/dist/patterns-cli.d.ts +3 -1
  328. package/dist/{pipeline-HJ8DKbFl.d.ts → pipeline-C8vfIiTX.d.ts} +1 -1
  329. package/dist/policy-runtime.d.ts +3 -1
  330. package/dist/proactive-contention.d.ts +3 -1
  331. package/dist/provenance.d.ts +3 -1
  332. package/dist/{public-http-DwXauTX3.d.ts → public-http-Cy0aYbys.d.ts} +1 -1
  333. package/dist/{qmd-BzxluoLt.d.ts → qmd-B9p1SZTZ.d.ts} +1 -1
  334. package/dist/qmd-preflight.d.ts +4 -2
  335. package/dist/qmd-recall-cache.d.ts +3 -1
  336. package/dist/qmd.d.ts +4 -2
  337. package/dist/qmd.js +4 -4
  338. package/dist/recall-concurrency-config.d.ts +3 -1
  339. package/dist/recall-disclosure-escalation.d.ts +3 -1
  340. package/dist/recall-explain-renderer.d.ts +3 -1
  341. package/dist/recall-explain-renderer.js +3 -3
  342. package/dist/recall-memory-map.d.ts +3 -1
  343. package/dist/recall-planner-llm.d.ts +3 -1
  344. package/dist/recall-state.d.ts +3 -1
  345. package/dist/recall-tag-filter.d.ts +3 -1
  346. package/dist/recall-timings.d.ts +3 -1
  347. package/dist/recall-xray-cli.d.ts +3 -1
  348. package/dist/recall-xray-cli.js +4 -4
  349. package/dist/recall-xray-renderer.d.ts +3 -1
  350. package/dist/recall-xray-renderer.js +3 -3
  351. package/dist/recall-xray.d.ts +3 -1
  352. package/dist/recall-xray.js +2 -2
  353. package/dist/reconcile/cursor.d.ts +3 -1
  354. package/dist/reconcile/manifest.d.ts +3 -1
  355. package/dist/reconcile/manifest.js +3 -3
  356. package/dist/reconcile/plan.d.ts +3 -1
  357. package/dist/replay/normalizers/chatgpt.d.ts +3 -1
  358. package/dist/replay/normalizers/claude.d.ts +3 -1
  359. package/dist/replay/normalizers/openclaw.d.ts +3 -1
  360. package/dist/replay/normalizers/shared.d.ts +3 -1
  361. package/dist/replay/runner.d.ts +3 -1
  362. package/dist/replay/types.d.ts +3 -1
  363. package/dist/replica-divergence.d.ts +3 -1
  364. package/dist/replica-peers-config.d.ts +3 -1
  365. package/dist/resolution-4552BNRV.js +36 -0
  366. package/dist/resolution-4552BNRV.js.map +1 -0
  367. package/dist/resolve-auth-token.d.ts +3 -1
  368. package/dist/resume-bundles.js +9 -2
  369. package/dist/retrieval-agents.d.ts +4 -2
  370. package/dist/retrieval-tiers.d.ts +3 -1
  371. package/dist/routing/engine.d.ts +3 -1
  372. package/dist/routing/store.d.ts +3 -1
  373. package/dist/salvage-envelope.d.ts +3 -1
  374. package/dist/salvage-envelope.js +10 -2
  375. package/dist/schemas.d.ts +130 -116
  376. package/dist/schemas.js +1 -1
  377. package/dist/{scope-profiles-CEMZz0t5.d.ts → scope-profiles-DLrRxFWR.d.ts} +1 -1
  378. package/dist/search/embed-helper.d.ts +3 -1
  379. package/dist/search/factory.d.ts +3 -1
  380. package/dist/search/factory.js +5 -5
  381. package/dist/search/index.d.ts +3 -1
  382. package/dist/search/index.js +9 -9
  383. package/dist/search/lancedb-backend.d.ts +3 -1
  384. package/dist/search/meilisearch-backend.d.ts +3 -1
  385. package/dist/search/noop-backend.d.ts +3 -1
  386. package/dist/search/orama-backend.d.ts +3 -1
  387. package/dist/search/port.d.ts +3 -1
  388. package/dist/search/remote-backend.d.ts +3 -1
  389. package/dist/{semantic-TddhF0y7.d.ts → semantic-BalR6EXU.d.ts} +1 -1
  390. package/dist/{semantic-consolidation-D9dYj6vu.d.ts → semantic-consolidation-DlN6xe20.d.ts} +1 -1
  391. package/dist/semantic-consolidation.d.ts +4 -2
  392. package/dist/semantic-consolidation.js +17 -16
  393. package/dist/semantic-rule-promotion.js +16 -15
  394. package/dist/semantic-rule-verifier.d.ts +3 -1
  395. package/dist/semantic-rule-verifier.js +16 -15
  396. package/dist/{service-_qgST_0y.d.ts → service-GkYyVfm9.d.ts} +2 -2
  397. package/dist/session-observer-bands.d.ts +3 -1
  398. package/dist/session-observer-state.d.ts +3 -1
  399. package/dist/shared-context/manager.d.ts +13 -11
  400. package/dist/signal.d.ts +3 -1
  401. package/dist/source-agent-qualifier.d.ts +3 -1
  402. package/dist/source-agent-qualifier.js +18 -17
  403. package/dist/{storage-B9lbNTYE.d.ts → storage-BIDzuKIn.d.ts} +3 -2
  404. package/dist/storage.d.ts +4 -2
  405. package/dist/storage.js +18 -17
  406. package/dist/subject-config.d.ts +40 -0
  407. package/dist/subject-config.js +20 -0
  408. package/dist/subject-config.js.map +1 -0
  409. package/dist/summarizer.d.ts +3 -1
  410. package/dist/summary-snapshot.d.ts +3 -1
  411. package/dist/support-passport/index.d.ts +43 -43
  412. package/dist/support-passport/index.js +39 -38
  413. package/dist/temporal-supersession.d.ts +4 -2
  414. package/dist/temporal-timeline-recall.d.ts +3 -1
  415. package/dist/temporal-validity.d.ts +3 -1
  416. package/dist/threading.d.ts +3 -1
  417. package/dist/tier-migration.d.ts +4 -2
  418. package/dist/tier-routing.d.ts +3 -1
  419. package/dist/topics.d.ts +3 -1
  420. package/dist/transcript.d.ts +3 -1
  421. package/dist/transfer/backup.js +2 -2
  422. package/dist/transfer/capsule-export.js +2 -2
  423. package/dist/transfer/capsule-import.js +2 -2
  424. package/dist/transfer/types.d.ts +86 -86
  425. package/dist/trust-score-stage.d.ts +3 -1
  426. package/dist/trust-score.d.ts +3 -1
  427. package/dist/{types-BrEzuxPA.d.ts → types-BxAcOl5Q.d.ts} +360 -32
  428. package/dist/types.d.ts +3 -1
  429. package/dist/types.js +1 -1
  430. package/dist/utility-runtime.d.ts +3 -1
  431. package/dist/verified-recall.js +16 -15
  432. package/dist/who-knows-cli.d.ts +40 -40
  433. package/dist/who-knows-cli.js +17 -16
  434. package/dist/who-knows.d.ts +42 -42
  435. package/dist/who-knows.js +16 -15
  436. package/dist/write-envelope.d.ts +7 -2
  437. package/dist/write-envelope.js +10 -1
  438. package/package.json +2 -2
  439. package/scripts/build-with-heap.mjs +1 -1
  440. package/src/access-boundary.ts +6 -0
  441. package/src/access-http.ts +6 -5
  442. package/src/access-mcp-admin-tools.ts +38 -0
  443. package/src/access-mcp-output-schemas.ts +20 -0
  444. package/src/access-mcp.ts +8 -8
  445. package/src/access-operations-batch.ts +13 -0
  446. package/src/access-service.ts +112 -0
  447. package/src/access-surface-catalog.test.ts +24 -0
  448. package/src/access-surface-catalog.ts +6 -0
  449. package/src/coding/action-gate.test.ts +341 -0
  450. package/src/coding/action-gate.ts +556 -0
  451. package/src/config.ts +15 -17
  452. package/src/contradiction/contradiction-review.ts +50 -4
  453. package/src/contradiction/contradiction-scan.ts +14 -3
  454. package/src/contradiction/resolution.ts +50 -2
  455. package/src/extraction-prompt.ts +1 -0
  456. package/src/extraction.ts +4 -1
  457. package/src/index.ts +9 -9
  458. package/src/mcp-read-only-tools.ts +1 -0
  459. package/src/memory-subject-cli.ts +135 -0
  460. package/src/memory-subject.test.ts +48 -0
  461. package/src/memory-subject.ts +314 -0
  462. package/src/memory-worth-outcomes.test.ts +6 -2
  463. package/src/memory-worth-outcomes.ts +11 -7
  464. package/src/operator-toolkit.ts +1 -1
  465. package/src/orchestration/extraction-persist.ts +48 -48
  466. package/src/orchestration/recall-internal.ts +6 -5
  467. package/src/orchestration/recall-rerank-coordinator.ts +123 -4
  468. package/src/orchestration/recall-result-formatter.ts +6 -2
  469. package/src/orchestration/recall-search-pipeline.ts +14 -1
  470. package/src/preferences/drift-config.ts +118 -0
  471. package/src/preferences/drift-recall.ts +133 -0
  472. package/src/preferences/drift-types.ts +87 -0
  473. package/src/preferences/index.ts +12 -0
  474. package/src/preferences/preference-drift.test.ts +690 -0
  475. package/src/preferences/preference-drift.ts +724 -0
  476. package/src/procedural/library-maintenance.test.ts +582 -0
  477. package/src/procedural/library-maintenance.ts +546 -0
  478. package/src/procedural/maintenance-config.ts +78 -0
  479. package/src/procedural/procedure-recall.ts +29 -1
  480. package/src/procedural/procedure-stats.ts +20 -0
  481. package/src/review/review-deck-access.test.ts +325 -0
  482. package/src/review/review-deck-http-base.ts +133 -0
  483. package/src/review/review-deck-mutation.test.ts +417 -0
  484. package/src/review/review-deck-mutation.ts +677 -0
  485. package/src/review/review-deck-snapshot.ts +196 -0
  486. package/src/review/review-deck-surface.ts +117 -0
  487. package/src/review/review-deck.test.ts +347 -0
  488. package/src/review/review-deck.ts +311 -0
  489. package/src/schemas.ts +7 -0
  490. package/src/spaces/index.ts +38 -2
  491. package/src/storage.ts +10 -8
  492. package/src/subject-config.ts +80 -0
  493. package/src/types.ts +33 -32
  494. package/src/write-envelope.test.ts +14 -0
  495. package/src/write-envelope.ts +24 -3
  496. package/dist/chunk-35NN3ZFA.js.map +0 -1
  497. package/dist/chunk-3PXVYJMC.js.map +0 -1
  498. package/dist/chunk-3RHFGGI5.js.map +0 -1
  499. package/dist/chunk-4NZHHGVL.js.map +0 -1
  500. package/dist/chunk-CEQF6L5K.js.map +0 -1
  501. package/dist/chunk-CUS6S7PN.js.map +0 -1
  502. package/dist/chunk-DBXZZIDU.js.map +0 -1
  503. package/dist/chunk-DEFI2QBT.js.map +0 -1
  504. package/dist/chunk-EIR5VLIH.js.map +0 -1
  505. package/dist/chunk-GEULB2VI.js.map +0 -1
  506. package/dist/chunk-JFJ3MHGV.js.map +0 -1
  507. package/dist/chunk-JG22O53B.js.map +0 -1
  508. package/dist/chunk-LCU5R6TQ.js.map +0 -1
  509. package/dist/chunk-MDVBCPOS.js +0 -402
  510. package/dist/chunk-MDVBCPOS.js.map +0 -1
  511. package/dist/chunk-MSTNSVXI.js.map +0 -1
  512. package/dist/chunk-WTOE7CW4.js.map +0 -1
  513. package/dist/chunk-YQ3CBLL4.js.map +0 -1
  514. package/dist/chunk-Z54TXZ2F.js.map +0 -1
  515. package/dist/resolution-DKMBPXHI.js +0 -18
  516. /package/dist/{capsule-crypto-7FJQINUR.js.map → capsule-crypto-YO5QJ6L3.js.map} +0 -0
  517. /package/dist/{chunk-MIBKEW7A.js.map → chunk-2VXWFYJE.js.map} +0 -0
  518. /package/dist/{chunk-3YTTAGPB.js.map → chunk-3DVBKTSO.js.map} +0 -0
  519. /package/dist/{chunk-JTSVMJHV.js.map → chunk-4XDGYCZI.js.map} +0 -0
  520. /package/dist/{chunk-HQSBYI5X.js.map → chunk-57HVIG5U.js.map} +0 -0
  521. /package/dist/{chunk-PMVPCZJZ.js.map → chunk-6433HV72.js.map} +0 -0
  522. /package/dist/{chunk-N6TRHP72.js.map → chunk-6TAX66IA.js.map} +0 -0
  523. /package/dist/{chunk-AGKIG3YA.js.map → chunk-6VALIZKG.js.map} +0 -0
  524. /package/dist/{chunk-NS5ETDYD.js.map → chunk-7BEPVIH3.js.map} +0 -0
  525. /package/dist/{chunk-LYIZXQYY.js.map → chunk-7KFIMGMP.js.map} +0 -0
  526. /package/dist/{chunk-LWVO2QZV.js.map → chunk-7QOO4LGC.js.map} +0 -0
  527. /package/dist/{chunk-CCTVAVTT.js.map → chunk-AUO2LJ3K.js.map} +0 -0
  528. /package/dist/{chunk-ALCJRQ72.js.map → chunk-AYDDB3XI.js.map} +0 -0
  529. /package/dist/{chunk-3TMYV3LP.js.map → chunk-AYYGRVRP.js.map} +0 -0
  530. /package/dist/{chunk-W6TSGWYS.js.map → chunk-AZAA5DNP.js.map} +0 -0
  531. /package/dist/{chunk-6JJT5AKI.js.map → chunk-BQUEAVNW.js.map} +0 -0
  532. /package/dist/{chunk-2NLLXCJG.js.map → chunk-BXLOS5AJ.js.map} +0 -0
  533. /package/dist/{chunk-CEH2AFXG.js.map → chunk-C24UZSFW.js.map} +0 -0
  534. /package/dist/{chunk-ZPN7W3OP.js.map → chunk-CDUUDBWJ.js.map} +0 -0
  535. /package/dist/{chunk-Y23B2QXP.js.map → chunk-D27J626P.js.map} +0 -0
  536. /package/dist/{chunk-2572MRP2.js.map → chunk-DHTQP334.js.map} +0 -0
  537. /package/dist/{chunk-HJQZQUPC.js.map → chunk-DJZWNKFO.js.map} +0 -0
  538. /package/dist/{chunk-X7Y7WX73.js.map → chunk-DQEMWVMT.js.map} +0 -0
  539. /package/dist/{chunk-VJ6ECBIP.js.map → chunk-E4MVQQVX.js.map} +0 -0
  540. /package/dist/{chunk-SYJ6EKKE.js.map → chunk-EIVIB73I.js.map} +0 -0
  541. /package/dist/{chunk-HUNSEO5U.js.map → chunk-EV3YFLCB.js.map} +0 -0
  542. /package/dist/{chunk-VPGRXEAB.js.map → chunk-G57LQRP6.js.map} +0 -0
  543. /package/dist/{chunk-BC4QD3FM.js.map → chunk-GN55KU2P.js.map} +0 -0
  544. /package/dist/{chunk-4W6INNXO.js.map → chunk-GUXS322H.js.map} +0 -0
  545. /package/dist/{chunk-3MADV4YC.js.map → chunk-IQSC3V2E.js.map} +0 -0
  546. /package/dist/{chunk-UYCIS6V5.js.map → chunk-JCWY73FK.js.map} +0 -0
  547. /package/dist/{chunk-T42L3S6A.js.map → chunk-LBWQ65SX.js.map} +0 -0
  548. /package/dist/{chunk-256FBCVX.js.map → chunk-M4AHBM72.js.map} +0 -0
  549. /package/dist/{chunk-YEQEGSJA.js.map → chunk-MBDJJTAT.js.map} +0 -0
  550. /package/dist/{chunk-IAY7YBXS.js.map → chunk-MRTUN665.js.map} +0 -0
  551. /package/dist/{chunk-R3AAOKR2.js.map → chunk-NZWEEALH.js.map} +0 -0
  552. /package/dist/{chunk-I2HTKOOP.js.map → chunk-ODZG724P.js.map} +0 -0
  553. /package/dist/{chunk-7QFBLYFP.js.map → chunk-OJD4WS2E.js.map} +0 -0
  554. /package/dist/{chunk-53ENM6F6.js.map → chunk-P4DHENRE.js.map} +0 -0
  555. /package/dist/{chunk-KPBLJCCV.js.map → chunk-PDVQ5JU3.js.map} +0 -0
  556. /package/dist/{chunk-ESCQ6LY7.js.map → chunk-QFMO32TO.js.map} +0 -0
  557. /package/dist/{chunk-HQSPXTQO.js.map → chunk-QXIQPCCN.js.map} +0 -0
  558. /package/dist/{chunk-CFRBTATE.js.map → chunk-R47WINCY.js.map} +0 -0
  559. /package/dist/{chunk-G72IPMR7.js.map → chunk-R4OCGPSH.js.map} +0 -0
  560. /package/dist/{chunk-VZVP2W4O.js.map → chunk-RK4WXUI2.js.map} +0 -0
  561. /package/dist/{chunk-JBPKEARU.js.map → chunk-RKNJBZ55.js.map} +0 -0
  562. /package/dist/{chunk-6L27N6YI.js.map → chunk-S7Q5CM7E.js.map} +0 -0
  563. /package/dist/{chunk-CTQRPANJ.js.map → chunk-SVSRPG6M.js.map} +0 -0
  564. /package/dist/{chunk-GXWDWOWP.js.map → chunk-TDKSCV62.js.map} +0 -0
  565. /package/dist/{chunk-S2VBSTTA.js.map → chunk-THG4GYIE.js.map} +0 -0
  566. /package/dist/{chunk-IXRC7EQG.js.map → chunk-TR7DGXGI.js.map} +0 -0
  567. /package/dist/{chunk-63FHSH7E.js.map → chunk-TYUS5TLG.js.map} +0 -0
  568. /package/dist/{chunk-7PWWGYGO.js.map → chunk-URHCUXKI.js.map} +0 -0
  569. /package/dist/{chunk-KQAFEZQX.js.map → chunk-VDX2J7OX.js.map} +0 -0
  570. /package/dist/{chunk-MUJ4QFUQ.js.map → chunk-W4BMEGQA.js.map} +0 -0
  571. /package/dist/{chunk-5HK3CJAR.js.map → chunk-W675UJCZ.js.map} +0 -0
  572. /package/dist/{chunk-X5SDZMO7.js.map → chunk-YHCBJULX.js.map} +0 -0
  573. /package/dist/{chunk-5UYSCYR7.js.map → chunk-Z4RPXHJH.js.map} +0 -0
  574. /package/dist/{contradiction-review-QKJH5DKD.js.map → contradiction-review-WRVLRWHS.js.map} +0 -0
  575. /package/dist/{contradiction-scan-VOTQRRSX.js.map → contradiction-scan-AKUWPX5N.js.map} +0 -0
  576. /package/dist/{resolution-DKMBPXHI.js.map → memory-subject-cli.js.map} +0 -0
@@ -8,20 +8,20 @@ import {
8
8
  } from "./chunk-GDB4J2H3.js";
9
9
  import {
10
10
  importCapsule
11
- } from "./chunk-PMVPCZJZ.js";
11
+ } from "./chunk-6433HV72.js";
12
12
  import {
13
13
  buildCodingGraphInstallHint,
14
14
  tryLoadCodingGraphModule
15
15
  } from "./chunk-VQ7B2Q6M.js";
16
- import {
17
- WriteQuarantineStore
18
- } from "./chunk-PJSK6OJM.js";
19
16
  import {
20
17
  WHO_KNOWS_DEFAULT_LIMIT,
21
18
  computeWhoKnows,
22
19
  loadWhoKnowsEntities,
23
20
  validateWhoKnowsInput
24
- } from "./chunk-R3AAOKR2.js";
21
+ } from "./chunk-NZWEEALH.js";
22
+ import {
23
+ WriteQuarantineStore
24
+ } from "./chunk-PJSK6OJM.js";
25
25
  import {
26
26
  trustResultFor
27
27
  } from "./chunk-GNVZQ5JN.js";
@@ -45,25 +45,25 @@ import {
45
45
  } from "./chunk-H7XKCNR6.js";
46
46
  import {
47
47
  toRecallExplainJson
48
- } from "./chunk-W6TSGWYS.js";
48
+ } from "./chunk-AZAA5DNP.js";
49
49
  import {
50
50
  estimateRecallTokens
51
- } from "./chunk-VPGRXEAB.js";
51
+ } from "./chunk-G57LQRP6.js";
52
52
  import {
53
53
  readAggregateExtractionWatermark
54
- } from "./chunk-4W6INNXO.js";
54
+ } from "./chunk-GUXS322H.js";
55
+ import {
56
+ ReplicaDivergenceMonitor
57
+ } from "./chunk-CVILPI77.js";
55
58
  import {
56
59
  recordObjectiveStateSnapshotsFromObservedMessages
57
60
  } from "./chunk-2HIJHXB3.js";
58
61
  import {
59
62
  objectiveStateStoreOverrideForNamespace
60
63
  } from "./chunk-HTP6XRUI.js";
61
- import {
62
- ReplicaDivergenceMonitor
63
- } from "./chunk-CVILPI77.js";
64
64
  import {
65
65
  recordMemoryOutcome
66
- } from "./chunk-EIR5VLIH.js";
66
+ } from "./chunk-4K7IW3F7.js";
67
67
  import {
68
68
  coerceIncludedMemories
69
69
  } from "./chunk-2YA5N2BY.js";
@@ -90,13 +90,14 @@ import {
90
90
  } from "./chunk-IVKIODHO.js";
91
91
  import {
92
92
  buildProcedurePersistBody,
93
- normalizeProcedureSteps
93
+ normalizeProcedureSteps,
94
+ parseProcedureStepsFromBody
94
95
  } from "./chunk-QDW3E4RD.js";
95
96
  import {
96
97
  persistExplicitCapture,
97
98
  queueExplicitCaptureForReview,
98
99
  validateExplicitCaptureInput
99
- } from "./chunk-NS5ETDYD.js";
100
+ } from "./chunk-7BEPVIH3.js";
100
101
  import {
101
102
  boundRecallContextComposition,
102
103
  composeRecallContext,
@@ -116,46 +117,42 @@ import {
116
117
  listMemoryGovernanceRuns,
117
118
  readMemoryGovernanceRunArtifact,
118
119
  runMemoryGovernance
119
- } from "./chunk-SYJ6EKKE.js";
120
+ } from "./chunk-EIVIB73I.js";
120
121
  import {
121
122
  CorpusWatermarkCache,
122
123
  computeServiceCorpusCensus
123
- } from "./chunk-53ENM6F6.js";
124
+ } from "./chunk-P4DHENRE.js";
124
125
  import {
125
126
  ExtractionDeadlineError,
126
127
  isActivityDigestPath,
127
128
  isArtifactMemoryPath,
128
129
  isLocationDayPath,
129
130
  isMeetingRecordPath
130
- } from "./chunk-S2VBSTTA.js";
131
+ } from "./chunk-THG4GYIE.js";
131
132
  import {
132
133
  defaultCapsulesDir
133
134
  } from "./chunk-ZY2MNJR6.js";
134
- import {
135
- filterTrajectoriesByLookbackDays,
136
- readCausalTrajectoryRecords
137
- } from "./chunk-PP7R754B.js";
138
135
  import {
139
136
  FileCalendarSource,
140
137
  buildBriefing,
141
138
  enqueuePassiveCorrectionNotification,
142
139
  parseBriefingFocus,
143
140
  parseBriefingWindow
144
- } from "./chunk-3TMYV3LP.js";
141
+ } from "./chunk-AYYGRVRP.js";
145
142
  import {
146
143
  parseEntityFile,
147
144
  parseFrontmatter,
148
145
  qmdCollectionPathParts,
149
146
  qmdResultPathCandidates,
150
147
  selfDeps
151
- } from "./chunk-DEFI2QBT.js";
148
+ } from "./chunk-PAYGC3BD.js";
152
149
  import {
153
150
  namespaceCollectionName
154
- } from "./chunk-X5SDZMO7.js";
151
+ } from "./chunk-YHCBJULX.js";
155
152
  import {
156
153
  DEFAULT_RECALL_DISCLOSURE,
157
154
  isRecallDisclosure
158
- } from "./chunk-JFJ3MHGV.js";
155
+ } from "./chunk-NXKJHSDN.js";
159
156
  import {
160
157
  normalizeProjectionPreview,
161
158
  normalizeProjectionTags
@@ -166,15 +163,26 @@ import {
166
163
  buildObserveRequestFingerprint,
167
164
  composeMemoryEnvelope,
168
165
  isMemoryCategory
169
- } from "./chunk-LCU5R6TQ.js";
166
+ } from "./chunk-RAIUTAZZ.js";
170
167
  import {
171
168
  applyTagFilter,
172
169
  normalizeTags,
173
170
  parseTagMatch
174
171
  } from "./chunk-BT7NVCML.js";
175
172
  import {
176
- createVersion
173
+ createVersion,
174
+ getVersion,
175
+ revertToVersion
177
176
  } from "./chunk-UFKPQBXH.js";
177
+ import {
178
+ MEMORY_CORPUS_VERSION_SENTINEL,
179
+ bumpMemoryCorpusVersionForDir
180
+ } from "./chunk-XCB6QDL6.js";
181
+ import {
182
+ HistoricalEntityCanonicalIdCache,
183
+ canonicalizeEntityRefFrontmatter,
184
+ repairContentAfterJournalMoveSync
185
+ } from "./chunk-ZVPVTPGI.js";
178
186
  import {
179
187
  supersessionKeysForFact
180
188
  } from "./chunk-5WITETWU.js";
@@ -194,9 +202,16 @@ import {
194
202
  import {
195
203
  isExternalWikiCollectionName
196
204
  } from "./chunk-JV3C2MNQ.js";
205
+ import {
206
+ filterTrajectoriesByLookbackDays,
207
+ readCausalTrajectoryRecords
208
+ } from "./chunk-PP7R754B.js";
209
+ import {
210
+ computePromotionCandidates
211
+ } from "./chunk-RIAM7DND.js";
197
212
  import {
198
213
  exportCapsule
199
- } from "./chunk-KQAFEZQX.js";
214
+ } from "./chunk-VDX2J7OX.js";
200
215
  import {
201
216
  evaluateActionConfidence
202
217
  } from "./chunk-Z2YFLXHU.js";
@@ -225,7 +240,7 @@ import {
225
240
  } from "./chunk-LNEWDF2A.js";
226
241
  import {
227
242
  createOfflineSyncManifestStream
228
- } from "./chunk-I2HTKOOP.js";
243
+ } from "./chunk-ODZG724P.js";
229
244
  import {
230
245
  offlineSyncStorageForSnapshot
231
246
  } from "./chunk-HZNYJN77.js";
@@ -243,6 +258,7 @@ import {
243
258
  } from "./chunk-KCT36JAW.js";
244
259
  import {
245
260
  inferMemoryStatus,
261
+ isActiveMemoryStatus,
246
262
  toMemoryPathRel
247
263
  } from "./chunk-7RJUVTVF.js";
248
264
  import {
@@ -251,13 +267,6 @@ import {
251
267
  import {
252
268
  displayErrorDetail
253
269
  } from "./chunk-RL6NEVXT.js";
254
- import {
255
- computeContentHash
256
- } from "./chunk-5FVVY2EB.js";
257
- import {
258
- serializeMutations,
259
- withHeldFileLock
260
- } from "./chunk-FFAZ2XFU.js";
261
270
  import {
262
271
  SUPPORT_PASSPORT_ATTRIBUTE_KEYS,
263
272
  SUPPORT_PASSPORT_CARD_TAG,
@@ -284,6 +293,13 @@ import {
284
293
  import {
285
294
  stripAttributesSuffix
286
295
  } from "./chunk-JDSVLVCG.js";
296
+ import {
297
+ computeContentHash
298
+ } from "./chunk-5FVVY2EB.js";
299
+ import {
300
+ serializeMutations,
301
+ withHeldFileLock
302
+ } from "./chunk-FFAZ2XFU.js";
287
303
  import {
288
304
  sanitizeMemoryContent
289
305
  } from "./chunk-5GKPFL3S.js";
@@ -374,6 +390,10 @@ import {
374
390
  raceAbort,
375
391
  throwIfAborted
376
392
  } from "./chunk-BTTPKDIL.js";
393
+ import {
394
+ readJsonFile,
395
+ writeJsonFileAtomic
396
+ } from "./chunk-P77QX3ID.js";
377
397
  import {
378
398
  AccessAuditAdapter
379
399
  } from "./chunk-TVVEYCNW.js";
@@ -387,7 +407,8 @@ import {
387
407
  SecureStoreLockedError
388
408
  } from "./chunk-XQ3HXAQH.js";
389
409
  import {
390
- ALL_CATEGORY_DIRS
410
+ ALL_CATEGORY_DIRS,
411
+ getCategoryDir
391
412
  } from "./chunk-VS2IYZRU.js";
392
413
  import {
393
414
  recordCitationUsage
@@ -397,7 +418,7 @@ import {
397
418
  } from "./chunk-3WCASNQZ.js";
398
419
 
399
420
  // src/access-service.ts
400
- import { createHash as createHash10 } from "crypto";
421
+ import { createHash as createHash13 } from "crypto";
401
422
  import { constants as fsConstants2 } from "fs";
402
423
  import { readdirSync, unlinkSync } from "fs";
403
424
  import { stat as stat3 } from "fs/promises";
@@ -5367,6 +5388,7 @@ var OPERATION_NAMES = [
5367
5388
  "recall_tier_explain",
5368
5389
  "recall_xray",
5369
5390
  "who_knows",
5391
+ "promotion_candidates",
5370
5392
  "namespace_writable",
5371
5393
  "wearables_status",
5372
5394
  "wearables_sync",
@@ -5387,6 +5409,7 @@ var OPERATION_NAMES = [
5387
5409
  "procedure_mining_run",
5388
5410
  "pattern_reinforcement_run",
5389
5411
  "procedural_stats",
5412
+ "procedure_library_maintenance",
5390
5413
  "memory_timeline",
5391
5414
  "suggestion_submit",
5392
5415
  "entity_get",
@@ -5437,6 +5460,7 @@ var OPERATION_NAMES = [
5437
5460
  "review_list",
5438
5461
  "review_resolve",
5439
5462
  "contradiction_scan_run",
5463
+ "preference_drift_scan",
5440
5464
  "memory_summarize_hourly",
5441
5465
  "conversation_index_update",
5442
5466
  "profiling_report",
@@ -5481,6 +5505,9 @@ var OPERATION_NAMES = [
5481
5505
  "trust_zones_status",
5482
5506
  "trust_zones_records",
5483
5507
  "review_disposition",
5508
+ "review_deck_list",
5509
+ "review_deck_action",
5510
+ "review_deck_undo",
5484
5511
  "trust_zones_promote",
5485
5512
  "trust_zones_demo_seed",
5486
5513
  "citations_observed",
@@ -5558,10 +5585,10 @@ function formatZodIssues(error) {
5558
5585
  const parts = [];
5559
5586
  for (const issue of error.issues) {
5560
5587
  const hasNumeric = issue.path.some((p) => typeof p === "number");
5561
- const path16 = hasNumeric ? issue.path.filter((p) => typeof p === "string").join(".") || "(root)" : issue.path.length > 0 ? issue.path.join(".") : "(root)";
5588
+ const path20 = hasNumeric ? issue.path.filter((p) => typeof p === "string").join(".") || "(root)" : issue.path.length > 0 ? issue.path.join(".") : "(root)";
5562
5589
  const options = enumOptionsFromIssue(issue);
5563
5590
  const suffix = options ? `. Valid: ${options.join(", ")}` : "";
5564
- parts.push(`${path16}: ${issue.message}${suffix}`);
5591
+ parts.push(`${path20}: ${issue.message}${suffix}`);
5565
5592
  }
5566
5593
  return parts.length > 0 ? `request validation failed: ${parts.join("; ")}` : "request validation failed";
5567
5594
  }
@@ -6114,6 +6141,343 @@ async function promoteMemory(options) {
6114
6141
  };
6115
6142
  }
6116
6143
 
6144
+ // src/procedural/library-maintenance.ts
6145
+ import path10 from "path";
6146
+ var MAINTENANCE_ACTOR = "procedure-library-maintenance";
6147
+ var MAINTENANCE_RULE_VERSION = "procedure-library-maintenance:1";
6148
+ function maintenanceMarkerPath(memoryDir) {
6149
+ return path10.join(memoryDir, "state", "procedure-maintenance.json");
6150
+ }
6151
+ async function readProcedureMaintenanceMarker(memoryDir) {
6152
+ try {
6153
+ const raw = await readJsonFile(maintenanceMarkerPath(memoryDir));
6154
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return null;
6155
+ const m = raw;
6156
+ if (typeof m.lastRunAt !== "string") return null;
6157
+ return {
6158
+ schemaVersion: 1,
6159
+ lastRunAt: m.lastRunAt,
6160
+ lastApplyAt: typeof m.lastApplyAt === "string" ? m.lastApplyAt : null,
6161
+ appliedCount: typeof m.appliedCount === "number" ? m.appliedCount : 0
6162
+ };
6163
+ } catch {
6164
+ return null;
6165
+ }
6166
+ }
6167
+ function evidenceFor(m) {
6168
+ return {
6169
+ memoryId: m.frontmatter.id,
6170
+ mwSuccess: m.frontmatter.mw_success ?? 0,
6171
+ mwFail: m.frontmatter.mw_fail ?? 0,
6172
+ lastAccessed: m.frontmatter.lastAccessed ?? null,
6173
+ updated: m.frontmatter.updated ?? null
6174
+ };
6175
+ }
6176
+ function tsMs(value) {
6177
+ if (typeof value !== "string") return null;
6178
+ const ms = Date.parse(value);
6179
+ return Number.isFinite(ms) ? ms : null;
6180
+ }
6181
+ function procedureTitle(content) {
6182
+ const text = content.replace(/\r\n/g, "\n").trim();
6183
+ const idx = text.search(/^##\s+Step\s+\d+\s*$/im);
6184
+ return (idx === -1 ? text : text.slice(0, idx)).trim();
6185
+ }
6186
+ function normalizePhrase(s) {
6187
+ return s.toLowerCase().replace(/[^a-z0-9]+/g, " ").trim();
6188
+ }
6189
+ function stepSignature(steps) {
6190
+ if (steps === null) return "<unparsed>";
6191
+ return steps.map(
6192
+ (s) => `${s.order}|${normalizePhrase(s.intent)}|${s.toolCall?.kind ?? ""}|${s.toolCall?.signature ?? ""}`
6193
+ ).join(";;");
6194
+ }
6195
+ function isUserEditedProcedure(content) {
6196
+ const steps = parseProcedureStepsFromBody(content);
6197
+ if (steps === null) return true;
6198
+ const rebuilt = buildProcedurePersistBody(procedureTitle(content), steps);
6199
+ return rebuilt.trim() !== content.replace(/\r\n/g, "\n").trim();
6200
+ }
6201
+ function compareCanonical(a, b) {
6202
+ const aMs = tsMs(a.frontmatter.updated) ?? tsMs(a.frontmatter.created) ?? 0;
6203
+ const bMs = tsMs(b.frontmatter.updated) ?? tsMs(b.frontmatter.created) ?? 0;
6204
+ if (aMs !== bMs) return aMs > bMs ? -1 : 1;
6205
+ const aId = a.frontmatter.id ?? "";
6206
+ const bId = b.frontmatter.id ?? "";
6207
+ if (aId !== bId) return aId < bId ? -1 : 1;
6208
+ return 0;
6209
+ }
6210
+ function recentTrajectoryToolText(trajectories) {
6211
+ return trajectories.map((r) => r.actionSummary).join("\n").toLowerCase();
6212
+ }
6213
+ async function runProcedureLibraryMaintenance(options) {
6214
+ const now = options.now ?? /* @__PURE__ */ new Date();
6215
+ const nowIso = now.toISOString();
6216
+ const mode = options.apply === true ? "apply" : "shadow";
6217
+ const cfg = options.config.procedural;
6218
+ if (cfg?.enabled !== true || cfg.maintenance?.enabled !== true) {
6219
+ return {
6220
+ schemaVersion: 1,
6221
+ generatedAt: nowIso,
6222
+ mode,
6223
+ scannedProcedures: 0,
6224
+ proposed: [],
6225
+ applied: [],
6226
+ appliedCount: 0,
6227
+ skippedReason: cfg?.enabled !== true ? "procedural_disabled" : "maintenance_disabled"
6228
+ };
6229
+ }
6230
+ const maintenance = cfg.maintenance;
6231
+ const all = await options.storage.readAllMemories();
6232
+ const byId = /* @__PURE__ */ new Map();
6233
+ for (const m of all) {
6234
+ if (m.frontmatter.category !== "procedure") continue;
6235
+ if (!isActiveMemoryStatus(m.frontmatter.status)) continue;
6236
+ if (typeof m.frontmatter.id === "string" && m.frontmatter.id.length > 0) {
6237
+ byId.set(m.frontmatter.id, m);
6238
+ }
6239
+ }
6240
+ const activeProcedures = [...byId.values()];
6241
+ const report = {
6242
+ schemaVersion: 1,
6243
+ generatedAt: nowIso,
6244
+ mode,
6245
+ scannedProcedures: activeProcedures.length,
6246
+ proposed: [],
6247
+ applied: [],
6248
+ appliedCount: 0
6249
+ };
6250
+ if (activeProcedures.length === 0 && mode === "shadow") return report;
6251
+ const mergeConsumed = /* @__PURE__ */ new Set();
6252
+ if (maintenance.mergeEnabled) {
6253
+ const clusters = /* @__PURE__ */ new Map();
6254
+ for (const m of activeProcedures) {
6255
+ const steps = parseProcedureStepsFromBody(m.content);
6256
+ const key = `${normalizePhrase(procedureTitle(m.content))}
6257
+ @@
6258
+ ${stepSignature(steps)}`;
6259
+ const bucket = clusters.get(key);
6260
+ if (bucket) bucket.push(m);
6261
+ else clusters.set(key, [m]);
6262
+ }
6263
+ for (const cluster of clusters.values()) {
6264
+ if (cluster.length < 2) continue;
6265
+ const sortedCluster = [...cluster].sort(compareCanonical);
6266
+ const userEdited = sortedCluster.filter((m) => isUserEditedProcedure(m.content));
6267
+ if (userEdited.length > 0) {
6268
+ report.proposed.push({
6269
+ action: "flag_user_edited",
6270
+ reasonCode: "user_edited_protected",
6271
+ memoryIds: sortedCluster.map((m) => m.frontmatter.id),
6272
+ reason: "duplicate-signature cluster contains user-edited bodies; merge skipped for manual review",
6273
+ evidence: sortedCluster.map(evidenceFor)
6274
+ });
6275
+ continue;
6276
+ }
6277
+ const canonical = sortedCluster[0];
6278
+ const duplicates = sortedCluster.slice(1);
6279
+ for (const m of sortedCluster) mergeConsumed.add(m.frontmatter.id);
6280
+ report.proposed.push({
6281
+ action: "merge",
6282
+ reasonCode: "merge_duplicate_signature",
6283
+ memoryIds: [canonical.frontmatter.id, ...duplicates.map((m) => m.frontmatter.id)],
6284
+ canonicalId: canonical.frontmatter.id,
6285
+ reason: `near-identical trigger phrase + step signature across ${sortedCluster.length} active procedures`,
6286
+ evidence: sortedCluster.map(evidenceFor)
6287
+ });
6288
+ }
6289
+ }
6290
+ const trajectoryDir = typeof options.config.causalTrajectoryStoreDir === "string" && options.config.causalTrajectoryStoreDir.trim().length > 0 ? options.config.causalTrajectoryStoreDir.trim() : void 0;
6291
+ const { trajectories } = await readCausalTrajectoryRecords({
6292
+ memoryDir: options.memoryDir,
6293
+ causalTrajectoryStoreDir: trajectoryDir
6294
+ });
6295
+ const recentTrajectories = filterTrajectoriesByLookbackDays(
6296
+ trajectories,
6297
+ cfg.lookbackDays,
6298
+ now.getTime()
6299
+ );
6300
+ const repairFlags = [];
6301
+ const staleToolsByProcedure = /* @__PURE__ */ new Map();
6302
+ if (recentTrajectories.length > 0) {
6303
+ const toolText = recentTrajectoryToolText(recentTrajectories);
6304
+ for (const m of activeProcedures) {
6305
+ if (mergeConsumed.has(m.frontmatter.id)) continue;
6306
+ const steps = parseProcedureStepsFromBody(m.content);
6307
+ if (steps === null) continue;
6308
+ const tools = [
6309
+ ...new Set(
6310
+ steps.map((s) => s.toolCall?.kind).filter((t) => typeof t === "string" && t.length > 0)
6311
+ )
6312
+ ];
6313
+ if (tools.length === 0) continue;
6314
+ const stale = tools.filter((t) => !toolText.includes(t.toLowerCase()));
6315
+ if (stale.length === 0) continue;
6316
+ staleToolsByProcedure.set(m.frontmatter.id, stale);
6317
+ repairFlags.push({
6318
+ action: "flag_repair",
6319
+ reasonCode: "needs_repair_stale_tools",
6320
+ memoryIds: [m.frontmatter.id],
6321
+ reason: `tools absent from last ${cfg.lookbackDays}d of trajectories: ${stale.join(", ")}`,
6322
+ evidence: [evidenceFor(m)]
6323
+ });
6324
+ }
6325
+ }
6326
+ const retireActions = [];
6327
+ const retireIds = /* @__PURE__ */ new Set();
6328
+ const idleMs = maintenance.retireIdleDays * 24 * 60 * 60 * 1e3;
6329
+ for (const m of activeProcedures) {
6330
+ if (mergeConsumed.has(m.frontmatter.id)) continue;
6331
+ const mwSuccess = m.frontmatter.mw_success ?? 0;
6332
+ const mwFail = m.frontmatter.mw_fail ?? 0;
6333
+ const failureDominant = mwFail >= maintenance.retireMinOutcomes && mwFail > mwSuccess * maintenance.retireFailRatio;
6334
+ const lastSignalMs = tsMs(m.frontmatter.lastAccessed) ?? tsMs(m.frontmatter.updated);
6335
+ const idle = maintenance.retireIdleDays > 0 && mwSuccess + mwFail === 0 && lastSignalMs !== null && lastSignalMs < now.getTime() - idleMs;
6336
+ const reasonCode = failureDominant ? "retire_failure_dominant" : idle ? "retire_idle" : null;
6337
+ if (reasonCode === null) continue;
6338
+ if (isUserEditedProcedure(m.content)) {
6339
+ report.proposed.push({
6340
+ action: "flag_user_edited",
6341
+ reasonCode: "user_edited_protected",
6342
+ memoryIds: [m.frontmatter.id],
6343
+ reason: `user-edited body exempt from automatic retirement (${reasonCode} waived)`,
6344
+ evidence: [evidenceFor(m)]
6345
+ });
6346
+ continue;
6347
+ }
6348
+ retireIds.add(m.frontmatter.id);
6349
+ retireActions.push({
6350
+ action: "retire",
6351
+ reasonCode,
6352
+ memoryIds: [m.frontmatter.id],
6353
+ reason: reasonCode === "retire_failure_dominant" ? `mw_fail ${mwFail} >= ${maintenance.retireMinOutcomes} and > mw_success ${mwSuccess} * ${maintenance.retireFailRatio}` : `no access signal for ${maintenance.retireIdleDays}d and zero recorded outcomes`,
6354
+ evidence: [evidenceFor(m)]
6355
+ });
6356
+ }
6357
+ for (const flag of repairFlags) {
6358
+ if (retireIds.has(flag.memoryIds[0])) continue;
6359
+ report.proposed.push(flag);
6360
+ }
6361
+ report.proposed.push(...retireActions);
6362
+ if (mode === "shadow") return report;
6363
+ const applied = report.proposed;
6364
+ let writes = 0;
6365
+ for (const action of applied) {
6366
+ try {
6367
+ if (action.action === "merge") {
6368
+ const canonicalId = action.canonicalId;
6369
+ const canonical = canonicalId !== void 0 ? byId.get(canonicalId) : void 0;
6370
+ if (!canonical || canonicalId === void 0) continue;
6371
+ const memberIds = [...action.memoryIds].sort();
6372
+ const previousCount = canonical.frontmatter.reinforcement_count ?? 0;
6373
+ const newCount = Math.max(previousCount, memberIds.length);
6374
+ if (newCount !== canonical.frontmatter.reinforcement_count || canonical.frontmatter.derived_via !== "pattern-reinforcement") {
6375
+ await options.storage.writeMemoryFrontmatter(
6376
+ canonical,
6377
+ {
6378
+ reinforcement_count: newCount,
6379
+ last_reinforced_at: nowIso,
6380
+ derived_via: "pattern-reinforcement",
6381
+ derived_from: memberIds,
6382
+ updated: nowIso
6383
+ },
6384
+ {
6385
+ actor: MAINTENANCE_ACTOR,
6386
+ reasonCode: action.reasonCode,
6387
+ ruleVersion: MAINTENANCE_RULE_VERSION,
6388
+ relatedMemoryIds: memberIds
6389
+ }
6390
+ );
6391
+ writes += 1;
6392
+ }
6393
+ for (const memberId of action.memoryIds) {
6394
+ if (memberId === canonicalId) continue;
6395
+ const member = byId.get(memberId);
6396
+ if (!member) continue;
6397
+ await options.storage.writeMemoryFrontmatter(
6398
+ member,
6399
+ {
6400
+ status: "superseded",
6401
+ supersededBy: canonicalId,
6402
+ supersededAt: nowIso,
6403
+ updated: nowIso
6404
+ },
6405
+ {
6406
+ actor: MAINTENANCE_ACTOR,
6407
+ reasonCode: action.reasonCode,
6408
+ ruleVersion: MAINTENANCE_RULE_VERSION,
6409
+ relatedMemoryIds: [canonicalId]
6410
+ }
6411
+ );
6412
+ writes += 1;
6413
+ }
6414
+ } else if (action.action === "retire") {
6415
+ const memory = byId.get(action.memoryIds[0]);
6416
+ if (!memory) continue;
6417
+ const archivedPath = await options.storage.archiveMemory(memory, {
6418
+ at: now,
6419
+ actor: `${MAINTENANCE_ACTOR}.apply`,
6420
+ reasonCode: action.reasonCode,
6421
+ ruleVersion: MAINTENANCE_RULE_VERSION,
6422
+ relatedMemoryIds: []
6423
+ });
6424
+ if (archivedPath !== null) writes += 1;
6425
+ } else if (action.action === "flag_repair") {
6426
+ const memory = byId.get(action.memoryIds[0]);
6427
+ if (!memory) continue;
6428
+ const existing = memory.frontmatter.structuredAttributes ?? {};
6429
+ const prior = existing.needsRepair;
6430
+ let priorReason = null;
6431
+ if (typeof prior === "string") {
6432
+ try {
6433
+ const parsed = JSON.parse(prior);
6434
+ if (typeof parsed.reason === "string") priorReason = parsed.reason;
6435
+ } catch {
6436
+ priorReason = prior;
6437
+ }
6438
+ }
6439
+ if (priorReason === action.reason) continue;
6440
+ const stamp = JSON.stringify({ reason: action.reason, detectedAt: nowIso });
6441
+ await options.storage.writeMemoryFrontmatter(
6442
+ memory,
6443
+ {
6444
+ structuredAttributes: { ...existing, needsRepair: stamp },
6445
+ updated: nowIso
6446
+ },
6447
+ {
6448
+ actor: MAINTENANCE_ACTOR,
6449
+ reasonCode: action.reasonCode,
6450
+ ruleVersion: MAINTENANCE_RULE_VERSION
6451
+ }
6452
+ );
6453
+ writes += 1;
6454
+ }
6455
+ report.applied.push(action);
6456
+ } catch (err) {
6457
+ log.warn(
6458
+ `procedure-library-maintenance: action ${action.reasonCode} on ${action.memoryIds.join(",")} failed: ${err instanceof Error ? err.message : String(err)}`
6459
+ );
6460
+ }
6461
+ }
6462
+ report.appliedCount = report.applied.length;
6463
+ if (writes > 0) {
6464
+ bumpMemoryCorpusVersionForDir(options.memoryDir);
6465
+ }
6466
+ try {
6467
+ await writeJsonFileAtomic(maintenanceMarkerPath(options.memoryDir), {
6468
+ schemaVersion: 1,
6469
+ lastRunAt: nowIso,
6470
+ lastApplyAt: nowIso,
6471
+ appliedCount: report.appliedCount
6472
+ });
6473
+ } catch (err) {
6474
+ log.warn(
6475
+ `procedure-library-maintenance: failed to persist run marker: ${err instanceof Error ? err.message : String(err)}`
6476
+ );
6477
+ }
6478
+ return report;
6479
+ }
6480
+
6117
6481
  // src/procedural/procedure-stats.ts
6118
6482
  function snapshotConfig(config) {
6119
6483
  const p = config.procedural;
@@ -6127,7 +6491,7 @@ function snapshotConfig(config) {
6127
6491
  recallMaxProcedures: typeof p?.recallMaxProcedures === "number" ? p.recallMaxProcedures : 0
6128
6492
  };
6129
6493
  }
6130
- function tsMs(value) {
6494
+ function tsMs2(value) {
6131
6495
  if (typeof value !== "string") return null;
6132
6496
  const ms = Date.parse(value);
6133
6497
  return Number.isFinite(ms) ? ms : null;
@@ -6149,6 +6513,7 @@ async function computeProcedureStats(options) {
6149
6513
  let lastWriteMs = null;
6150
6514
  let writesLast7Days = 0;
6151
6515
  let minerSourced = 0;
6516
+ let needsRepairFlags = 0;
6152
6517
  const known = [
6153
6518
  "active",
6154
6519
  "pending_review",
@@ -6172,8 +6537,8 @@ async function computeProcedureStats(options) {
6172
6537
  } else {
6173
6538
  counts.other += 1;
6174
6539
  }
6175
- const createdMs = tsMs(m.frontmatter.created);
6176
- const updatedMs = tsMs(m.frontmatter.updated);
6540
+ const createdMs = tsMs2(m.frontmatter.created);
6541
+ const updatedMs = tsMs2(m.frontmatter.updated);
6177
6542
  const latestMs = createdMs !== null && updatedMs !== null ? Math.max(createdMs, updatedMs) : updatedMs ?? createdMs;
6178
6543
  if (latestMs !== null) {
6179
6544
  if (lastWriteMs === null || latestMs > lastWriteMs) {
@@ -6186,7 +6551,11 @@ async function computeProcedureStats(options) {
6186
6551
  if (m.frontmatter.source === "procedure-miner") {
6187
6552
  minerSourced += 1;
6188
6553
  }
6554
+ if (m.frontmatter.structuredAttributes?.needsRepair !== void 0 && isActiveMemoryStatus(m.frontmatter.status)) {
6555
+ needsRepairFlags += 1;
6556
+ }
6189
6557
  }
6558
+ const maintenanceMarker = await readProcedureMaintenanceMarker(storage.dir);
6190
6559
  return {
6191
6560
  schemaVersion: 1,
6192
6561
  generatedAt: new Date(nowMs).toISOString(),
@@ -6196,7 +6565,9 @@ async function computeProcedureStats(options) {
6196
6565
  writesLast7Days,
6197
6566
  minerSourced
6198
6567
  },
6199
- config: snapshotConfig(config)
6568
+ config: snapshotConfig(config),
6569
+ lastMaintenanceAt: maintenanceMarker?.lastRunAt ?? null,
6570
+ needsRepairFlags
6200
6571
  };
6201
6572
  }
6202
6573
  function formatProcedureStatsText(report) {
@@ -6231,6 +6602,10 @@ function formatProcedureStatsText(report) {
6231
6602
  lines.push(` lastWriteAt: ${recent.lastWriteAt ?? "(none)"}`);
6232
6603
  lines.push(` writesLast7Days: ${recent.writesLast7Days}`);
6233
6604
  lines.push(` minerSourced: ${recent.minerSourced}`);
6605
+ lines.push("");
6606
+ lines.push(` maintenance:`);
6607
+ lines.push(` lastMaintenanceAt: ${report.lastMaintenanceAt ?? "(never)"}`);
6608
+ lines.push(` needsRepairFlags: ${report.needsRepairFlags}`);
6234
6609
  return lines.join("\n") + "\n";
6235
6610
  }
6236
6611
 
@@ -8691,7 +9066,7 @@ import { createHash as createHash5 } from "crypto";
8691
9066
  import * as nodePath2 from "path";
8692
9067
 
8693
9068
  // src/orchestration/recall-result-formatter.ts
8694
- import path10 from "path";
9069
+ import path11 from "path";
8695
9070
  function renderConnectorLabel(connector) {
8696
9071
  if (!isValidConnectorId(connector)) return null;
8697
9072
  return connector.length <= CONNECTOR_LABEL_MAX_LENGTH ? connector : `${connector.slice(0, CONNECTOR_LABEL_MAX_LENGTH - 1)}\u2026`;
@@ -8713,15 +9088,15 @@ function resolveEffectiveIdentityInjectionMode(options) {
8713
9088
  return { mode: options.configuredMode, shouldInject: true };
8714
9089
  }
8715
9090
  function displayResultPath(resultPath, memoryDir, namespace) {
8716
- if (!path10.isAbsolute(resultPath)) return resultPath;
8717
- const root = path10.resolve(memoryDir);
8718
- const nsRoot = path10.join(root, "namespaces");
8719
- if (namespace && (resultPath === nsRoot || resultPath.startsWith(nsRoot + path10.sep))) {
8720
- const afterNs = path10.relative(nsRoot, resultPath).split(path10.sep).slice(1).join("/");
9091
+ if (!path11.isAbsolute(resultPath)) return resultPath;
9092
+ const root = path11.resolve(memoryDir);
9093
+ const nsRoot = path11.join(root, "namespaces");
9094
+ if (namespace && (resultPath === nsRoot || resultPath.startsWith(nsRoot + path11.sep))) {
9095
+ const afterNs = path11.relative(nsRoot, resultPath).split(path11.sep).slice(1).join("/");
8721
9096
  if (afterNs) return `${namespace}/${afterNs}`;
8722
9097
  }
8723
- const rel = path10.relative(root, resultPath);
8724
- return rel && !rel.startsWith("..") && !path10.isAbsolute(rel) ? rel.split(path10.sep).join("/") : resultPath;
9098
+ const rel = path11.relative(root, resultPath);
9099
+ return rel && !rel.startsWith("..") && !path11.isAbsolute(rel) ? rel.split(path11.sep).join("/") : resultPath;
8725
9100
  }
8726
9101
  function displaySafeRecallSnapshot(snapshot, memoryDir) {
8727
9102
  const includedMemories = coerceIncludedMemories(snapshot).map((memory) => ({
@@ -8789,14 +9164,15 @@ ${snippet}`;
8789
9164
  const withHandle = handle ? `${head.trimEnd()} ${handle}` : head.trimEnd();
8790
9165
  const connectorLabel = renderConnectorLabel(r.sourceConnector);
8791
9166
  const withConnector = connectorLabel ? `${withHandle} [agent: ${connectorLabel}]` : withHandle;
9167
+ const withDrift = r.driftNote ? `${withConnector} ${r.driftNote}` : withConnector;
8792
9168
  if (hedgeMap) {
8793
9169
  const item = trustResultFor(hedgeMap, r);
8794
9170
  if (item) {
8795
9171
  const hedge = renderEpistemicHedge(item.trust);
8796
- if (hedge.length > 0) return `${withConnector} ${hedge}`;
9172
+ if (hedge.length > 0) return `${withDrift} ${hedge}`;
8797
9173
  }
8798
9174
  }
8799
- return withConnector;
9175
+ return withDrift;
8800
9176
  });
8801
9177
  return { heading: `## ${title}`, entries };
8802
9178
  }
@@ -9989,102 +10365,1497 @@ var AccessRecallSurface = class {
9989
10365
  }
9990
10366
  };
9991
10367
 
9992
- // src/support-passport/card-service.ts
9993
- import { randomUUID as randomUUID2 } from "crypto";
10368
+ // src/review/review-deck-surface.ts
10369
+ import { createHash as createHash8 } from "crypto";
9994
10370
 
9995
- // src/support-passport/errors.ts
9996
- var SupportPassportError = class extends Error {
9997
- code;
9998
- status;
9999
- constructor(code, message, status) {
10371
+ // src/review/review-deck.ts
10372
+ import { createHash as createHash6 } from "crypto";
10373
+ var ReviewDeckCursorError = class extends Error {
10374
+ constructor(message = "Invalid review deck cursor") {
10000
10375
  super(message);
10001
- this.name = "SupportPassportError";
10002
- this.code = code;
10003
- this.status = status;
10376
+ this.name = "ReviewDeckCursorError";
10004
10377
  }
10005
10378
  };
10006
-
10007
- // src/support-passport/card-state.ts
10008
- function invalidInput() {
10009
- return new SupportPassportError("invalid_input", "The support card request is invalid.", 400);
10379
+ var ALLOWED_CHOICES = ["keep", "prepare_fix", "not_true"];
10380
+ var REVERSIBLE_RISK = {
10381
+ keep: "reversible",
10382
+ prepare_fix: "reversible",
10383
+ not_true: "reversible"
10384
+ };
10385
+ var REVIEW_REASON_LABELS = {
10386
+ low_confidence: "Low confidence",
10387
+ suggestion: "Suggested memory",
10388
+ tombstone_blocked: "Blocked by a deletion",
10389
+ contradiction: "Conflicts with another memory",
10390
+ duplicate: "Possible duplicate"
10391
+ };
10392
+ var EXCERPT_LIMIT = 240;
10393
+ function computeReviewItemRevision(fileContent) {
10394
+ return `rv1:${createHash6("sha256").update(fileContent).digest("hex")}`;
10010
10395
  }
10011
- function isStorageConflict(error) {
10012
- return error instanceof SupportPassportError && error.code === "storage_conflict";
10396
+ function projectReviewDeckItem(row, namespace) {
10397
+ const provenance = provenanceFromRow(row);
10398
+ return {
10399
+ schemaVersion: 1,
10400
+ itemId: row.itemId,
10401
+ source: "review",
10402
+ sourceId: row.itemId,
10403
+ memoryId: row.itemId,
10404
+ content: row.content,
10405
+ ...row.category !== void 0 ? { category: row.category } : {},
10406
+ ...row.lifecycleState !== void 0 ? { lifecycleState: row.lifecycleState } : {},
10407
+ ...row.confidence !== void 0 ? { confidence: row.confidence } : {},
10408
+ ...row.confidenceTier !== void 0 ? { confidenceTier: row.confidenceTier } : {},
10409
+ reviewReason: row.reviewReason,
10410
+ reviewReasonLabel: reviewReasonLabel(row.reviewReason),
10411
+ supportCount: provenance.filter((entry) => entry.relation === "supports").length,
10412
+ provenance,
10413
+ allowedChoices: ALLOWED_CHOICES,
10414
+ choiceRisk: REVERSIBLE_RISK,
10415
+ namespace,
10416
+ revision: row.revision
10417
+ };
10013
10418
  }
10014
- function once(callback) {
10015
- let called = false;
10016
- return () => {
10017
- if (called) return;
10018
- called = true;
10019
- callback?.();
10419
+ function compareReviewDeckRows(a, b) {
10420
+ const aBlocked = a.blockedBy && a.blockedBy.length > 0 ? 0 : 1;
10421
+ const bBlocked = b.blockedBy && b.blockedBy.length > 0 ? 0 : 1;
10422
+ if (aBlocked !== bBlocked) return aBlocked - bBlocked;
10423
+ const aConfidence = a.confidence ?? 0.5;
10424
+ const bConfidence = b.confidence ?? 0.5;
10425
+ if (aConfidence !== bConfidence) return aConfidence < bConfidence ? -1 : 1;
10426
+ if (a.created !== b.created) return a.created < b.created ? -1 : 1;
10427
+ if (a.itemId !== b.itemId) return a.itemId < b.itemId ? -1 : 1;
10428
+ return 0;
10429
+ }
10430
+ function encodeReviewDeckCursor(scope, lastSortKey) {
10431
+ return Buffer.from(
10432
+ JSON.stringify({
10433
+ v: 1,
10434
+ p: scope.principalDigest,
10435
+ n: scope.namespace,
10436
+ f: scope.filterDigest,
10437
+ c: scope.corpusVersion,
10438
+ k: lastSortKey
10439
+ }),
10440
+ "utf8"
10441
+ ).toString("base64url");
10442
+ }
10443
+ function decodeReviewDeckCursor(cursor, scope) {
10444
+ const payload = parseCursorPayload(cursor);
10445
+ if (payload.p !== scope.principalDigest || payload.n !== scope.namespace || payload.f !== scope.filterDigest || payload.c !== scope.corpusVersion) {
10446
+ throw new ReviewDeckCursorError("Review deck cursor scope mismatch");
10447
+ }
10448
+ return payload.k;
10449
+ }
10450
+ function buildReviewDeckPage(rows, opts) {
10451
+ const sorted = [...rows].sort(compareReviewDeckRows);
10452
+ const limit = Math.max(0, opts.limit);
10453
+ let start = 0;
10454
+ if (opts.cursor !== void 0) {
10455
+ const lastSortKey = decodeReviewDeckCursor(opts.cursor, opts.scope);
10456
+ start = sorted.findIndex((row) => reviewDeckSortKey(row) > lastSortKey);
10457
+ if (start < 0) start = sorted.length;
10458
+ }
10459
+ const pageRows = limit === 0 ? [] : sorted.slice(start, start + limit);
10460
+ const items = pageRows.map((row) => projectReviewDeckItem(row, opts.scope.namespace));
10461
+ const consumed = start + pageRows.length;
10462
+ const nextCursor = pageRows.length > 0 && consumed < sorted.length ? encodeReviewDeckCursor(opts.scope, reviewDeckSortKey(pageRows[pageRows.length - 1])) : void 0;
10463
+ return {
10464
+ schemaVersion: 1,
10465
+ items,
10466
+ total: sorted.length,
10467
+ ...nextCursor !== void 0 ? { nextCursor } : {}
10020
10468
  };
10021
10469
  }
10022
- function validateOwnerScope(owner, principal) {
10023
- const requestedPrincipal = SupportPassportListCardsInputSchema.safeParse({ principal });
10024
- const namespace = SupportPassportNamespaceSchema.safeParse(owner.namespace);
10025
- const ownerPrincipal = SupportPassportListCardsInputSchema.safeParse({ principal: owner.principal });
10026
- if (!requestedPrincipal.success || !namespace.success || !ownerPrincipal.success || ownerPrincipal.data.principal !== requestedPrincipal.data.principal) {
10027
- throw new SupportPassportError("card_data_invalid", "The support passport owner scope is invalid.", 500);
10470
+ function reviewDeckSortKey(row) {
10471
+ const blocked = row.blockedBy && row.blockedBy.length > 0 ? "0" : "1";
10472
+ return `${blocked} ${(row.confidence ?? 0.5).toFixed(6)} ${row.created} ${row.itemId}`;
10473
+ }
10474
+ function reviewReasonLabel(reason) {
10475
+ const known = REVIEW_REASON_LABELS[reason];
10476
+ if (known) return known;
10477
+ const words = reason.split("_").filter((part) => part.length > 0);
10478
+ if (words.length === 0) return "Review";
10479
+ return words.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
10480
+ }
10481
+ function provenanceFromRow(row) {
10482
+ const fm = parseFrontmatterFields(row.fileContent);
10483
+ const source = nonempty(row.source) ?? nonempty(fm.source);
10484
+ const context = nonempty(row.context) ?? nonempty(fm.context);
10485
+ const created = nonempty(row.created) ?? nonempty(fm.created);
10486
+ const supportIds = idList(fm.supports);
10487
+ const conflictIds = [...idList(fm.conflicts), ...idList(fm.contradicts)];
10488
+ const relatedIds = idList(fm.relatedMemoryIds);
10489
+ const relatedRelation = row.reviewReason === "contradiction" ? "conflicts" : "supports";
10490
+ const provenance = [];
10491
+ if (source !== void 0 || context !== void 0) {
10492
+ provenance.push({
10493
+ relation: "origin",
10494
+ ...created !== void 0 ? { sourceDate: created } : {},
10495
+ excerpt: truncateExcerpt(context ?? source ?? "")
10496
+ });
10028
10497
  }
10029
- return { ...owner, principal: ownerPrincipal.data.principal, namespace: namespace.data };
10030
- }
10031
- var MAX_OWNER_VISIBLE_CARDS = 100;
10032
- var OWNER_VISIBLE_STATUSES = /* @__PURE__ */ new Set(["pending_review", "active"]);
10033
- function revisionFor(card, status, updatedAt) {
10034
- return computeSupportPassportCardRevision({
10035
- cardId: card.cardId,
10036
- title: card.title,
10037
- statement: card.statement,
10038
- category: card.category,
10039
- status,
10040
- updatedAt,
10041
- reviewBy: card.reviewBy
10042
- });
10498
+ for (const sourceMemoryId of supportIds) {
10499
+ provenance.push({ relation: "supports", sourceMemoryId });
10500
+ }
10501
+ for (const sourceMemoryId of conflictIds) {
10502
+ provenance.push({ relation: "conflicts", sourceMemoryId });
10503
+ }
10504
+ for (const sourceMemoryId of relatedIds) {
10505
+ if (supportIds.includes(sourceMemoryId) || conflictIds.includes(sourceMemoryId)) continue;
10506
+ provenance.push({ relation: relatedRelation, sourceMemoryId });
10507
+ }
10508
+ return provenance;
10043
10509
  }
10044
- function projectRequiredCard(memory, namespace, principal) {
10045
- const card = projectSupportPassportCard(memory);
10046
- if (!card) throw new SupportPassportError("card_data_invalid", "The support card data is invalid.", 500);
10047
- if (card.namespace !== namespace || card.owner !== computeSupportPassportOwnerKey(principal)) {
10048
- throw new SupportPassportError("card_not_found", "The support card was not found.", 404);
10510
+ function parseFrontmatterFields(content) {
10511
+ if (!content.startsWith("---\n")) return {};
10512
+ const end = content.indexOf("\n---", 4);
10513
+ if (end === -1) return {};
10514
+ const fields = {};
10515
+ for (const line of content.slice(4, end).split("\n")) {
10516
+ const colonIdx = line.indexOf(":");
10517
+ if (colonIdx === -1) continue;
10518
+ fields[line.slice(0, colonIdx).trim()] = line.slice(colonIdx + 1).trim();
10049
10519
  }
10050
- return card;
10520
+ return fields;
10051
10521
  }
10052
- function projectOwnedCard(memory, namespace, principal) {
10053
- const card = projectSupportPassportCard(memory);
10054
- return card?.namespace === namespace && card.owner === computeSupportPassportOwnerKey(principal) ? card : null;
10522
+ function idList(value) {
10523
+ if (value === void 0 || value.length === 0) return [];
10524
+ return value.replace(/^\[|\]$/g, "").split(",").map((part) => part.trim().replace(/^["']|["']$/g, "")).filter((part) => part.length > 0);
10055
10525
  }
10056
- function ownsMemory(memory, namespace, principal) {
10057
- const attributes = memory.frontmatter.structuredAttributes;
10058
- return attributes !== void 0 && decodeSupportPassportNamespaceAttributes(attributes) === namespace && attributes[SUPPORT_PASSPORT_ATTRIBUTE_KEYS.owner] === computeSupportPassportOwnerKey(principal);
10526
+ function nonempty(value) {
10527
+ if (value === void 0) return void 0;
10528
+ return value.trim().length > 0 ? value : void 0;
10059
10529
  }
10060
- function requireRevision(card, expectedRevision) {
10061
- if (card.card.revision !== expectedRevision) {
10062
- throw new SupportPassportError("revision_conflict", "The support card changed after it was loaded.", 409);
10530
+ function truncateExcerpt(value) {
10531
+ return value.length <= EXCERPT_LIMIT ? value : value.slice(0, EXCERPT_LIMIT);
10532
+ }
10533
+ function parseCursorPayload(cursor) {
10534
+ if (cursor.length === 0) throw new ReviewDeckCursorError("Malformed review deck cursor");
10535
+ let parsed;
10536
+ try {
10537
+ parsed = JSON.parse(Buffer.from(cursor, "base64url").toString("utf8"));
10538
+ } catch {
10539
+ throw new ReviewDeckCursorError("Malformed review deck cursor");
10540
+ }
10541
+ if (!parsed || typeof parsed !== "object") throw new ReviewDeckCursorError("Malformed review deck cursor");
10542
+ const record = parsed;
10543
+ if (record.v !== 1) throw new ReviewDeckCursorError("Unsupported review deck cursor schema");
10544
+ if (typeof record.p !== "string" || typeof record.n !== "string" || typeof record.f !== "string" || typeof record.c !== "string" || typeof record.k !== "string" || record.k.length === 0) {
10545
+ throw new ReviewDeckCursorError("Malformed review deck cursor");
10063
10546
  }
10547
+ return { v: 1, p: record.p, n: record.n, f: record.f, c: record.c, k: record.k };
10064
10548
  }
10065
- function requireStatus(card, status) {
10066
- if (card.card.status !== status) {
10067
- throw new SupportPassportError("invalid_card_status", `The support card must have status ${status}.`, 409);
10549
+
10550
+ // src/review/review-deck-mutation.ts
10551
+ import { createHash as createHash7, randomUUID } from "crypto";
10552
+ import fs3 from "fs";
10553
+ import path14 from "path";
10554
+
10555
+ // src/review/index.ts
10556
+ import fs from "fs";
10557
+ import path12 from "path";
10558
+ var historicalIdCache = new HistoricalEntityCanonicalIdCache();
10559
+ function writeReviewFileCanonicalized(memoryDir, filePath, content) {
10560
+ const stateDir = path12.join(memoryDir, "state");
10561
+ const idsAtWrite = historicalIdCache.get(stateDir);
10562
+ let originalBytes = null;
10563
+ try {
10564
+ originalBytes = fs.readFileSync(filePath, "utf8");
10565
+ } catch {
10566
+ originalBytes = null;
10567
+ }
10568
+ const written = canonicalizeEntityRefFrontmatter(content, idsAtWrite);
10569
+ fs.writeFileSync(filePath, written, "utf8");
10570
+ try {
10571
+ repairContentAfterJournalMoveSync({
10572
+ stateDir,
10573
+ cache: historicalIdCache,
10574
+ idsAtWrite,
10575
+ rawContent: content,
10576
+ lastWritten: written,
10577
+ rewrite: (next) => fs.writeFileSync(filePath, next, "utf8")
10578
+ });
10579
+ } catch (err) {
10580
+ try {
10581
+ if (originalBytes === null) {
10582
+ fs.unlinkSync(filePath);
10583
+ } else {
10584
+ fs.writeFileSync(filePath, originalBytes, "utf8");
10585
+ }
10586
+ } catch {
10587
+ }
10588
+ throw err;
10068
10589
  }
10069
10590
  }
10070
- function ownerVisibleCards(storedCards) {
10071
- const visibleCards = storedCards.filter(
10072
- (item) => OWNER_VISIBLE_STATUSES.has(item.card.status) && !item.draftReplacementPrepared
10073
- );
10074
- if (visibleCards.length <= MAX_OWNER_VISIBLE_CARDS) return visibleCards;
10075
- const cardsWithPendingReplacements = new Set(
10076
- visibleCards.filter((item) => item.card.status === "pending_review").map((item) => item.memory.frontmatter.supersedes).filter((cardId) => typeof cardId === "string")
10077
- );
10078
- return visibleCards.filter(
10079
- (item) => item.card.status !== "active" || !cardsWithPendingReplacements.has(item.card.cardId)
10080
- );
10591
+ var DEFAULT_CONFIDENCE_THRESHOLD = 0.7;
10592
+ function realMemoryRoot(memoryDir) {
10593
+ try {
10594
+ const stat4 = fs.lstatSync(memoryDir);
10595
+ if (!stat4.isDirectory() || stat4.isSymbolicLink()) return null;
10596
+ return fs.realpathSync(memoryDir);
10597
+ } catch {
10598
+ return null;
10599
+ }
10081
10600
  }
10082
- function ownerListCards(storedCards) {
10083
- const visibleCards = ownerVisibleCards(storedCards);
10084
- const byId = new Map(storedCards.map((item) => [item.card.cardId, item]));
10085
- const activeReplacementPredecessors = activeSupportPassportReplacementPredecessorIds(visibleCards);
10086
- const replacedDraftIds = new Set(
10087
- visibleCards.filter(
10601
+ function isPathInside(rootReal, candidateReal) {
10602
+ const relative2 = path12.relative(rootReal, candidateReal);
10603
+ return relative2 === "" || !!relative2 && !relative2.startsWith("..") && !path12.isAbsolute(relative2);
10604
+ }
10605
+ function isSafeDirectory(rootReal, dir) {
10606
+ try {
10607
+ const stat4 = fs.lstatSync(dir);
10608
+ if (!stat4.isDirectory() || stat4.isSymbolicLink()) return false;
10609
+ return isPathInside(rootReal, fs.realpathSync(dir));
10610
+ } catch {
10611
+ return false;
10612
+ }
10613
+ }
10614
+ function ensureSafeDirectory(rootReal, dir) {
10615
+ if (fs.existsSync(dir)) {
10616
+ if (!isSafeDirectory(rootReal, dir)) {
10617
+ throw new Error(`Refusing to write through unsafe review path: ${dir}`);
10618
+ }
10619
+ return;
10620
+ }
10621
+ fs.mkdirSync(dir, { recursive: true });
10622
+ if (!isSafeDirectory(rootReal, dir)) {
10623
+ throw new Error(`Refusing to write through unsafe review path: ${dir}`);
10624
+ }
10625
+ }
10626
+ function listReviewItems(options) {
10627
+ const startTime = Date.now();
10628
+ const {
10629
+ memoryDir,
10630
+ reason: filterReason,
10631
+ limit = 50,
10632
+ confidenceThreshold = DEFAULT_CONFIDENCE_THRESHOLD
10633
+ } = options;
10634
+ const maxItems = Math.max(0, limit);
10635
+ const rootReal = realMemoryRoot(memoryDir);
10636
+ if (!rootReal || maxItems === 0) {
10637
+ return { items: [], total: 0, durationMs: Date.now() - startTime };
10638
+ }
10639
+ const items = [];
10640
+ const isLimitReached = () => items.length >= maxItems;
10641
+ const addItem = (item) => {
10642
+ if (isLimitReached()) return;
10643
+ if (filterReason && item.reviewReason !== filterReason) return;
10644
+ items.push(item);
10645
+ };
10646
+ const suggestionsDir = path12.join(memoryDir, "suggestions");
10647
+ if (!isLimitReached() && fs.existsSync(suggestionsDir) && isSafeDirectory(rootReal, suggestionsDir)) {
10648
+ walkMd(rootReal, suggestionsDir, (filePath, content) => {
10649
+ if (isLimitReached()) return true;
10650
+ const fm = parseFrontmatter2(content);
10651
+ const body = extractBody(content);
10652
+ if (!fm?.id) return false;
10653
+ addItem({
10654
+ id: fm.id,
10655
+ content: body,
10656
+ category: fm.category ?? "suggestion",
10657
+ confidence: parseConfidence(fm.confidence, 0.5),
10658
+ confidenceTier: fm.confidenceTier ?? "low",
10659
+ source: fm.source ?? "unknown",
10660
+ filePath,
10661
+ created: fm.created ?? (/* @__PURE__ */ new Date()).toISOString(),
10662
+ reviewReason: "suggestion"
10663
+ });
10664
+ return isLimitReached();
10665
+ });
10666
+ }
10667
+ const reviewDir = path12.join(memoryDir, "review");
10668
+ if (!isLimitReached() && fs.existsSync(reviewDir) && isSafeDirectory(rootReal, reviewDir)) {
10669
+ walkMd(rootReal, reviewDir, (filePath, content) => {
10670
+ if (isLimitReached()) return true;
10671
+ const fm = parseFrontmatter2(content);
10672
+ const body = extractBody(content);
10673
+ if (!fm?.id) return false;
10674
+ addItem({
10675
+ id: fm.id,
10676
+ content: body,
10677
+ category: fm.category ?? "review",
10678
+ confidence: parseConfidence(fm.confidence, 0.5),
10679
+ confidenceTier: fm.confidenceTier ?? "low",
10680
+ source: fm.source ?? "unknown",
10681
+ filePath,
10682
+ created: fm.created ?? (/* @__PURE__ */ new Date()).toISOString(),
10683
+ reviewReason: fm.reviewReason ?? "low_confidence",
10684
+ context: fm.context
10685
+ });
10686
+ return isLimitReached();
10687
+ });
10688
+ }
10689
+ const categories = ALL_CATEGORY_DIRS;
10690
+ for (const category of categories) {
10691
+ if (isLimitReached()) break;
10692
+ const dir = path12.join(memoryDir, category);
10693
+ if (!fs.existsSync(dir) || !isSafeDirectory(rootReal, dir)) continue;
10694
+ walkMd(rootReal, dir, (filePath, content) => {
10695
+ if (isLimitReached()) return true;
10696
+ const fm = parseFrontmatter2(content);
10697
+ const body = extractBody(content);
10698
+ if (!fm?.id) return false;
10699
+ const confidence = parseConfidence(fm.confidence, 1);
10700
+ if (confidence >= confidenceThreshold && !(typeof fm.blockedBy === "string" && fm.blockedBy.length > 0)) return false;
10701
+ if (parseBoolean(fm.reviewDismissed)) return false;
10702
+ if (items.some((i) => i.id === fm.id)) return false;
10703
+ addItem({
10704
+ id: fm.id,
10705
+ content: body,
10706
+ category: fm.category ?? category.slice(0, -1),
10707
+ confidence,
10708
+ confidenceTier: fm.confidenceTier ?? "low",
10709
+ source: fm.source ?? "unknown",
10710
+ filePath,
10711
+ created: fm.created ?? (/* @__PURE__ */ new Date()).toISOString(),
10712
+ reviewReason: typeof fm.blockedBy === "string" && fm.blockedBy.length > 0 ? "tombstone_blocked" : "low_confidence"
10713
+ });
10714
+ return isLimitReached();
10715
+ });
10716
+ }
10717
+ return {
10718
+ items,
10719
+ total: items.length,
10720
+ durationMs: Date.now() - startTime
10721
+ };
10722
+ }
10723
+ function performReview(memoryDir, itemId, action, options = {}) {
10724
+ const result = action === "approve" ? approveItem(memoryDir, itemId, options) : action === "dismiss" ? dismissItem(memoryDir, itemId, options) : flagItem(memoryDir, itemId, options);
10725
+ if (result.updatedPath !== void 0) bumpMemoryCorpusVersionForDir(memoryDir);
10726
+ return result;
10727
+ }
10728
+ function approveItem(memoryDir, itemId, options) {
10729
+ const rootReal = realMemoryRoot(memoryDir);
10730
+ if (!rootReal) return { itemId, action: "approve", message: "Item not found" };
10731
+ const found = findReviewFileById(memoryDir, itemId, options);
10732
+ if (!found) {
10733
+ return { itemId, action: "approve", message: "Item not found" };
10734
+ }
10735
+ const content = fs.readFileSync(found.filePath, "utf8");
10736
+ const fm = parseFrontmatter2(content);
10737
+ if (!fm) return { itemId, action: "approve", message: "Could not parse frontmatter" };
10738
+ const blockedBy = typeof fm.blockedBy === "string" ? fm.blockedBy : null;
10739
+ const fireBlockedRevocation = () => {
10740
+ if (!blockedBy || !options.onApproveBlockedMemory) return;
10741
+ try {
10742
+ const maybe = options.onApproveBlockedMemory(blockedBy, itemId);
10743
+ if (maybe && typeof maybe.then === "function") {
10744
+ void maybe.catch(() => void 0);
10745
+ }
10746
+ } catch {
10747
+ }
10748
+ };
10749
+ const updatedContent = updateFrontmatterFields(content, {
10750
+ confidence: "0.9",
10751
+ confidenceTier: "high",
10752
+ reviewDismissed: null,
10753
+ // Clear the tombstone-block markers so the promoted memory is active.
10754
+ // Clear the tombstone-block markers AND restore active status so the
10755
+ // promoted memory is fully active in recall + provenance (issue #1579
10756
+ // review: leaving status: pending_review kept it invisible to recall).
10757
+ ...blockedBy ? { blockedBy: null, tombstoneBlockTier: null, status: "active" } : {}
10758
+ });
10759
+ if (found.location === "category") {
10760
+ writeReviewFileCanonicalized(memoryDir, found.filePath, updatedContent);
10761
+ fireBlockedRevocation();
10762
+ return {
10763
+ itemId,
10764
+ action: "approve",
10765
+ updatedPath: found.filePath,
10766
+ message: "Approved low-confidence memory in place with confidence 0.9",
10767
+ ...blockedBy ? { clearedTombstoneId: blockedBy } : {}
10768
+ };
10769
+ }
10770
+ const category = fm.category ?? "fact";
10771
+ const targetDir = getCategoryDir(memoryDir, category);
10772
+ const dateDir = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
10773
+ ensureSafeDirectory(rootReal, targetDir);
10774
+ const outputPath = path12.join(targetDir, dateDir, path12.basename(found.filePath));
10775
+ ensureSafeDirectory(rootReal, path12.dirname(outputPath));
10776
+ const reviewStateDir = path12.join(memoryDir, "state");
10777
+ const idsAtWrite = historicalIdCache.get(reviewStateDir);
10778
+ const promotedWritten = canonicalizeEntityRefFrontmatter(updatedContent, idsAtWrite);
10779
+ const promotedPath = writeFileWithoutClobber(outputPath, promotedWritten, itemId);
10780
+ try {
10781
+ repairContentAfterJournalMoveSync({
10782
+ stateDir: reviewStateDir,
10783
+ cache: historicalIdCache,
10784
+ idsAtWrite,
10785
+ rawContent: updatedContent,
10786
+ lastWritten: promotedWritten,
10787
+ rewrite: (next) => fs.writeFileSync(promotedPath, next, "utf8")
10788
+ });
10789
+ } catch (err) {
10790
+ try {
10791
+ fs.unlinkSync(promotedPath);
10792
+ } catch {
10793
+ }
10794
+ throw err;
10795
+ }
10796
+ fs.unlinkSync(found.filePath);
10797
+ fireBlockedRevocation();
10798
+ return {
10799
+ itemId,
10800
+ action: "approve",
10801
+ updatedPath: promotedPath,
10802
+ message: `Promoted to ${category} with confidence 0.9`,
10803
+ ...blockedBy ? { clearedTombstoneId: blockedBy } : {}
10804
+ };
10805
+ }
10806
+ function dismissItem(memoryDir, itemId, options) {
10807
+ const found = findReviewFileById(memoryDir, itemId, options);
10808
+ if (!found) {
10809
+ return { itemId, action: "dismiss", message: "Item not found" };
10810
+ }
10811
+ if (found.location === "queue") {
10812
+ fs.unlinkSync(found.filePath);
10813
+ return { itemId, action: "dismiss", message: "Dismissed and removed" };
10814
+ }
10815
+ const content = fs.readFileSync(found.filePath, "utf8");
10816
+ writeReviewFileCanonicalized(
10817
+ memoryDir,
10818
+ found.filePath,
10819
+ updateFrontmatterFields(content, {
10820
+ reviewDismissed: "true",
10821
+ reviewDismissedAt: (/* @__PURE__ */ new Date()).toISOString()
10822
+ })
10823
+ );
10824
+ return {
10825
+ itemId,
10826
+ action: "dismiss",
10827
+ updatedPath: found.filePath,
10828
+ message: "Dismissed low-confidence memory in place"
10829
+ };
10830
+ }
10831
+ function flagItem(memoryDir, itemId, options) {
10832
+ const found = findReviewFileById(memoryDir, itemId, options);
10833
+ if (!found) {
10834
+ return { itemId, action: "flag", message: "Item not found" };
10835
+ }
10836
+ const content = fs.readFileSync(found.filePath, "utf8");
10837
+ const fixed = updateFrontmatterFields(content, {
10838
+ flagged: "true",
10839
+ flaggedAt: (/* @__PURE__ */ new Date()).toISOString()
10840
+ });
10841
+ writeReviewFileCanonicalized(memoryDir, found.filePath, fixed);
10842
+ return {
10843
+ itemId,
10844
+ action: "flag",
10845
+ updatedPath: found.filePath,
10846
+ message: "Flagged for further review"
10847
+ };
10848
+ }
10849
+ function findReviewFileById(memoryDir, id, options = {}) {
10850
+ const rootReal = realMemoryRoot(memoryDir);
10851
+ if (!rootReal) return null;
10852
+ for (const loc of ["suggestions", "review"]) {
10853
+ const dir = path12.join(memoryDir, loc);
10854
+ if (!fs.existsSync(dir) || !isSafeDirectory(rootReal, dir)) continue;
10855
+ const found = findFileById(rootReal, dir, id);
10856
+ if (found) return { filePath: found, location: "queue" };
10857
+ }
10858
+ for (const category of ALL_CATEGORY_DIRS) {
10859
+ const dir = path12.join(memoryDir, category);
10860
+ if (!fs.existsSync(dir) || !isSafeDirectory(rootReal, dir)) continue;
10861
+ const found = findFileById(rootReal, dir, id, (fm) => isLowConfidenceReviewCandidate(fm, options));
10862
+ if (found) return { filePath: found, location: "category" };
10863
+ }
10864
+ return null;
10865
+ }
10866
+ function findFileById(rootReal, dir, id, include) {
10867
+ const files = walkMdPaths(rootReal, dir);
10868
+ for (const filePath of files) {
10869
+ const content = readFileSafe(filePath);
10870
+ if (!content) continue;
10871
+ const fm = parseFrontmatter2(content);
10872
+ if (fm?.id === id && (!include || include(fm))) return filePath;
10873
+ }
10874
+ return null;
10875
+ }
10876
+ function isLowConfidenceReviewCandidate(fm, options) {
10877
+ const threshold = options.confidenceThreshold ?? DEFAULT_CONFIDENCE_THRESHOLD;
10878
+ if (typeof fm.blockedBy === "string" && fm.blockedBy.length > 0) {
10879
+ return !parseBoolean(fm.reviewDismissed);
10880
+ }
10881
+ return parseConfidence(fm.confidence, 1) < threshold && !parseBoolean(fm.reviewDismissed);
10882
+ }
10883
+ function parseBoolean(value) {
10884
+ if (typeof value === "boolean") return value;
10885
+ if (typeof value !== "string") return false;
10886
+ const normalized = value.trim().toLowerCase();
10887
+ return normalized === "true" || normalized === "1" || normalized === "yes";
10888
+ }
10889
+ function parseConfidence(value, fallback) {
10890
+ if (typeof value === "number") return Number.isFinite(value) ? value : fallback;
10891
+ if (typeof value === "string") {
10892
+ const n = parseFloat(value);
10893
+ return Number.isFinite(n) ? n : fallback;
10894
+ }
10895
+ return fallback;
10896
+ }
10897
+ function updateFrontmatterFields(content, fields) {
10898
+ const match = content.match(/^(---\n)([\s\S]*?)(\n---(?:\n|$))/);
10899
+ if (!match) return content;
10900
+ const seen = /* @__PURE__ */ new Set();
10901
+ const lines = match[2].split("\n");
10902
+ const nextLines = [];
10903
+ for (const line of lines) {
10904
+ const colonIdx = line.indexOf(":");
10905
+ if (colonIdx === -1) {
10906
+ nextLines.push(line);
10907
+ continue;
10908
+ }
10909
+ const key = line.slice(0, colonIdx).trim();
10910
+ if (!Object.prototype.hasOwnProperty.call(fields, key)) {
10911
+ nextLines.push(line);
10912
+ continue;
10913
+ }
10914
+ seen.add(key);
10915
+ const value = fields[key];
10916
+ if (value !== null) {
10917
+ nextLines.push(`${key}: ${value}`);
10918
+ }
10919
+ }
10920
+ for (const [key, value] of Object.entries(fields)) {
10921
+ if (value !== null && !seen.has(key)) {
10922
+ nextLines.push(`${key}: ${value}`);
10923
+ }
10924
+ }
10925
+ return `${match[1]}${nextLines.join("\n")}${match[3]}${content.slice(match[0].length)}`;
10926
+ }
10927
+ function readFileSafe(filePath) {
10928
+ try {
10929
+ return fs.readFileSync(filePath, "utf8");
10930
+ } catch {
10931
+ return null;
10932
+ }
10933
+ }
10934
+ function writeFileWithoutClobber(basePath, content, discriminator) {
10935
+ const parsed = path12.parse(basePath);
10936
+ const safeDiscriminator = sanitizeFilePart(discriminator);
10937
+ for (let attempt = 0; attempt < 1e3; attempt++) {
10938
+ const candidate = attempt === 0 ? basePath : path12.join(
10939
+ parsed.dir,
10940
+ `${parsed.name}-${safeDiscriminator}${attempt === 1 ? "" : `-${attempt}`}${parsed.ext || ".md"}`
10941
+ );
10942
+ try {
10943
+ fs.writeFileSync(candidate, content, { encoding: "utf8", flag: "wx" });
10944
+ return candidate;
10945
+ } catch (error) {
10946
+ if (error.code === "EEXIST") continue;
10947
+ throw error;
10948
+ }
10949
+ }
10950
+ throw new Error(`Could not find a free review promotion path for ${basePath}`);
10951
+ }
10952
+ function sanitizeFilePart(value) {
10953
+ const chars = [];
10954
+ let previousWasDash = false;
10955
+ for (const char of value) {
10956
+ const next = isSafeFilePartChar(char) ? char : "-";
10957
+ if (next === "-" && previousWasDash) continue;
10958
+ chars.push(next);
10959
+ previousWasDash = next === "-";
10960
+ if (chars.length >= 64) break;
10961
+ }
10962
+ let start = 0;
10963
+ let end = chars.length;
10964
+ while (start < end && chars[start] === "-") start++;
10965
+ while (end > start && chars[end - 1] === "-") end--;
10966
+ const sanitized = chars.slice(start, end).join("");
10967
+ return sanitized || "review-item";
10968
+ }
10969
+ function isSafeFilePartChar(value) {
10970
+ if (value.length !== 1) return false;
10971
+ const code = value.charCodeAt(0);
10972
+ return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122 || value === "." || value === "_" || value === "-";
10973
+ }
10974
+ function parseFrontmatter2(content) {
10975
+ const match = content.match(/^---\n([\s\S]*?)\n---/);
10976
+ if (!match) return null;
10977
+ const fm = {};
10978
+ for (const line of match[1].split("\n")) {
10979
+ const colonIdx = line.indexOf(":");
10980
+ if (colonIdx === -1) continue;
10981
+ const key = line.slice(0, colonIdx).trim();
10982
+ const value = line.slice(colonIdx + 1).trim();
10983
+ fm[key] = value;
10984
+ }
10985
+ return fm;
10986
+ }
10987
+ function extractBody(content) {
10988
+ const match = content.match(/^---\n[\s\S]*?\n---\n([\s\S]*)/);
10989
+ return match ? match[1].trim() : content.trim();
10990
+ }
10991
+ function walkMd(rootReal, dir, callback) {
10992
+ if (!isSafeDirectory(rootReal, dir)) return false;
10993
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
10994
+ const fullPath = path12.join(dir, entry.name);
10995
+ if (entry.isSymbolicLink()) continue;
10996
+ if (entry.isDirectory()) {
10997
+ if (walkMd(rootReal, fullPath, callback)) return true;
10998
+ } else if (entry.isFile() && entry.name.endsWith(".md")) {
10999
+ const content = readFileSafe(fullPath);
11000
+ if (content && callback(fullPath, content) === true) return true;
11001
+ }
11002
+ }
11003
+ return false;
11004
+ }
11005
+ function walkMdPaths(rootReal, dir) {
11006
+ const results = [];
11007
+ if (!isSafeDirectory(rootReal, dir)) return results;
11008
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
11009
+ const fullPath = path12.join(dir, entry.name);
11010
+ if (entry.isSymbolicLink()) continue;
11011
+ if (entry.isDirectory()) {
11012
+ results.push(...walkMdPaths(rootReal, fullPath));
11013
+ } else if (entry.isFile() && entry.name.endsWith(".md")) {
11014
+ results.push(fullPath);
11015
+ }
11016
+ }
11017
+ return results;
11018
+ }
11019
+
11020
+ // src/review/review-deck-snapshot.ts
11021
+ import fs2 from "fs";
11022
+ import path13 from "path";
11023
+ var QUEUE_DIRS = ["suggestions", "review"];
11024
+ function readReviewDeckSnapshot(opts) {
11025
+ const corpusVersion = readCorpusVersion(opts.memoryDir);
11026
+ const rootReal = realMemoryRoot2(opts.memoryDir);
11027
+ if (!rootReal) return { corpusVersion, total: 0, rows: [] };
11028
+ const rows = [];
11029
+ for (const location of QUEUE_DIRS) {
11030
+ const dir = path13.join(opts.memoryDir, location);
11031
+ if (!fs2.existsSync(dir) || !isSafeDirectory2(rootReal, dir)) continue;
11032
+ walkMd2(rootReal, dir, (filePath, content) => {
11033
+ const row = rowFromQueueFile(filePath, content, location);
11034
+ if (row) rows.push(row);
11035
+ });
11036
+ }
11037
+ return { corpusVersion, total: rows.length, rows };
11038
+ }
11039
+ function readReviewDeckRow(opts) {
11040
+ const rootReal = realMemoryRoot2(opts.memoryDir);
11041
+ if (!rootReal) return null;
11042
+ for (const location of QUEUE_DIRS) {
11043
+ const dir = path13.join(opts.memoryDir, location);
11044
+ if (!fs2.existsSync(dir) || !isSafeDirectory2(rootReal, dir)) continue;
11045
+ let found = null;
11046
+ walkMd2(rootReal, dir, (filePath, content) => {
11047
+ const row = rowFromQueueFile(filePath, content, location);
11048
+ if (row?.itemId === opts.itemId) {
11049
+ found = row;
11050
+ return true;
11051
+ }
11052
+ });
11053
+ if (found) return found;
11054
+ }
11055
+ return null;
11056
+ }
11057
+ function readCorpusVersion(memoryDir) {
11058
+ try {
11059
+ return String(fs2.statSync(path13.join(memoryDir, "state", MEMORY_CORPUS_VERSION_SENTINEL)).size);
11060
+ } catch {
11061
+ return "0";
11062
+ }
11063
+ }
11064
+ function rowFromQueueFile(filePath, content, location) {
11065
+ const fm = parseFrontmatter3(content);
11066
+ const itemId = optionalString(fm?.id);
11067
+ if (!fm || !itemId || !isPendingQueueRow(fm)) return null;
11068
+ const blockedBy = optionalString(fm.blockedBy);
11069
+ const confidence = parseOptionalConfidence(fm.confidence);
11070
+ const category = optionalString(fm.category);
11071
+ const confidenceTier = optionalString(fm.confidenceTier);
11072
+ const source = optionalString(fm.source);
11073
+ const context = optionalString(fm.context);
11074
+ const lifecycleState = optionalString(fm.lifecycleState) ?? optionalString(fm.status);
11075
+ const created = optionalString(fm.created) ?? "";
11076
+ const explicitReason = optionalString(fm.reviewReason);
11077
+ return {
11078
+ itemId,
11079
+ filePath,
11080
+ fileContent: content,
11081
+ revision: computeReviewItemRevision(content),
11082
+ content: extractBody2(content),
11083
+ reviewReason: explicitReason ?? (blockedBy ? "tombstone_blocked" : location === "suggestions" ? "suggestion" : "low_confidence"),
11084
+ created,
11085
+ ...category ? { category } : {},
11086
+ ...confidence !== void 0 ? { confidence } : {},
11087
+ ...confidenceTier ? { confidenceTier } : {},
11088
+ ...source ? { source } : {},
11089
+ ...blockedBy ? { blockedBy } : {},
11090
+ ...lifecycleState ? { lifecycleState } : {},
11091
+ ...context ? { context } : {}
11092
+ };
11093
+ }
11094
+ function isPendingQueueRow(fm) {
11095
+ if (parseBoolean2(fm.reviewDismissed)) return false;
11096
+ const status = optionalString(fm.status);
11097
+ return status === void 0 || status === "pending_review";
11098
+ }
11099
+ function realMemoryRoot2(memoryDir) {
11100
+ try {
11101
+ const stat4 = fs2.lstatSync(memoryDir);
11102
+ if (!stat4.isDirectory() || stat4.isSymbolicLink()) return null;
11103
+ return fs2.realpathSync(memoryDir);
11104
+ } catch {
11105
+ return null;
11106
+ }
11107
+ }
11108
+ function isPathInside2(rootReal, candidateReal) {
11109
+ const relative2 = path13.relative(rootReal, candidateReal);
11110
+ return relative2 === "" || !!relative2 && !relative2.startsWith("..") && !path13.isAbsolute(relative2);
11111
+ }
11112
+ function isSafeDirectory2(rootReal, dir) {
11113
+ try {
11114
+ const stat4 = fs2.lstatSync(dir);
11115
+ if (!stat4.isDirectory() || stat4.isSymbolicLink()) return false;
11116
+ return isPathInside2(rootReal, fs2.realpathSync(dir));
11117
+ } catch {
11118
+ return false;
11119
+ }
11120
+ }
11121
+ function walkMd2(rootReal, dir, callback) {
11122
+ if (!isSafeDirectory2(rootReal, dir)) return false;
11123
+ for (const entry of fs2.readdirSync(dir, { withFileTypes: true })) {
11124
+ const fullPath = path13.join(dir, entry.name);
11125
+ if (entry.isSymbolicLink()) continue;
11126
+ if (entry.isDirectory()) {
11127
+ if (walkMd2(rootReal, fullPath, callback)) return true;
11128
+ } else if (entry.isFile() && entry.name.endsWith(".md")) {
11129
+ const content = readFileSafe2(fullPath);
11130
+ if (content && callback(fullPath, content) === true) return true;
11131
+ }
11132
+ }
11133
+ return false;
11134
+ }
11135
+ function readFileSafe2(filePath) {
11136
+ try {
11137
+ return fs2.readFileSync(filePath, "utf8");
11138
+ } catch {
11139
+ return null;
11140
+ }
11141
+ }
11142
+ function splitFrontmatter(content) {
11143
+ if (!content.startsWith("---\n")) return null;
11144
+ const end = content.indexOf("\n---", 4);
11145
+ if (end === -1) return null;
11146
+ const after = end + "\n---".length;
11147
+ const body = content.startsWith("\n", after) ? content.slice(after + 1) : content.slice(after);
11148
+ return { fields: content.slice(4, end), body };
11149
+ }
11150
+ function parseFrontmatter3(content) {
11151
+ const split = splitFrontmatter(content);
11152
+ if (!split) return null;
11153
+ const fm = {};
11154
+ for (const line of split.fields.split("\n")) {
11155
+ const colonIdx = line.indexOf(":");
11156
+ if (colonIdx === -1) continue;
11157
+ fm[line.slice(0, colonIdx).trim()] = line.slice(colonIdx + 1).trim();
11158
+ }
11159
+ return fm;
11160
+ }
11161
+ function extractBody2(content) {
11162
+ const split = splitFrontmatter(content);
11163
+ return split ? split.body.trim() : content.trim();
11164
+ }
11165
+ function parseBoolean2(value) {
11166
+ if (typeof value === "boolean") return value;
11167
+ if (typeof value !== "string") return false;
11168
+ const normalized = value.trim().toLowerCase();
11169
+ return normalized === "true" || normalized === "1" || normalized === "yes";
11170
+ }
11171
+ function optionalString(value) {
11172
+ if (typeof value !== "string") return void 0;
11173
+ const trimmed = value.trim();
11174
+ return trimmed.length > 0 ? trimmed : void 0;
11175
+ }
11176
+ function parseOptionalConfidence(value) {
11177
+ if (typeof value === "number") return Number.isFinite(value) ? value : void 0;
11178
+ if (typeof value === "string" && value.trim().length > 0) {
11179
+ const parsed = Number.parseFloat(value);
11180
+ return Number.isFinite(parsed) ? parsed : void 0;
11181
+ }
11182
+ return void 0;
11183
+ }
11184
+
11185
+ // src/review/review-deck-mutation.ts
11186
+ var ACTOR = "admin-console.review-deck";
11187
+ var RULE_VERSION = "admin-console.review-deck.v1";
11188
+ var DECK_VERSIONING = {
11189
+ enabled: true,
11190
+ maxVersionsPerPage: 20,
11191
+ sidecarDir: ".versions"
11192
+ };
11193
+ var KEEP_EFFECT = "Kept: this memory can now be recalled.";
11194
+ var NOT_TRUE_EFFECT = "Marked untrue: removed from the review queue.";
11195
+ var PLANNED_EFFECT = "Prepared a correction plan.";
11196
+ var PLAN_FAILED_EFFECT = "Could not prepare a correction plan.";
11197
+ var MISSING_EFFECT = "This review item is no longer available.";
11198
+ var CONFLICT_EFFECT = "This memory changed. Review it again.";
11199
+ var UNDO_EFFECT = "Undid the last review decision.";
11200
+ var UNDO_CONFLICT_EFFECT = "Another change happened first. Nothing was undone.";
11201
+ var UNDO_FAILED_EFFECT = "This action cannot be undone.";
11202
+ var ReviewDeckIdempotencyError = class extends Error {
11203
+ name = "ReviewDeckIdempotencyError";
11204
+ constructor(message = "Idempotency key was reused with a different review request.") {
11205
+ super(message);
11206
+ }
11207
+ };
11208
+ var ReviewDeckInputError = class extends Error {
11209
+ name = "ReviewDeckInputError";
11210
+ constructor(message) {
11211
+ super(message);
11212
+ }
11213
+ };
11214
+ var LEDGER_ACTION = {
11215
+ keep: "approve",
11216
+ not_true: "dismiss",
11217
+ undo: "undo"
11218
+ };
11219
+ var EVENT_TYPE = {
11220
+ keep: "promoted",
11221
+ not_true: "rejected",
11222
+ undo: "restored"
11223
+ };
11224
+ function sha256Hex(value) {
11225
+ return createHash7("sha256").update(value, "utf8").digest("hex");
11226
+ }
11227
+ function computeReceiptId(namespace, principalDigest, idempotencyKey) {
11228
+ return `rcp1:${sha256Hex(`${namespace}\0${principalDigest}\0${idempotencyKey}`)}`;
11229
+ }
11230
+ function computeRequestFingerprint(parts) {
11231
+ return `rfp1:${sha256Hex(parts.join("\0"))}`;
11232
+ }
11233
+ function actionFingerprint(ctx, itemId, action, expectedRevision, correctionText) {
11234
+ const parts = [ctx.principalDigest, ctx.namespace, itemId, action, expectedRevision];
11235
+ if (correctionText !== void 0) parts.push(correctionText);
11236
+ return computeRequestFingerprint(parts);
11237
+ }
11238
+ function isNonEmptyString(value) {
11239
+ return typeof value === "string" && value.length > 0;
11240
+ }
11241
+ function isReceiptAction(value) {
11242
+ return value === "approve" || value === "dismiss" || value === "undo";
11243
+ }
11244
+ function parseReviewLifecycleReceipt(value) {
11245
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return null;
11246
+ const rec = value;
11247
+ if (rec.schemaVersion !== 1) return null;
11248
+ if (!isNonEmptyString(rec.receiptId)) return null;
11249
+ if (!isNonEmptyString(rec.requestFingerprint)) return null;
11250
+ if (!isNonEmptyString(rec.principalDigest)) return null;
11251
+ if (!isNonEmptyString(rec.itemId)) return null;
11252
+ if (!isReceiptAction(rec.action)) return null;
11253
+ if (typeof rec.beforeRevision !== "string") return null;
11254
+ if (typeof rec.afterRevision !== "string") return null;
11255
+ if (!isNonEmptyString(rec.sourcePath) || path14.isAbsolute(rec.sourcePath)) return null;
11256
+ if (rec.revisionArtifact !== void 0 && typeof rec.revisionArtifact !== "string") return null;
11257
+ if (rec.undoOfReceiptId !== void 0 && typeof rec.undoOfReceiptId !== "string") return null;
11258
+ const parsed = {
11259
+ schemaVersion: 1,
11260
+ receiptId: rec.receiptId,
11261
+ requestFingerprint: rec.requestFingerprint,
11262
+ principalDigest: rec.principalDigest,
11263
+ itemId: rec.itemId,
11264
+ action: rec.action,
11265
+ beforeRevision: rec.beforeRevision,
11266
+ afterRevision: rec.afterRevision,
11267
+ sourcePath: rec.sourcePath
11268
+ };
11269
+ if (typeof rec.revisionArtifact === "string") parsed.revisionArtifact = rec.revisionArtifact;
11270
+ if (typeof rec.undoOfReceiptId === "string") parsed.undoOfReceiptId = rec.undoOfReceiptId;
11271
+ return parsed;
11272
+ }
11273
+ function asStoredEvent(value) {
11274
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return null;
11275
+ return value;
11276
+ }
11277
+ function findStoredReceipt(events, receiptId) {
11278
+ for (const raw of events) {
11279
+ const event = asStoredEvent(raw);
11280
+ if (!event) continue;
11281
+ const receipt = parseReviewLifecycleReceipt(event.reviewReceipt);
11282
+ if (receipt && receipt.receiptId === receiptId) return { event, receipt };
11283
+ }
11284
+ return null;
11285
+ }
11286
+ function resolveInside(memoryDir, rel) {
11287
+ if (!rel || path14.isAbsolute(rel)) return null;
11288
+ const root = path14.resolve(memoryDir);
11289
+ const abs = path14.resolve(root, rel.split("/").join(path14.sep));
11290
+ const next = path14.relative(root, abs);
11291
+ if (next.startsWith("..") || path14.isAbsolute(next)) return null;
11292
+ return abs;
11293
+ }
11294
+ function currentRevision(absPath) {
11295
+ try {
11296
+ return computeReviewItemRevision(fs3.readFileSync(absPath, "utf8"));
11297
+ } catch {
11298
+ return "";
11299
+ }
11300
+ }
11301
+ function publicReceipt(input) {
11302
+ return {
11303
+ schemaVersion: 1,
11304
+ receiptId: input.receiptId,
11305
+ itemId: input.itemId,
11306
+ action: input.action,
11307
+ outcome: input.outcome,
11308
+ effect: input.effect,
11309
+ undoAvailable: input.undoAvailable,
11310
+ ...input.appliedRevision !== void 0 ? { appliedRevision: input.appliedRevision } : {},
11311
+ ...input.correctionPlanId !== void 0 ? { correctionPlanId: input.correctionPlanId } : {},
11312
+ ...input.correctionPreview !== void 0 ? { correctionPreview: input.correctionPreview } : {}
11313
+ };
11314
+ }
11315
+ async function snapshotForUndo(filePath, memoryDir) {
11316
+ try {
11317
+ const content = fs3.readFileSync(filePath, "utf8");
11318
+ const version = await createVersion(
11319
+ filePath,
11320
+ content,
11321
+ "manual",
11322
+ DECK_VERSIONING,
11323
+ void 0,
11324
+ void 0,
11325
+ memoryDir
11326
+ );
11327
+ return version.versionId;
11328
+ } catch {
11329
+ return void 0;
11330
+ }
11331
+ }
11332
+ async function artifactReadable(filePath, versionId, memoryDir) {
11333
+ try {
11334
+ await getVersion(filePath, versionId, DECK_VERSIONING, memoryDir);
11335
+ return true;
11336
+ } catch {
11337
+ return false;
11338
+ }
11339
+ }
11340
+ function undoTargetRevision(receipt, createdRel) {
11341
+ const created = createdRel && createdRel !== receipt.sourcePath ? createdRel : void 0;
11342
+ if (receipt.action === "approve" && created) return created;
11343
+ return receipt.sourcePath;
11344
+ }
11345
+ async function honestUndoAvailable(ctx, receipt, createdRel) {
11346
+ if (!receipt.revisionArtifact || receipt.action === "undo") return false;
11347
+ const sourceAbs = resolveInside(ctx.memoryDir, receipt.sourcePath);
11348
+ if (!sourceAbs) return false;
11349
+ if (!await artifactReadable(sourceAbs, receipt.revisionArtifact, ctx.memoryDir)) return false;
11350
+ const targetRel = undoTargetRevision(receipt, createdRel);
11351
+ const targetAbs = resolveInside(ctx.memoryDir, targetRel);
11352
+ if (!targetAbs) return false;
11353
+ return currentRevision(targetAbs) === receipt.afterRevision;
11354
+ }
11355
+ async function replayReceipt(ctx, hit, action) {
11356
+ const stored = hit.event.reviewDeckReceipt;
11357
+ const undoAvailable = await honestUndoAvailable(ctx, hit.receipt, hit.event.reviewCreatedPath);
11358
+ if (stored && stored.schemaVersion === 1 && stored.receiptId === hit.receipt.receiptId) {
11359
+ return {
11360
+ ...stored,
11361
+ undoAvailable,
11362
+ appliedRevision: stored.appliedRevision ?? hit.receipt.afterRevision
11363
+ };
11364
+ }
11365
+ return publicReceipt({
11366
+ receiptId: hit.receipt.receiptId,
11367
+ itemId: hit.receipt.itemId,
11368
+ action,
11369
+ outcome: "applied",
11370
+ effect: action === "keep" ? KEEP_EFFECT : action === "not_true" ? NOT_TRUE_EFFECT : UNDO_EFFECT,
11371
+ undoAvailable,
11372
+ appliedRevision: hit.receipt.afterRevision
11373
+ });
11374
+ }
11375
+ function applyKeepOrNotTrueSync(input) {
11376
+ let current;
11377
+ try {
11378
+ current = fs3.readFileSync(input.filePath, "utf8");
11379
+ } catch {
11380
+ return { kind: "failed" };
11381
+ }
11382
+ const currentRev = computeReviewItemRevision(current);
11383
+ if (currentRev !== input.expectedRevision) {
11384
+ return { kind: "conflict", current: currentRev };
11385
+ }
11386
+ const result = performReview(
11387
+ input.memoryDir,
11388
+ input.itemId,
11389
+ input.action === "keep" ? "approve" : "dismiss",
11390
+ { onApproveBlockedMemory: input.onApproveBlockedMemory }
11391
+ );
11392
+ if (result.message === "Item not found" || result.message === "Could not parse frontmatter") {
11393
+ return { kind: "failed" };
11394
+ }
11395
+ if (result.updatedPath && fs3.existsSync(result.updatedPath)) {
11396
+ return {
11397
+ kind: "applied",
11398
+ afterRevision: computeReviewItemRevision(fs3.readFileSync(result.updatedPath, "utf8")),
11399
+ createdAbs: result.updatedPath
11400
+ };
11401
+ }
11402
+ return { kind: "applied", afterRevision: "" };
11403
+ }
11404
+ async function appendAppliedEvent(ctx, input) {
11405
+ const event = {
11406
+ eventId: `mle-${randomUUID()}`,
11407
+ memoryId: input.itemId,
11408
+ eventType: EVENT_TYPE[input.action],
11409
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
11410
+ actor: ACTOR,
11411
+ ruleVersion: RULE_VERSION,
11412
+ reviewReceipt: input.receipt,
11413
+ reviewNamespace: ctx.namespace,
11414
+ reviewDeckReceipt: input.publicReceipt,
11415
+ before: { path: input.receipt.sourcePath },
11416
+ ...input.createdRel ? { after: { path: input.createdRel }, reviewCreatedPath: input.createdRel } : {},
11417
+ ...input.undoOfReceiptId ? { relatedMemoryIds: [input.itemId] } : {}
11418
+ };
11419
+ await ctx.appendLifecycleEvents([event]);
11420
+ }
11421
+ async function executeReviewDeckAction(ctx, req) {
11422
+ throwIfAborted(ctx.signal);
11423
+ if (req.schemaVersion !== 1) throw new ReviewDeckInputError("schemaVersion must be 1");
11424
+ if (!isNonEmptyString(req.itemId)) throw new ReviewDeckInputError("itemId is required");
11425
+ if (!isNonEmptyString(req.revision)) throw new ReviewDeckInputError("revision is required");
11426
+ if (!isNonEmptyString(req.idempotencyKey)) throw new ReviewDeckInputError("idempotencyKey is required");
11427
+ const receiptId = computeReceiptId(ctx.namespace, ctx.principalDigest, req.idempotencyKey);
11428
+ if (req.action === "prepare_fix") {
11429
+ const correctionText = req.correctionText;
11430
+ if (typeof correctionText !== "string" || correctionText.trim() === "") {
11431
+ throw new ReviewDeckInputError("correctionText is required");
11432
+ }
11433
+ if (!ctx.planCorrection) {
11434
+ return publicReceipt({
11435
+ receiptId,
11436
+ itemId: req.itemId,
11437
+ action: "prepare_fix",
11438
+ outcome: "failed",
11439
+ effect: PLAN_FAILED_EFFECT,
11440
+ undoAvailable: false
11441
+ });
11442
+ }
11443
+ const planned = await ctx.planCorrection({ itemId: req.itemId, correctionText });
11444
+ if (!planned.planId) {
11445
+ return publicReceipt({
11446
+ receiptId,
11447
+ itemId: req.itemId,
11448
+ action: "prepare_fix",
11449
+ outcome: "failed",
11450
+ effect: planned.message?.trim() || PLAN_FAILED_EFFECT,
11451
+ undoAvailable: false
11452
+ });
11453
+ }
11454
+ return publicReceipt({
11455
+ receiptId,
11456
+ itemId: req.itemId,
11457
+ action: "prepare_fix",
11458
+ outcome: "planned",
11459
+ effect: PLANNED_EFFECT,
11460
+ undoAvailable: false,
11461
+ correctionPlanId: planned.planId,
11462
+ correctionPreview: planned.preview
11463
+ });
11464
+ }
11465
+ if (req.action !== "keep" && req.action !== "not_true") {
11466
+ throw new ReviewDeckInputError("unsupported review deck action");
11467
+ }
11468
+ const fingerprint = actionFingerprint(ctx, req.itemId, req.action, req.revision);
11469
+ const existing = findStoredReceipt(await ctx.readLifecycleEvents(), receiptId);
11470
+ if (existing) {
11471
+ if (existing.receipt.requestFingerprint !== fingerprint) throw new ReviewDeckIdempotencyError();
11472
+ return replayReceipt(ctx, existing, req.action);
11473
+ }
11474
+ const row = readReviewDeckRow({ memoryDir: ctx.memoryDir, itemId: req.itemId });
11475
+ if (!row) {
11476
+ return publicReceipt({
11477
+ receiptId,
11478
+ itemId: req.itemId,
11479
+ action: req.action,
11480
+ outcome: "failed",
11481
+ effect: MISSING_EFFECT,
11482
+ undoAvailable: false
11483
+ });
11484
+ }
11485
+ throwIfAborted(ctx.signal);
11486
+ const revisionArtifact = await snapshotForUndo(row.filePath, ctx.memoryDir);
11487
+ throwIfAborted(ctx.signal);
11488
+ const applied = applyKeepOrNotTrueSync({
11489
+ memoryDir: ctx.memoryDir,
11490
+ itemId: req.itemId,
11491
+ filePath: row.filePath,
11492
+ expectedRevision: req.revision,
11493
+ action: req.action,
11494
+ onApproveBlockedMemory: ctx.onApproveBlockedMemory
11495
+ });
11496
+ if (applied.kind === "conflict") {
11497
+ return publicReceipt({
11498
+ receiptId,
11499
+ itemId: req.itemId,
11500
+ action: req.action,
11501
+ outcome: "conflict",
11502
+ effect: CONFLICT_EFFECT,
11503
+ undoAvailable: false,
11504
+ appliedRevision: applied.current
11505
+ });
11506
+ }
11507
+ if (applied.kind === "failed") {
11508
+ return publicReceipt({
11509
+ receiptId,
11510
+ itemId: req.itemId,
11511
+ action: req.action,
11512
+ outcome: "failed",
11513
+ effect: MISSING_EFFECT,
11514
+ undoAvailable: false
11515
+ });
11516
+ }
11517
+ const sourcePath = toMemoryPathRel(ctx.memoryDir, row.filePath);
11518
+ const createdRel = applied.createdAbs ? toMemoryPathRel(ctx.memoryDir, applied.createdAbs) : void 0;
11519
+ const ledgerReceipt = {
11520
+ schemaVersion: 1,
11521
+ receiptId,
11522
+ requestFingerprint: fingerprint,
11523
+ principalDigest: ctx.principalDigest,
11524
+ itemId: req.itemId,
11525
+ action: LEDGER_ACTION[req.action],
11526
+ beforeRevision: req.revision,
11527
+ afterRevision: applied.afterRevision,
11528
+ sourcePath,
11529
+ ...revisionArtifact ? { revisionArtifact } : {}
11530
+ };
11531
+ const undoAvailable = Boolean(revisionArtifact);
11532
+ const published = publicReceipt({
11533
+ receiptId,
11534
+ itemId: req.itemId,
11535
+ action: req.action,
11536
+ outcome: "applied",
11537
+ effect: req.action === "keep" ? KEEP_EFFECT : NOT_TRUE_EFFECT,
11538
+ undoAvailable,
11539
+ appliedRevision: applied.afterRevision
11540
+ });
11541
+ await appendAppliedEvent(ctx, {
11542
+ itemId: req.itemId,
11543
+ action: req.action,
11544
+ receipt: ledgerReceipt,
11545
+ createdRel,
11546
+ publicReceipt: published
11547
+ });
11548
+ return published;
11549
+ }
11550
+ async function executeReviewDeckUndo(ctx, req) {
11551
+ throwIfAborted(ctx.signal);
11552
+ if (req.schemaVersion !== 1) throw new ReviewDeckInputError("schemaVersion must be 1");
11553
+ if (!isNonEmptyString(req.receiptId)) throw new ReviewDeckInputError("receiptId is required");
11554
+ if (typeof req.expectedRevision !== "string") throw new ReviewDeckInputError("expectedRevision is required");
11555
+ if (!isNonEmptyString(req.idempotencyKey)) throw new ReviewDeckInputError("idempotencyKey is required");
11556
+ const undoReceiptId = computeReceiptId(ctx.namespace, ctx.principalDigest, req.idempotencyKey);
11557
+ const events = await ctx.readLifecycleEvents();
11558
+ const original = findStoredReceipt(events, req.receiptId);
11559
+ if (!original) {
11560
+ return publicReceipt({
11561
+ receiptId: undoReceiptId,
11562
+ itemId: "",
11563
+ action: "undo",
11564
+ outcome: "failed",
11565
+ effect: UNDO_FAILED_EFFECT,
11566
+ undoAvailable: false
11567
+ });
11568
+ }
11569
+ const scopeOk = original.receipt.principalDigest === ctx.principalDigest && original.event.reviewNamespace === ctx.namespace;
11570
+ if (!scopeOk) {
11571
+ return publicReceipt({
11572
+ receiptId: undoReceiptId,
11573
+ itemId: "",
11574
+ action: "undo",
11575
+ outcome: "failed",
11576
+ effect: UNDO_FAILED_EFFECT,
11577
+ undoAvailable: false
11578
+ });
11579
+ }
11580
+ const fingerprint = actionFingerprint(
11581
+ ctx,
11582
+ original.receipt.itemId,
11583
+ "undo",
11584
+ req.expectedRevision
11585
+ );
11586
+ const priorUndo = findStoredReceipt(events, undoReceiptId);
11587
+ if (priorUndo) {
11588
+ if (priorUndo.receipt.requestFingerprint !== fingerprint) throw new ReviewDeckIdempotencyError();
11589
+ return replayReceipt(ctx, priorUndo, "undo");
11590
+ }
11591
+ if (req.expectedRevision !== original.receipt.afterRevision) {
11592
+ return publicReceipt({
11593
+ receiptId: undoReceiptId,
11594
+ itemId: original.receipt.itemId,
11595
+ action: "undo",
11596
+ outcome: "conflict",
11597
+ effect: UNDO_CONFLICT_EFFECT,
11598
+ undoAvailable: false
11599
+ });
11600
+ }
11601
+ const createdRel = original.event.reviewCreatedPath;
11602
+ const targetRel = undoTargetRevision(original.receipt, createdRel);
11603
+ const targetAbs = resolveInside(ctx.memoryDir, targetRel);
11604
+ const sourceAbs = resolveInside(ctx.memoryDir, original.receipt.sourcePath);
11605
+ if (!targetAbs || !sourceAbs) {
11606
+ return publicReceipt({
11607
+ receiptId: undoReceiptId,
11608
+ itemId: original.receipt.itemId,
11609
+ action: "undo",
11610
+ outcome: "failed",
11611
+ effect: UNDO_FAILED_EFFECT,
11612
+ undoAvailable: false
11613
+ });
11614
+ }
11615
+ if (currentRevision(targetAbs) !== original.receipt.afterRevision) {
11616
+ return publicReceipt({
11617
+ receiptId: undoReceiptId,
11618
+ itemId: original.receipt.itemId,
11619
+ action: "undo",
11620
+ outcome: "conflict",
11621
+ effect: UNDO_CONFLICT_EFFECT,
11622
+ undoAvailable: false,
11623
+ appliedRevision: currentRevision(targetAbs)
11624
+ });
11625
+ }
11626
+ if (!original.receipt.revisionArtifact) {
11627
+ return publicReceipt({
11628
+ receiptId: undoReceiptId,
11629
+ itemId: original.receipt.itemId,
11630
+ action: "undo",
11631
+ outcome: "failed",
11632
+ effect: UNDO_FAILED_EFFECT,
11633
+ undoAvailable: false
11634
+ });
11635
+ }
11636
+ throwIfAborted(ctx.signal);
11637
+ try {
11638
+ await revertToVersion(
11639
+ sourceAbs,
11640
+ original.receipt.revisionArtifact,
11641
+ DECK_VERSIONING,
11642
+ void 0,
11643
+ ctx.memoryDir
11644
+ );
11645
+ } catch {
11646
+ return publicReceipt({
11647
+ receiptId: undoReceiptId,
11648
+ itemId: original.receipt.itemId,
11649
+ action: "undo",
11650
+ outcome: "failed",
11651
+ effect: UNDO_FAILED_EFFECT,
11652
+ undoAvailable: false
11653
+ });
11654
+ }
11655
+ if (createdRel && createdRel !== original.receipt.sourcePath) {
11656
+ const createdAbs = resolveInside(ctx.memoryDir, createdRel);
11657
+ if (createdAbs && createdAbs !== sourceAbs && fs3.existsSync(createdAbs)) {
11658
+ fs3.unlinkSync(createdAbs);
11659
+ }
11660
+ }
11661
+ bumpMemoryCorpusVersionForDir(ctx.memoryDir);
11662
+ const afterRevision = currentRevision(sourceAbs);
11663
+ const ledgerReceipt = {
11664
+ schemaVersion: 1,
11665
+ receiptId: undoReceiptId,
11666
+ requestFingerprint: fingerprint,
11667
+ principalDigest: ctx.principalDigest,
11668
+ itemId: original.receipt.itemId,
11669
+ action: "undo",
11670
+ beforeRevision: original.receipt.afterRevision,
11671
+ afterRevision,
11672
+ sourcePath: original.receipt.sourcePath,
11673
+ undoOfReceiptId: original.receipt.receiptId
11674
+ };
11675
+ const published = publicReceipt({
11676
+ receiptId: undoReceiptId,
11677
+ itemId: original.receipt.itemId,
11678
+ action: "undo",
11679
+ outcome: "applied",
11680
+ effect: UNDO_EFFECT,
11681
+ undoAvailable: false,
11682
+ appliedRevision: afterRevision
11683
+ });
11684
+ await appendAppliedEvent(ctx, {
11685
+ itemId: original.receipt.itemId,
11686
+ action: "undo",
11687
+ receipt: ledgerReceipt,
11688
+ publicReceipt: published,
11689
+ undoOfReceiptId: original.receipt.receiptId
11690
+ });
11691
+ return published;
11692
+ }
11693
+
11694
+ // src/review/review-deck-surface.ts
11695
+ function digest(value) {
11696
+ return createHash8("sha256").update(value).digest("hex");
11697
+ }
11698
+ var ReviewDeckSurface = class {
11699
+ constructor(deps) {
11700
+ this.deps = deps;
11701
+ }
11702
+ deps;
11703
+ async list(opts) {
11704
+ const namespace = this.deps.resolveReadableNamespace(opts.namespace, opts.principal);
11705
+ const storage = await this.deps.orchestrator.getStorage(namespace);
11706
+ const snapshot = readReviewDeckSnapshot({ memoryDir: storage.dir, namespace });
11707
+ try {
11708
+ return buildReviewDeckPage(snapshot.rows, {
11709
+ scope: {
11710
+ principalDigest: digest(opts.principal ?? ""),
11711
+ namespace,
11712
+ filterDigest: digest(""),
11713
+ corpusVersion: snapshot.corpusVersion
11714
+ },
11715
+ cursor: opts.cursor,
11716
+ limit: opts.limit
11717
+ });
11718
+ } catch (error) {
11719
+ if (error instanceof ReviewDeckCursorError) {
11720
+ throw new EngramAccessInputError(error.message);
11721
+ }
11722
+ throw error;
11723
+ }
11724
+ }
11725
+ async action(req, opts) {
11726
+ return executeReviewDeckAction(await this.mutationContext(opts), req);
11727
+ }
11728
+ async undo(req, opts) {
11729
+ return executeReviewDeckUndo(await this.mutationContext(opts), req);
11730
+ }
11731
+ async mutationContext(opts) {
11732
+ const namespace = this.deps.writableNamespaceFor(opts.namespace, void 0, opts.principal);
11733
+ this.deps.resolveReadableNamespace(namespace, opts.principal);
11734
+ const storage = await this.deps.orchestrator.getStorage(namespace);
11735
+ return {
11736
+ memoryDir: storage.dir,
11737
+ namespace,
11738
+ principalDigest: digest(opts.principal ?? ""),
11739
+ appendLifecycleEvents: async (events) => {
11740
+ await storage.appendMemoryLifecycleEvents(events);
11741
+ },
11742
+ readLifecycleEvents: (memoryId) => memoryId ? storage.getMemoryTimeline(memoryId) : storage.readMemoryLifecycleEvents(),
11743
+ onApproveBlockedMemory: (tombstoneId) => {
11744
+ void storage.revokeTombstone(tombstoneId, "user_correction").catch(() => void 0);
11745
+ },
11746
+ planCorrection: async ({ itemId, correctionText }) => {
11747
+ const plan = await this.deps.correctionPlan(
11748
+ {
11749
+ text: correctionText,
11750
+ targetIds: [itemId],
11751
+ principal: opts.principal,
11752
+ namespace
11753
+ },
11754
+ opts.signal ? { abortSignal: opts.signal } : void 0
11755
+ );
11756
+ return { planId: plan.planId, preview: plan };
11757
+ },
11758
+ signal: opts.signal
11759
+ };
11760
+ }
11761
+ };
11762
+
11763
+ // src/support-passport/card-service.ts
11764
+ import { randomUUID as randomUUID3 } from "crypto";
11765
+
11766
+ // src/support-passport/errors.ts
11767
+ var SupportPassportError = class extends Error {
11768
+ code;
11769
+ status;
11770
+ constructor(code, message, status) {
11771
+ super(message);
11772
+ this.name = "SupportPassportError";
11773
+ this.code = code;
11774
+ this.status = status;
11775
+ }
11776
+ };
11777
+
11778
+ // src/support-passport/card-state.ts
11779
+ function invalidInput() {
11780
+ return new SupportPassportError("invalid_input", "The support card request is invalid.", 400);
11781
+ }
11782
+ function isStorageConflict(error) {
11783
+ return error instanceof SupportPassportError && error.code === "storage_conflict";
11784
+ }
11785
+ function once(callback) {
11786
+ let called = false;
11787
+ return () => {
11788
+ if (called) return;
11789
+ called = true;
11790
+ callback?.();
11791
+ };
11792
+ }
11793
+ function validateOwnerScope(owner, principal) {
11794
+ const requestedPrincipal = SupportPassportListCardsInputSchema.safeParse({ principal });
11795
+ const namespace = SupportPassportNamespaceSchema.safeParse(owner.namespace);
11796
+ const ownerPrincipal = SupportPassportListCardsInputSchema.safeParse({ principal: owner.principal });
11797
+ if (!requestedPrincipal.success || !namespace.success || !ownerPrincipal.success || ownerPrincipal.data.principal !== requestedPrincipal.data.principal) {
11798
+ throw new SupportPassportError("card_data_invalid", "The support passport owner scope is invalid.", 500);
11799
+ }
11800
+ return { ...owner, principal: ownerPrincipal.data.principal, namespace: namespace.data };
11801
+ }
11802
+ var MAX_OWNER_VISIBLE_CARDS = 100;
11803
+ var OWNER_VISIBLE_STATUSES = /* @__PURE__ */ new Set(["pending_review", "active"]);
11804
+ function revisionFor(card, status, updatedAt) {
11805
+ return computeSupportPassportCardRevision({
11806
+ cardId: card.cardId,
11807
+ title: card.title,
11808
+ statement: card.statement,
11809
+ category: card.category,
11810
+ status,
11811
+ updatedAt,
11812
+ reviewBy: card.reviewBy
11813
+ });
11814
+ }
11815
+ function projectRequiredCard(memory, namespace, principal) {
11816
+ const card = projectSupportPassportCard(memory);
11817
+ if (!card) throw new SupportPassportError("card_data_invalid", "The support card data is invalid.", 500);
11818
+ if (card.namespace !== namespace || card.owner !== computeSupportPassportOwnerKey(principal)) {
11819
+ throw new SupportPassportError("card_not_found", "The support card was not found.", 404);
11820
+ }
11821
+ return card;
11822
+ }
11823
+ function projectOwnedCard(memory, namespace, principal) {
11824
+ const card = projectSupportPassportCard(memory);
11825
+ return card?.namespace === namespace && card.owner === computeSupportPassportOwnerKey(principal) ? card : null;
11826
+ }
11827
+ function ownsMemory(memory, namespace, principal) {
11828
+ const attributes = memory.frontmatter.structuredAttributes;
11829
+ return attributes !== void 0 && decodeSupportPassportNamespaceAttributes(attributes) === namespace && attributes[SUPPORT_PASSPORT_ATTRIBUTE_KEYS.owner] === computeSupportPassportOwnerKey(principal);
11830
+ }
11831
+ function requireRevision(card, expectedRevision) {
11832
+ if (card.card.revision !== expectedRevision) {
11833
+ throw new SupportPassportError("revision_conflict", "The support card changed after it was loaded.", 409);
11834
+ }
11835
+ }
11836
+ function requireStatus(card, status) {
11837
+ if (card.card.status !== status) {
11838
+ throw new SupportPassportError("invalid_card_status", `The support card must have status ${status}.`, 409);
11839
+ }
11840
+ }
11841
+ function ownerVisibleCards(storedCards) {
11842
+ const visibleCards = storedCards.filter(
11843
+ (item) => OWNER_VISIBLE_STATUSES.has(item.card.status) && !item.draftReplacementPrepared
11844
+ );
11845
+ if (visibleCards.length <= MAX_OWNER_VISIBLE_CARDS) return visibleCards;
11846
+ const cardsWithPendingReplacements = new Set(
11847
+ visibleCards.filter((item) => item.card.status === "pending_review").map((item) => item.memory.frontmatter.supersedes).filter((cardId) => typeof cardId === "string")
11848
+ );
11849
+ return visibleCards.filter(
11850
+ (item) => item.card.status !== "active" || !cardsWithPendingReplacements.has(item.card.cardId)
11851
+ );
11852
+ }
11853
+ function ownerListCards(storedCards) {
11854
+ const visibleCards = ownerVisibleCards(storedCards);
11855
+ const byId = new Map(storedCards.map((item) => [item.card.cardId, item]));
11856
+ const activeReplacementPredecessors = activeSupportPassportReplacementPredecessorIds(visibleCards);
11857
+ const replacedDraftIds = new Set(
11858
+ visibleCards.filter(
10088
11859
  (item) => item.card.status === "pending_review" && item.replacesDraftId !== void 0 && byId.get(item.replacesDraftId)?.card.status === "pending_review"
10089
11860
  ).map((item) => item.replacesDraftId)
10090
11861
  );
@@ -10180,14 +11951,14 @@ async function completeSupportPassportReplacementPrior(input) {
10180
11951
  }
10181
11952
 
10182
11953
  // src/support-passport/generated-batch.ts
10183
- import path12 from "path";
11954
+ import path16 from "path";
10184
11955
  import { z as z2 } from "zod";
10185
11956
 
10186
11957
  // src/support-passport/private-file.ts
10187
- import { randomUUID } from "crypto";
11958
+ import { randomUUID as randomUUID2 } from "crypto";
10188
11959
  import { constants as fsConstants } from "fs";
10189
11960
  import { lstat as lstat3, mkdir as mkdir3, open, rename as rename2, rm as rm2, stat as stat2 } from "fs/promises";
10190
- import path11 from "path";
11961
+ import path15 from "path";
10191
11962
  var UNSUPPORTED_DIRECTORY_SYNC_ERRORS = /* @__PURE__ */ new Set(["EINVAL", "ENOSYS", "ENOTSUP", "EOPNOTSUPP"]);
10192
11963
  var NON_WRITABLE_ANCESTOR_SYNC_ERRORS = /* @__PURE__ */ new Set(["EROFS", "EPERM", "EACCES"]);
10193
11964
  function assertStableDirectory(before, opened, after, errorMessage) {
@@ -10213,8 +11984,8 @@ function openFlags(...flags) {
10213
11984
  return combined;
10214
11985
  }
10215
11986
  function assertContainedPath(trustedRoot, directory, errorMessage) {
10216
- const relative2 = path11.relative(path11.resolve(trustedRoot), path11.resolve(directory));
10217
- if (relative2 === ".." || relative2.startsWith(`..${path11.sep}`) || path11.isAbsolute(relative2)) {
11987
+ const relative2 = path15.relative(path15.resolve(trustedRoot), path15.resolve(directory));
11988
+ if (relative2 === ".." || relative2.startsWith(`..${path15.sep}`) || path15.isAbsolute(relative2)) {
10218
11989
  throw new Error(errorMessage);
10219
11990
  }
10220
11991
  }
@@ -10247,7 +12018,7 @@ async function syncDirectoryHandle(handle) {
10247
12018
  }
10248
12019
  async function resolvePrivateDirectoryPath(directory, handle, opened, errorMessage, platform = process.platform) {
10249
12020
  const descriptorRoot = requirePrivateFileDescriptorRoot(platform, errorMessage);
10250
- const pinnedPath = path11.join(descriptorRoot, String(handle.fd));
12021
+ const pinnedPath = path15.join(descriptorRoot, String(handle.fd));
10251
12022
  const metadata = await stat2(pinnedPath);
10252
12023
  if (!metadata.isDirectory() || metadata.dev !== opened.dev || metadata.ino !== opened.ino) {
10253
12024
  throw new Error(errorMessage);
@@ -10263,12 +12034,12 @@ function requirePrivateFileDescriptorRoot(platform, errorMessage) {
10263
12034
  throw new Error(errorMessage);
10264
12035
  }
10265
12036
  async function openStableDirectoryFromRoot(trustedRoot, directory, errorMessage, platform = process.platform) {
10266
- const root = path11.resolve(trustedRoot);
10267
- const target = path11.resolve(directory);
12037
+ const root = path15.resolve(trustedRoot);
12038
+ const target = path15.resolve(directory);
10268
12039
  assertContainedPath(root, target, errorMessage);
10269
12040
  requirePrivateFileDescriptorRoot(platform, errorMessage);
10270
- const relative2 = path11.relative(root, target);
10271
- const components = relative2 === "" ? [] : relative2.split(path11.sep);
12041
+ const relative2 = path15.relative(root, target);
12042
+ const components = relative2 === "" ? [] : relative2.split(path15.sep);
10272
12043
  const handles = [];
10273
12044
  let currentPath = root;
10274
12045
  try {
@@ -10276,10 +12047,10 @@ async function openStableDirectoryFromRoot(trustedRoot, directory, errorMessage,
10276
12047
  handles.push(current.handle);
10277
12048
  for (const component of components) {
10278
12049
  const pinnedParent = await resolvePrivateDirectoryPath(currentPath, current.handle, current.opened, errorMessage);
10279
- const child = await openDirectoryNoFollow(path11.join(pinnedParent, component), errorMessage);
12050
+ const child = await openDirectoryNoFollow(path15.join(pinnedParent, component), errorMessage);
10280
12051
  handles.push(child.handle);
10281
12052
  assertStableDirectory(current.before, current.opened, await lstat3(currentPath), errorMessage);
10282
- currentPath = path11.join(currentPath, component);
12053
+ currentPath = path15.join(currentPath, component);
10283
12054
  current = child;
10284
12055
  }
10285
12056
  assertStableDirectory(current.before, current.opened, await lstat3(target), errorMessage);
@@ -10300,12 +12071,12 @@ async function openStableDirectoryFromRoot(trustedRoot, directory, errorMessage,
10300
12071
  }
10301
12072
  }
10302
12073
  async function ensurePrivateDirectoryNoFollow(trustedRoot, directory, errorMessage, syncVerifiedParent = syncDirectoryHandle, hardenExistingChildren = true, platform = process.platform) {
10303
- const root = path11.resolve(trustedRoot);
10304
- const target = path11.resolve(directory);
12074
+ const root = path15.resolve(trustedRoot);
12075
+ const target = path15.resolve(directory);
10305
12076
  assertContainedPath(root, target, errorMessage);
10306
- const relative2 = path11.relative(root, target);
12077
+ const relative2 = path15.relative(root, target);
10307
12078
  requirePrivateFileDescriptorRoot(platform, errorMessage);
10308
- const components = relative2 === "" ? [] : relative2.split(path11.sep);
12079
+ const components = relative2 === "" ? [] : relative2.split(path15.sep);
10309
12080
  const handles = [];
10310
12081
  let currentPath = root;
10311
12082
  try {
@@ -10313,7 +12084,7 @@ async function ensurePrivateDirectoryNoFollow(trustedRoot, directory, errorMessa
10313
12084
  handles.push(current.handle);
10314
12085
  for (const component of components) {
10315
12086
  const pinnedParent = await resolvePrivateDirectoryPath(currentPath, current.handle, current.opened, errorMessage);
10316
- const childPath = path11.join(pinnedParent, component);
12087
+ const childPath = path15.join(pinnedParent, component);
10317
12088
  let created = false;
10318
12089
  try {
10319
12090
  await mkdir3(childPath, { mode: 448 });
@@ -10328,7 +12099,7 @@ async function ensurePrivateDirectoryNoFollow(trustedRoot, directory, errorMessa
10328
12099
  await child.handle.chmod(448);
10329
12100
  }
10330
12101
  assertStableDirectory(current.before, current.opened, await lstat3(currentPath), errorMessage);
10331
- currentPath = path11.join(currentPath, component);
12102
+ currentPath = path15.join(currentPath, component);
10332
12103
  current = child;
10333
12104
  }
10334
12105
  assertStableDirectory(current.before, current.opened, await lstat3(target), errorMessage);
@@ -10337,8 +12108,8 @@ async function ensurePrivateDirectoryNoFollow(trustedRoot, directory, errorMessa
10337
12108
  }
10338
12109
  }
10339
12110
  async function ensurePrivateDirectoryTreeNoFollow(directory, errorMessage, syncVerifiedParent = syncDirectoryHandle, platform = process.platform) {
10340
- const target = path11.resolve(directory);
10341
- const filesystemRoot = path11.parse(target).root;
12111
+ const target = path15.resolve(directory);
12112
+ const filesystemRoot = path15.parse(target).root;
10342
12113
  const rootMetadata = await stat2(filesystemRoot);
10343
12114
  await ensurePrivateDirectoryNoFollow(
10344
12115
  filesystemRoot,
@@ -10373,15 +12144,15 @@ async function withPrivateDirectoryNoFollow(trustedRoot, directory, errorMessage
10373
12144
  }
10374
12145
  }
10375
12146
  async function readPrivateFileNoFollow(directory, filePath, errorMessage, trustedRoot = directory, platform = process.platform) {
10376
- if (path11.dirname(filePath) !== path11.resolve(directory)) throw new Error(errorMessage);
10377
- const targetName = path11.basename(filePath);
12147
+ if (path15.dirname(filePath) !== path15.resolve(directory)) throw new Error(errorMessage);
12148
+ const targetName = path15.basename(filePath);
10378
12149
  let directoryHandles = [];
10379
12150
  let fileHandle;
10380
12151
  try {
10381
12152
  const stableDirectory = await openStableDirectoryFromRoot(trustedRoot, directory, errorMessage, platform);
10382
12153
  directoryHandles = stableDirectory.handles;
10383
12154
  const pinnedDirectory = stableDirectory.pinnedDirectory;
10384
- const targetPath = path11.join(pinnedDirectory, targetName);
12155
+ const targetPath = path15.join(pinnedDirectory, targetName);
10385
12156
  const before = await lstat3(targetPath);
10386
12157
  if (before.isSymbolicLink() || !before.isFile()) throw new Error(errorMessage);
10387
12158
  try {
@@ -10400,10 +12171,10 @@ async function readPrivateFileNoFollow(directory, filePath, errorMessage, truste
10400
12171
  }
10401
12172
  }
10402
12173
  async function appendPrivateFileAtPinnedDirectory(pinnedDirectory, targetName, content, errorMessage, directoryHandle, openFile) {
10403
- if (targetName.length === 0 || targetName === "." || targetName === ".." || path11.basename(targetName) !== targetName) {
12174
+ if (targetName.length === 0 || targetName === "." || targetName === ".." || path15.basename(targetName) !== targetName) {
10404
12175
  throw new Error(errorMessage);
10405
12176
  }
10406
- const targetPath = path11.join(pinnedDirectory, targetName);
12177
+ const targetPath = path15.join(pinnedDirectory, targetName);
10407
12178
  let fileHandle;
10408
12179
  try {
10409
12180
  try {
@@ -10439,8 +12210,8 @@ async function appendPrivateFileAtPinnedDirectory(pinnedDirectory, targetName, c
10439
12210
  }
10440
12211
  async function appendPrivateFileInPinnedDirectory(pinnedDirectory, fileName, content, errorMessage, platform = process.platform) {
10441
12212
  const descriptorRoot = requirePrivateFileDescriptorRoot(platform, errorMessage);
10442
- const resolvedDirectory = path11.resolve(pinnedDirectory);
10443
- const descriptor = path11.relative(descriptorRoot, resolvedDirectory);
12213
+ const resolvedDirectory = path15.resolve(pinnedDirectory);
12214
+ const descriptor = path15.relative(descriptorRoot, resolvedDirectory);
10444
12215
  if (!/^\d+$/.test(descriptor)) throw new Error(errorMessage);
10445
12216
  const before = await stat2(resolvedDirectory);
10446
12217
  if (!before.isDirectory()) throw new Error(errorMessage);
@@ -10456,9 +12227,9 @@ async function appendPrivateFileInPinnedDirectory(pinnedDirectory, fileName, con
10456
12227
  }
10457
12228
  }
10458
12229
  async function writePrivateFileAtomicallyNoFollow(directory, filePath, content, errorMessage, trustedRoot = directory, platform = process.platform, syncVerifiedDirectory = syncDirectoryHandle) {
10459
- if (path11.dirname(filePath) !== path11.resolve(directory)) throw new Error(errorMessage);
10460
- const targetName = path11.basename(filePath);
10461
- const tempName = `.${targetName}.${randomUUID()}.tmp`;
12230
+ if (path15.dirname(filePath) !== path15.resolve(directory)) throw new Error(errorMessage);
12231
+ const targetName = path15.basename(filePath);
12232
+ const tempName = `.${targetName}.${randomUUID2()}.tmp`;
10462
12233
  let tempPath;
10463
12234
  let directoryHandles = [];
10464
12235
  let fileHandle;
@@ -10466,8 +12237,8 @@ async function writePrivateFileAtomicallyNoFollow(directory, filePath, content,
10466
12237
  const stableDirectory = await openStableDirectoryFromRoot(trustedRoot, directory, errorMessage, platform);
10467
12238
  directoryHandles = stableDirectory.handles;
10468
12239
  const pinnedDirectory = stableDirectory.pinnedDirectory;
10469
- tempPath = path11.join(pinnedDirectory, tempName);
10470
- const targetPath = path11.join(pinnedDirectory, targetName);
12240
+ tempPath = path15.join(pinnedDirectory, tempName);
12241
+ const targetPath = path15.join(pinnedDirectory, targetName);
10471
12242
  try {
10472
12243
  fileHandle = await open(
10473
12244
  tempPath,
@@ -10504,7 +12275,7 @@ async function writePrivateFileAtomicallyNoFollow(directory, filePath, content,
10504
12275
  }
10505
12276
  async function removePrivateFilesNoFollow(directory, fileNames, errorMessage, trustedRoot = directory, platform = process.platform) {
10506
12277
  if (fileNames.some(
10507
- (fileName) => fileName.length === 0 || fileName === "." || fileName === ".." || path11.basename(fileName) !== fileName
12278
+ (fileName) => fileName.length === 0 || fileName === "." || fileName === ".." || path15.basename(fileName) !== fileName
10508
12279
  )) {
10509
12280
  throw new Error(errorMessage);
10510
12281
  }
@@ -10514,7 +12285,7 @@ async function removePrivateFilesNoFollow(directory, fileNames, errorMessage, tr
10514
12285
  directoryHandles = stableDirectory.handles;
10515
12286
  const pinnedDirectory = stableDirectory.pinnedDirectory;
10516
12287
  for (const fileName of fileNames) {
10517
- await rm2(path11.join(pinnedDirectory, fileName), { force: true });
12288
+ await rm2(path15.join(pinnedDirectory, fileName), { force: true });
10518
12289
  }
10519
12290
  assertStableDirectory(stableDirectory.before, stableDirectory.opened, await lstat3(directory), errorMessage);
10520
12291
  if (stableDirectory.handle) await syncDirectoryHandle(stableDirectory.handle);
@@ -10535,13 +12306,13 @@ var GeneratedBatchMarkerSchema = z2.object({
10535
12306
  }).strict();
10536
12307
  var BATCH_ERROR = "The generated draft batch state is not safe.";
10537
12308
  function batchDirectory(storage) {
10538
- return path12.join(storage.dir, "state", "support-passport", "generated-batches");
12309
+ return path16.join(storage.dir, "state", "support-passport", "generated-batches");
10539
12310
  }
10540
12311
  function batchFileName(batchId) {
10541
12312
  return `${BatchIdSchema.parse(batchId)}.json`;
10542
12313
  }
10543
12314
  function batchPath(storage, batchId) {
10544
- return path12.join(batchDirectory(storage), batchFileName(batchId));
12315
+ return path16.join(batchDirectory(storage), batchFileName(batchId));
10545
12316
  }
10546
12317
  function markerFor(context, batchId, size, complete) {
10547
12318
  return GeneratedBatchMarkerSchema.parse({
@@ -10965,19 +12736,19 @@ var SupportPassportAnswerModelInputSchema = z4.object({
10965
12736
  }).strict();
10966
12737
 
10967
12738
  // src/support-passport/owner-lock.ts
10968
- import { createHash as createHash6 } from "crypto";
10969
- import path13 from "path";
12739
+ import { createHash as createHash9 } from "crypto";
12740
+ import path17 from "path";
10970
12741
  var CARD_MUTATION_LOCK_STALE_MS = 6e4;
10971
12742
  var CARD_MUTATION_LOCK_MAX_WAIT_MS = 3e4;
10972
12743
  function computeSupportPassportOwnerLockKey(namespace, principal) {
10973
- return createHash6("sha256").update(JSON.stringify([namespace, principal])).digest("hex");
12744
+ return createHash9("sha256").update(JSON.stringify([namespace, principal])).digest("hex");
10974
12745
  }
10975
12746
  function supportPassportOwnerLockPath(storage, scope) {
10976
12747
  const ownerLockKey = scope.ownerKey ?? computeSupportPassportOwnerLockKey(scope.namespace, scope.principal);
10977
12748
  if (!/^[a-f0-9]{64}$/.test(ownerLockKey)) {
10978
12749
  throw new SupportPassportError("card_data_invalid", "The support passport owner scope is invalid.", 500);
10979
12750
  }
10980
- return path13.join(storage.dir, "state", `support-passport-cards-${ownerLockKey}.lock`);
12751
+ return path17.join(storage.dir, "state", `support-passport-cards-${ownerLockKey}.lock`);
10981
12752
  }
10982
12753
  async function withSupportPassportOwnerLock(storage, scope, task) {
10983
12754
  const lockPath = supportPassportOwnerLockPath(storage, scope);
@@ -11085,7 +12856,7 @@ var SupportPassportCardService = class {
11085
12856
  const onCommitted = once(input.onCommitted);
11086
12857
  return await withSupportPassportOwnerLock(storage, { namespace, principal }, async (lock) => {
11087
12858
  const batchContext = this.generatedBatchContext(storage, lock, principal, namespace, onCommitted);
11088
- const batchId = randomUUID2();
12859
+ const batchId = randomUUID3();
11089
12860
  const created = [];
11090
12861
  const createdIds = [];
11091
12862
  const createdRecords = [];
@@ -11873,9 +13644,9 @@ var SupportPassportCardService = class {
11873
13644
  };
11874
13645
 
11875
13646
  // src/support-passport/grant-store.ts
11876
- import { createHash as createHash7, randomBytes, randomUUID as randomUUID3, timingSafeEqual } from "crypto";
13647
+ import { createHash as createHash10, randomBytes, randomUUID as randomUUID4, timingSafeEqual } from "crypto";
11877
13648
  import { lstat as lstat4, open as open2, readdir as readdir4 } from "fs/promises";
11878
- import path14 from "path";
13649
+ import path18 from "path";
11879
13650
  var GRANT_LOCK_STALE_MS = 3e4;
11880
13651
  var GRANT_LOCK_WAIT_MS = 5e3;
11881
13652
  var GRANT_LOCK_HEARTBEAT_MS = 1e4;
@@ -11898,7 +13669,7 @@ var MalformedGrantStateError = class extends Error {
11898
13669
  }
11899
13670
  };
11900
13671
  function sha256(domain, value) {
11901
- return createHash7("sha256").update(domain).update("\0").update(value).digest("hex");
13672
+ return createHash10("sha256").update(domain).update("\0").update(value).digest("hex");
11902
13673
  }
11903
13674
  function hashesMatch(left, right) {
11904
13675
  const leftBytes = Buffer.from(left, "hex");
@@ -11967,12 +13738,12 @@ var SupportPassportGrantStore = class {
11967
13738
  runWithHeldFileLock;
11968
13739
  syncDirectory;
11969
13740
  constructor(options) {
11970
- this.memoryDir = path14.resolve(expandTildePath(options.memoryDir));
11971
- this.grantsDir = path14.join(this.memoryDir, "state", "support-passport", "grants");
11972
- this.ownerIndexesDir = path14.join(this.grantsDir, "owners");
13741
+ this.memoryDir = path18.resolve(expandTildePath(options.memoryDir));
13742
+ this.grantsDir = path18.join(this.memoryDir, "state", "support-passport", "grants");
13743
+ this.ownerIndexesDir = path18.join(this.grantsDir, "owners");
11973
13744
  this.now = options.now ?? (() => /* @__PURE__ */ new Date());
11974
13745
  this.makeSecret = options.makeSecret ?? (() => randomBytes(32));
11975
- this.makeGrantId = options.makeGrantId ?? randomUUID3;
13746
+ this.makeGrantId = options.makeGrantId ?? randomUUID4;
11976
13747
  this.runWithHeldFileLock = options.withHeldFileLock ?? withHeldFileLock;
11977
13748
  this.syncDirectory = options.syncDirectory ?? syncDirectoryForDurability;
11978
13749
  }
@@ -12182,11 +13953,11 @@ var SupportPassportGrantStore = class {
12182
13953
  }
12183
13954
  filePath(grantId) {
12184
13955
  const normalizedGrantId = normalizeGrantId(grantId);
12185
- return path14.join(this.grantsDir, `${normalizedGrantId}.json`);
13956
+ return path18.join(this.grantsDir, `${normalizedGrantId}.json`);
12186
13957
  }
12187
13958
  ownerIndexPath(ownerHash) {
12188
13959
  if (!SAFE_OWNER_INDEX_HASH.test(ownerHash)) throw new Error("support passport owner index hash is invalid");
12189
- return path14.join(this.ownerIndexesDir, `${ownerHash}.json`);
13960
+ return path18.join(this.ownerIndexesDir, `${ownerHash}.json`);
12190
13961
  }
12191
13962
  ownerHash(namespace, principalHash) {
12192
13963
  return sha256("support-passport-owner-index:v1", `${namespace}\0${principalHash}`);
@@ -12242,12 +14013,12 @@ var SupportPassportGrantStore = class {
12242
14013
  this.grantsDir,
12243
14014
  grantIds.map((grantId) => `${grantId}.json`),
12244
14015
  "support passport grant files must be regular files in a stable directory",
12245
- path14.parse(this.memoryDir).root
14016
+ path18.parse(this.memoryDir).root
12246
14017
  );
12247
14018
  }
12248
14019
  ownerMembershipDirectory(ownerHash) {
12249
14020
  if (!SAFE_OWNER_INDEX_HASH.test(ownerHash)) throw new Error("support passport owner index hash is invalid");
12250
- return path14.join(this.ownerIndexesDir, ownerHash);
14021
+ return path18.join(this.ownerIndexesDir, ownerHash);
12251
14022
  }
12252
14023
  async ensureOwnerMembershipDirectory(ownerHash) {
12253
14024
  const directory = this.ownerMembershipDirectory(ownerHash);
@@ -12262,11 +14033,11 @@ var SupportPassportGrantStore = class {
12262
14033
  const directory = await this.ensureOwnerMembershipDirectory(ownerHash);
12263
14034
  await writePrivateFileAtomicallyNoFollow(
12264
14035
  directory,
12265
- path14.join(directory, `${state.grantId}.json`),
14036
+ path18.join(directory, `${state.grantId}.json`),
12266
14037
  `${JSON.stringify({ schemaVersion: 1, grantId: state.grantId })}
12267
14038
  `,
12268
14039
  "support passport owner membership must be regular files in a stable directory",
12269
- path14.parse(this.memoryDir).root
14040
+ path18.parse(this.memoryDir).root
12270
14041
  );
12271
14042
  }
12272
14043
  async removeOwnerMembership(state) {
@@ -12276,7 +14047,7 @@ var SupportPassportGrantStore = class {
12276
14047
  directory,
12277
14048
  [`${state.grantId}.json`],
12278
14049
  "support passport owner membership must be regular files in a stable directory",
12279
- path14.parse(this.memoryDir).root
14050
+ path18.parse(this.memoryDir).root
12280
14051
  );
12281
14052
  }
12282
14053
  async removeStoredGrant(state) {
@@ -12377,7 +14148,7 @@ var SupportPassportGrantStore = class {
12377
14148
  const ownerHash = this.ownerHash(namespace, principalHash);
12378
14149
  const directory = await this.ensureOwnerMembershipDirectory(ownerHash);
12379
14150
  const grantIds = await withPrivateDirectoryNoFollow(
12380
- path14.parse(this.memoryDir).root,
14151
+ path18.parse(this.memoryDir).root,
12381
14152
  directory,
12382
14153
  "support passport owner membership must be regular files in a stable directory",
12383
14154
  async (pinnedDirectory) => {
@@ -12408,7 +14179,7 @@ var SupportPassportGrantStore = class {
12408
14179
  this.ownerIndexesDir,
12409
14180
  filePath,
12410
14181
  "support passport owner indexes must be regular files in a stable directory",
12411
- path14.parse(this.memoryDir).root
14182
+ path18.parse(this.memoryDir).root
12412
14183
  );
12413
14184
  } catch (error) {
12414
14185
  if (error.code === "ENOENT") return [];
@@ -12448,7 +14219,7 @@ var SupportPassportGrantStore = class {
12448
14219
  `${JSON.stringify({ schemaVersion: 1, ownerHash, grantIds }, null, 2)}
12449
14220
  `,
12450
14221
  "support passport owner indexes must be regular files in a stable directory",
12451
- path14.parse(this.memoryDir).root
14222
+ path18.parse(this.memoryDir).root
12452
14223
  );
12453
14224
  }
12454
14225
  async readState(grantId) {
@@ -12458,7 +14229,7 @@ var SupportPassportGrantStore = class {
12458
14229
  this.grantsDir,
12459
14230
  filePath,
12460
14231
  "support passport grant files must be regular files in a stable directory",
12461
- path14.parse(this.memoryDir).root
14232
+ path18.parse(this.memoryDir).root
12462
14233
  );
12463
14234
  try {
12464
14235
  const state = SupportPassportGrantStateSchema.parse(JSON.parse(content));
@@ -12492,7 +14263,7 @@ var SupportPassportGrantStore = class {
12492
14263
  `${JSON.stringify(state, null, 2)}
12493
14264
  `,
12494
14265
  "support passport grant files must be regular files in a stable directory",
12495
- path14.parse(this.memoryDir).root
14266
+ path18.parse(this.memoryDir).root
12496
14267
  );
12497
14268
  }
12498
14269
  async ensureSafeDirectories() {
@@ -12526,8 +14297,8 @@ var SupportPassportGrantStore = class {
12526
14297
  void 0
12527
14298
  );
12528
14299
  this.memoryDir = configuredMemoryDir;
12529
- this.grantsDir = path14.join(configuredMemoryDir, "state", "support-passport", "grants");
12530
- this.ownerIndexesDir = path14.join(this.grantsDir, "owners");
14300
+ this.grantsDir = path18.join(configuredMemoryDir, "state", "support-passport", "grants");
14301
+ this.ownerIndexesDir = path18.join(this.grantsDir, "owners");
12531
14302
  })();
12532
14303
  }
12533
14304
  const currentAttempt = this.memoryRootReady;
@@ -12541,12 +14312,12 @@ var SupportPassportGrantStore = class {
12541
14312
  async withMutationLock(task) {
12542
14313
  await this.ensureSafeDirectories();
12543
14314
  return await withPrivateDirectoryNoFollow(
12544
- path14.parse(this.memoryDir).root,
14315
+ path18.parse(this.memoryDir).root,
12545
14316
  this.grantsDir,
12546
14317
  "support passport grant lock directory must remain inside the memory directory",
12547
14318
  async (pinnedDirectory) => await this.withExclusiveLock(
12548
14319
  `support-passport-grants:${this.grantsDir}`,
12549
- path14.join(pinnedDirectory, ".grants.lock"),
14320
+ path18.join(pinnedDirectory, ".grants.lock"),
12550
14321
  task
12551
14322
  )
12552
14323
  );
@@ -12555,12 +14326,12 @@ var SupportPassportGrantStore = class {
12555
14326
  const normalizedGrantId = normalizeGrantId(grantId);
12556
14327
  await this.ensureSafeDirectories();
12557
14328
  return await withPrivateDirectoryNoFollow(
12558
- path14.parse(this.memoryDir).root,
14329
+ path18.parse(this.memoryDir).root,
12559
14330
  this.grantsDir,
12560
14331
  "support passport grant lock directory must remain inside the memory directory",
12561
14332
  async (pinnedDirectory) => await this.withExclusiveLock(
12562
14333
  `support-passport-grant:${this.grantsDir}:${normalizedGrantId}`,
12563
- path14.join(pinnedDirectory, `.${normalizedGrantId}.lock`),
14334
+ path18.join(pinnedDirectory, `.${normalizedGrantId}.lock`),
12564
14335
  task
12565
14336
  )
12566
14337
  );
@@ -12568,12 +14339,12 @@ var SupportPassportGrantStore = class {
12568
14339
  async withOwnerIndexLock(ownerHash, task) {
12569
14340
  await this.ensureSafeDirectories();
12570
14341
  return await withPrivateDirectoryNoFollow(
12571
- path14.parse(this.memoryDir).root,
14342
+ path18.parse(this.memoryDir).root,
12572
14343
  this.ownerIndexesDir,
12573
14344
  "support passport owner lock directory must remain inside the memory directory",
12574
14345
  async (pinnedDirectory) => await this.withExclusiveLock(
12575
14346
  `support-passport-owner:${this.ownerIndexesDir}:${ownerHash}`,
12576
- path14.join(pinnedDirectory, `.${ownerHash}.lock`),
14347
+ path18.join(pinnedDirectory, `.${ownerHash}.lock`),
12577
14348
  task
12578
14349
  )
12579
14350
  );
@@ -13410,8 +15181,8 @@ var SupportPassportModelAdapter = class {
13410
15181
  };
13411
15182
 
13412
15183
  // src/support-passport/model-audit.ts
13413
- import { createHash as createHash8 } from "crypto";
13414
- import path15 from "path";
15184
+ import { createHash as createHash11 } from "crypto";
15185
+ import path19 from "path";
13415
15186
  import { z as z5 } from "zod";
13416
15187
  var HashSchema = z5.string().regex(/^[a-f0-9]{64}$/);
13417
15188
  var SupportPassportModelAuditRecordSchema = z5.object({
@@ -13448,7 +15219,7 @@ var SupportPassportModelAuditRecordSchema = z5.object({
13448
15219
  }
13449
15220
  });
13450
15221
  function hashSupportPassportAuditValues(domain, values) {
13451
- return createHash8("sha256").update(`support-passport-audit:${domain}:v1`).update("\0").update([...values].sort().join("\0")).digest("hex");
15222
+ return createHash11("sha256").update(`support-passport-audit:${domain}:v1`).update("\0").update([...values].sort().join("\0")).digest("hex");
13452
15223
  }
13453
15224
  var SupportPassportModelAuditStore = class {
13454
15225
  memoryDir;
@@ -13456,15 +15227,15 @@ var SupportPassportModelAuditStore = class {
13456
15227
  memoryRootReady;
13457
15228
  runWithHeldFileLock;
13458
15229
  constructor(options) {
13459
- this.memoryDir = path15.resolve(expandTildePath(options.memoryDir));
13460
- this.auditDir = path15.join(this.memoryDir, "state", "support-passport", "audit");
15230
+ this.memoryDir = path19.resolve(expandTildePath(options.memoryDir));
15231
+ this.auditDir = path19.join(this.memoryDir, "state", "support-passport", "audit");
13461
15232
  this.runWithHeldFileLock = options.withHeldFileLock ?? withHeldFileLock;
13462
15233
  }
13463
15234
  async record(input) {
13464
15235
  const record = SupportPassportModelAuditRecordSchema.parse(input);
13465
15236
  await this.ensureSafeDirectories();
13466
15237
  const day = record.occurredAt.slice(0, 10);
13467
- const filePath = path15.join(this.auditDir, `${day}.jsonl`);
15238
+ const filePath = path19.join(this.auditDir, `${day}.jsonl`);
13468
15239
  await serializeMutations(
13469
15240
  `support-passport-audit:${filePath}`,
13470
15241
  () => withPrivateDirectoryNoFollow(
@@ -13472,7 +15243,7 @@ var SupportPassportModelAuditStore = class {
13472
15243
  this.auditDir,
13473
15244
  "support passport audit directory must remain inside the memory directory",
13474
15245
  async (pinnedDirectory) => await this.runWithHeldFileLock(
13475
- path15.join(pinnedDirectory, `.${day}.lock`),
15246
+ path19.join(pinnedDirectory, `.${day}.lock`),
13476
15247
  {
13477
15248
  staleMs: 3e4,
13478
15249
  maxWaitMs: 5e3,
@@ -13509,7 +15280,7 @@ var SupportPassportModelAuditStore = class {
13509
15280
  "support passport memory directory must be a stable directory"
13510
15281
  );
13511
15282
  this.memoryDir = configuredMemoryDir;
13512
- this.auditDir = path15.join(configuredMemoryDir, "state", "support-passport", "audit");
15283
+ this.auditDir = path19.join(configuredMemoryDir, "state", "support-passport", "audit");
13513
15284
  })();
13514
15285
  }
13515
15286
  const currentAttempt = this.memoryRootReady;
@@ -13523,7 +15294,7 @@ var SupportPassportModelAuditStore = class {
13523
15294
  };
13524
15295
 
13525
15296
  // src/support-passport/model-service.ts
13526
- import { createHash as createHash9 } from "crypto";
15297
+ import { createHash as createHash12 } from "crypto";
13527
15298
  import { z as z6 } from "zod";
13528
15299
  var DraftServiceInputSchema = z6.object({
13529
15300
  principal: z6.string().trim().min(1).max(512),
@@ -13559,7 +15330,7 @@ function supportPassportSourceContent(memory) {
13559
15330
  return hasStructuredAttributes(memory.frontmatter.structuredAttributes) ? stripAttributesSuffix(memory.content) : memory.content;
13560
15331
  }
13561
15332
  function computeSupportPassportSourceRevision(content, structuredAttributes) {
13562
- return createHash9("sha256").update("support-passport-source:v1\0").update(hasStructuredAttributes(structuredAttributes) ? stripAttributesSuffix(content) : content).digest("hex");
15333
+ return createHash12("sha256").update("support-passport-source:v1\0").update(hasStructuredAttributes(structuredAttributes) ? stripAttributesSuffix(content) : content).digest("hex");
13563
15334
  }
13564
15335
  function isSupportPassportSourceEligible(memory) {
13565
15336
  const status = memory.frontmatter.status ?? "active";
@@ -14195,6 +15966,7 @@ var EngramAccessService = class extends SupportPassportAccessServiceBase {
14195
15966
  this.idempotency = new AccessIdempotencyStore(orchestrator.config.memoryDir);
14196
15967
  this.replicaDivergenceMonitor = new ReplicaDivergenceMonitor({ resolveSecretRef: options.resolveSecretRef });
14197
15968
  this.injectedSupportPassportGatewayRoute = options.supportPassportGatewayRoute ?? null;
15969
+ this.reviewDeckEnabled = options.reviewDeckEnabled === true;
14198
15970
  const accessCaps = resolveAccessSetupCapabilities(orchestrator.config);
14199
15971
  this.budget = new CrossNamespaceBudget({
14200
15972
  enabled: accessCaps.recallCrossNamespaceBudget,
@@ -14234,6 +16006,7 @@ var EngramAccessService = class extends SupportPassportAccessServiceBase {
14234
16006
  corpusWatermarkCache = new CorpusWatermarkCache();
14235
16007
  replicaDivergenceMonitor;
14236
16008
  injectedSupportPassportGatewayRoute;
16009
+ reviewDeckEnabled;
14237
16010
  /** AccessObserveWriteSurface (access-service decomposition). Lazy; selfDeps live wiring. */
14238
16011
  _accessObserveWriteSurface;
14239
16012
  get accessObserveWriteSurface() {
@@ -14262,6 +16035,15 @@ var EngramAccessService = class extends SupportPassportAccessServiceBase {
14262
16035
  }
14263
16036
  return this._accessAdminOpsSurface;
14264
16037
  }
16038
+ _reviewDeckSurface;
16039
+ get reviewDeckSurface() {
16040
+ if (!this._reviewDeckSurface) {
16041
+ this._reviewDeckSurface = new ReviewDeckSurface(
16042
+ selfDeps(this)
16043
+ );
16044
+ }
16045
+ return this._reviewDeckSurface;
16046
+ }
14265
16047
  /** AccessRecallSurface (access-service decomposition). Lazy; selfDeps live wiring. */
14266
16048
  _accessRecallSurface;
14267
16049
  get accessRecallSurface() {
@@ -15223,6 +17005,36 @@ var EngramAccessService = class extends SupportPassportAccessServiceBase {
15223
17005
  ]);
15224
17006
  return computeWhoKnows({ topic, limit, memories, entities });
15225
17007
  }
17008
+ /**
17009
+ * Read-only promotion-candidate surfacing (issue #2372): agent-subject,
17010
+ * active, reuse-signaled memories in the caller's namespace with no
17011
+ * equivalent in the target layer. No auto-promotion — callers use the
17012
+ * existing promotion commands.
17013
+ */
17014
+ async promotionCandidates(request) {
17015
+ const limit = request.limit ?? 20;
17016
+ if (!Number.isInteger(limit) || limit < 1 || limit > 100) {
17017
+ throw new EngramAccessInputError(
17018
+ `promotion_candidates: limit expects an integer in [1, 100] (got ${String(request.limit)})`
17019
+ );
17020
+ }
17021
+ const resolvedNamespace = this.resolveReadableNamespace(request.namespace, request.authenticatedPrincipal);
17022
+ const resolvedTarget = this.resolveReadableNamespace(
17023
+ request.targetNamespace ?? this.orchestrator.config.sharedNamespace,
17024
+ request.authenticatedPrincipal
17025
+ );
17026
+ const minAccessCount = this.orchestrator.config.promotionCandidates.minAccessCount;
17027
+ const [memories, targetMemories] = await Promise.all([
17028
+ (await this.orchestrator.getStorage(resolvedNamespace)).readAllMemories(),
17029
+ (await this.orchestrator.getStorage(resolvedTarget)).readAllMemories()
17030
+ ]);
17031
+ return {
17032
+ namespace: resolvedNamespace,
17033
+ targetNamespace: resolvedTarget,
17034
+ minAccessCount,
17035
+ candidates: computePromotionCandidates({ memories, targetMemories, minAccessCount, limit })
17036
+ };
17037
+ }
15226
17038
  async memoryStore(request, hooks) {
15227
17039
  return this.accessObserveWriteSurface.memoryStore(request, hooks);
15228
17040
  }
@@ -15863,6 +17675,35 @@ var EngramAccessService = class extends SupportPassportAccessServiceBase {
15863
17675
  });
15864
17676
  return { namespace: resolvedNamespace, ...report };
15865
17677
  }
17678
+ /**
17679
+ * Procedure library health maintenance (issue #2370). Shadow-first: the
17680
+ * gate is checked BEFORE any storage read, so `maintenance.enabled=false`
17681
+ * returns `{ enabled: false }` having touched nothing but config. Apply
17682
+ * mode additionally requires `apply: true`; `dryRun: true` forces shadow.
17683
+ *
17684
+ * The authenticated principal (never a client-supplied actor) drives the
17685
+ * namespace via the same writable resolver `procedureMiningRun` uses, so
17686
+ * cross-tenant writes are impossible.
17687
+ */
17688
+ async procedureLibraryMaintenance(request, principal) {
17689
+ const procedural = this.orchestrator.config.procedural;
17690
+ if (procedural?.enabled !== true || procedural.maintenance?.enabled !== true) {
17691
+ return { enabled: false };
17692
+ }
17693
+ const resolvedNamespace = this.writableNamespaceFor(
17694
+ request.namespace,
17695
+ void 0,
17696
+ request.authenticatedPrincipal ?? principal
17697
+ );
17698
+ const storage = await this.orchestrator.getStorage(resolvedNamespace);
17699
+ const report = await runProcedureLibraryMaintenance({
17700
+ memoryDir: storage.dir,
17701
+ storage,
17702
+ config: this.orchestrator.config,
17703
+ apply: request.apply === true && request.dryRun !== true
17704
+ });
17705
+ return { enabled: true, namespace: resolvedNamespace, report };
17706
+ }
15866
17707
  async memorySummarizeHourly() {
15867
17708
  await this.orchestrator.summarizer.runHourly();
15868
17709
  return {
@@ -16986,8 +18827,8 @@ var EngramAccessService = class extends SupportPassportAccessServiceBase {
16986
18827
  async offlineSyncSnapshot(options = {}) {
16987
18828
  const resolvedNamespace = this.resolveReadableNamespace(options.namespace, options.principal);
16988
18829
  const storage = await offlineSyncStorageForSnapshot(this.orchestrator, resolvedNamespace);
16989
- const storageHash = createHash10("sha256").update(storage.dir).digest("hex").slice(0, 16);
16990
- const deletions = [...await storage.readDeletionRevisions()].map(([path16, mtimeMs]) => ({ path: path16, mtimeMs }));
18830
+ const storageHash = createHash13("sha256").update(storage.dir).digest("hex").slice(0, 16);
18831
+ const deletions = [...await storage.readDeletionRevisions()].map(([path20, mtimeMs]) => ({ path: path20, mtimeMs }));
16991
18832
  const snapshotBuilder = options.includeContent === false && options.baseFiles && options.baseFiles.length > 0 ? buildOfflineSyncSnapshotFromBase : buildOfflineSyncSnapshot;
16992
18833
  const snapshot = await snapshotBuilder({
16993
18834
  root: storage.dir,
@@ -17010,10 +18851,10 @@ var EngramAccessService = class extends SupportPassportAccessServiceBase {
17010
18851
  async offlineSyncSnapshotStream(options = {}) {
17011
18852
  const resolvedNamespace = this.resolveReadableNamespace(options.namespace, options.principal);
17012
18853
  const storage = await offlineSyncStorageForSnapshot(this.orchestrator, resolvedNamespace);
17013
- const storageHash = createHash10("sha256").update(storage.dir).digest("hex").slice(0, 16);
18854
+ const storageHash = createHash13("sha256").update(storage.dir).digest("hex").slice(0, 16);
17014
18855
  const deletions = await filterOfflineSyncDeletionRevisions({
17015
18856
  root: storage.dir,
17016
- deletions: [...await storage.readDeletionRevisions()].map(([path16, mtimeMs]) => ({ path: path16, mtimeMs })),
18857
+ deletions: [...await storage.readDeletionRevisions()].map(([path20, mtimeMs]) => ({ path: path20, mtimeMs })),
17017
18858
  includeTranscripts: options.includeTranscripts !== false,
17018
18859
  userExcludeRegexps: this.offlineSyncUserExcludes
17019
18860
  });
@@ -17050,7 +18891,7 @@ var EngramAccessService = class extends SupportPassportAccessServiceBase {
17050
18891
  async offlineSyncFiles(options) {
17051
18892
  const resolvedNamespace = this.resolveReadableNamespace(options.namespace, options.principal);
17052
18893
  const storage = await offlineSyncStorageForSnapshot(this.orchestrator, resolvedNamespace);
17053
- const storageHash = createHash10("sha256").update(storage.dir).digest("hex").slice(0, 16);
18894
+ const storageHash = createHash13("sha256").update(storage.dir).digest("hex").slice(0, 16);
17054
18895
  try {
17055
18896
  const snapshot = await buildOfflineSyncSnapshotForPaths({
17056
18897
  root: storage.dir,
@@ -17289,6 +19130,15 @@ var EngramAccessService = class extends SupportPassportAccessServiceBase {
17289
19130
  async adminPromoteMemory(request) {
17290
19131
  return this.accessAdminOpsSurface.adminPromoteMemory(request);
17291
19132
  }
19133
+ async reviewDeckList(opts) {
19134
+ return this.reviewDeckSurface.list(opts);
19135
+ }
19136
+ async reviewDeckAction(...args) {
19137
+ return this.reviewDeckSurface.action(...args);
19138
+ }
19139
+ async reviewDeckUndo(...args) {
19140
+ return this.reviewDeckSurface.undo(...args);
19141
+ }
17292
19142
  };
17293
19143
 
17294
19144
  // src/access-recall-concurrency.ts
@@ -17647,6 +19497,7 @@ export {
17647
19497
  resolveNamespaceWritablePreflight,
17648
19498
  resolveAuthorizedNamespaceWritablePreflight,
17649
19499
  resolveQueryNamespaceWritablePreflight,
19500
+ runProcedureLibraryMaintenance,
17650
19501
  computeProcedureStats,
17651
19502
  formatProcedureStatsText,
17652
19503
  AccessIdentityContinuitySurface,
@@ -17659,6 +19510,17 @@ export {
17659
19510
  RecallResultFormatter,
17660
19511
  assembleRecallResponse,
17661
19512
  AccessRecallSurface,
19513
+ ReviewDeckCursorError,
19514
+ computeReviewItemRevision,
19515
+ projectReviewDeckItem,
19516
+ compareReviewDeckRows,
19517
+ encodeReviewDeckCursor,
19518
+ decodeReviewDeckCursor,
19519
+ buildReviewDeckPage,
19520
+ listReviewItems,
19521
+ performReview,
19522
+ readReviewDeckSnapshot,
19523
+ readReviewDeckRow,
17662
19524
  SupportPassportError,
17663
19525
  SupportPassportGrantCardRefSchema,
17664
19526
  SupportPassportGrantStateSchema,
@@ -17705,4 +19567,4 @@ export {
17705
19567
  EngramAccessService,
17706
19568
  AccessAdminOpsSurface
17707
19569
  };
17708
- //# sourceMappingURL=chunk-3PXVYJMC.js.map
19570
+ //# sourceMappingURL=chunk-WN5FSGLE.js.map