@remnic/core 9.65.2 → 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 (449) hide show
  1. package/dist/access-admin-ops-surface.d.ts +44 -44
  2. package/dist/access-admin-ops-surface.js +14 -14
  3. package/dist/access-authorization-probe.d.ts +38 -38
  4. package/dist/access-authorization-probe.js +15 -15
  5. package/dist/access-boundary.d.ts +40 -40
  6. package/dist/access-boundary.js +14 -14
  7. package/dist/access-cli.js +52 -52
  8. package/dist/access-coding-context-resolution.d.ts +3 -1
  9. package/dist/access-extraction-force-flush.d.ts +25 -25
  10. package/dist/access-extraction-force-flush.js +14 -14
  11. package/dist/access-health-types.d.ts +3 -1
  12. package/dist/access-http-lcm-compaction.d.ts +39 -39
  13. package/dist/access-http-lifecycle-flush.d.ts +39 -39
  14. package/dist/access-http-offline-stream.d.ts +25 -25
  15. package/dist/access-http-query.d.ts +4 -2
  16. package/dist/access-http-query.js +16 -16
  17. package/dist/access-http.d.ts +51 -44
  18. package/dist/access-http.js +30 -30
  19. package/dist/access-identity-continuity-surface.d.ts +12 -12
  20. package/dist/access-identity-continuity-surface.js +14 -14
  21. package/dist/access-lcm-surface.d.ts +27 -27
  22. package/dist/access-lcm-surface.js +14 -14
  23. package/dist/access-mcp-admin-tools.d.ts +9 -1
  24. package/dist/access-mcp-admin-tools.js +3 -1
  25. package/dist/access-mcp-output-schemas.js +1 -1
  26. package/dist/access-mcp.d.ts +39 -39
  27. package/dist/access-mcp.js +24 -24
  28. package/dist/access-memory-search-fanout.d.ts +4 -2
  29. package/dist/{access-namespace-preflight-Dhvcl-T0.d.ts → access-namespace-preflight-B7Usyz-K.d.ts} +1 -1
  30. package/dist/access-namespace-preflight.d.ts +5 -3
  31. package/dist/access-namespace-preflight.js +14 -14
  32. package/dist/access-observe-write-surface.d.ts +39 -39
  33. package/dist/access-observe-write-surface.js +14 -14
  34. package/dist/access-offline-manifest.d.ts +12 -12
  35. package/dist/access-operations-batch.js +18 -18
  36. package/dist/access-operations.d.ts +40 -40
  37. package/dist/access-operations.js +21 -21
  38. package/dist/access-recall-concurrency.d.ts +40 -40
  39. package/dist/access-recall-concurrency.js +14 -14
  40. package/dist/access-recall-response.d.ts +24 -24
  41. package/dist/access-recall-response.js +14 -14
  42. package/dist/access-recall-surface.d.ts +24 -24
  43. package/dist/access-recall-surface.js +14 -14
  44. package/dist/access-schema.d.ts +45 -45
  45. package/dist/{access-service-Bke1alZO.d.ts → access-service-DkaIG3n8.d.ts} +219 -75
  46. package/dist/access-service-helpers.d.ts +40 -40
  47. package/dist/access-service.d.ts +47 -47
  48. package/dist/access-service.js +14 -14
  49. package/dist/access-surface-catalog.d.ts +40 -40
  50. package/dist/access-surface-catalog.js +20 -16
  51. package/dist/access-surface-catalog.js.map +1 -1
  52. package/dist/access-wearables-meetings-surface.d.ts +5 -3
  53. package/dist/action-confidence.d.ts +3 -1
  54. package/dist/active-memory-bridge.d.ts +3 -1
  55. package/dist/active-recall.d.ts +3 -1
  56. package/dist/active-recall.js +6 -1
  57. package/dist/active-recall.js.map +1 -1
  58. package/dist/ambient-provenance.d.ts +3 -1
  59. package/dist/artifact-search.d.ts +3 -1
  60. package/dist/behavior-learner.d.ts +3 -1
  61. package/dist/behavior-signals.d.ts +3 -1
  62. package/dist/bootstrap.d.ts +12 -12
  63. package/dist/briefing-window.d.ts +4 -2
  64. package/dist/briefing.d.ts +4 -2
  65. package/dist/briefing.js +3 -3
  66. package/dist/buffer-surprise-report.d.ts +3 -1
  67. package/dist/buffer-turn-helpers.d.ts +3 -1
  68. package/dist/buffer.d.ts +4 -2
  69. package/dist/bulk-import/index.d.ts +5 -3
  70. package/dist/calibration.d.ts +3 -1
  71. package/dist/capabilities.d.ts +3 -1
  72. package/dist/{catalog-DV6qnbr7.d.ts → catalog-CX2BZEJh.d.ts} +1 -1
  73. package/dist/causal-behavior.d.ts +1 -1
  74. package/dist/causal-consolidation.d.ts +3 -1
  75. package/dist/causal-consolidation.js +7 -7
  76. package/dist/causal-trajectory-graph.d.ts +1 -1
  77. package/dist/{chunk-R7JAM2XF.js → chunk-2VXWFYJE.js} +3 -3
  78. package/dist/{chunk-UXO5IMBK.js → chunk-4XDGYCZI.js} +2 -2
  79. package/dist/{chunk-OTHZWLUD.js → chunk-57HVIG5U.js} +2 -2
  80. package/dist/{chunk-EILZG5VC.js → chunk-6TAX66IA.js} +2 -2
  81. package/dist/{chunk-NKKD4ZAU.js → chunk-6VALIZKG.js} +2 -2
  82. package/dist/{chunk-BWLRUMOG.js → chunk-76PL4XLG.js} +435 -1
  83. package/dist/chunk-76PL4XLG.js.map +1 -0
  84. package/dist/{chunk-2E36UXVW.js → chunk-7KFIMGMP.js} +2 -2
  85. package/dist/{chunk-LGO6A7GJ.js → chunk-7QOO4LGC.js} +28 -28
  86. package/dist/{chunk-TBOJ76ER.js → chunk-AB3A7EFH.js} +18 -2
  87. package/dist/{chunk-TBOJ76ER.js.map → chunk-AB3A7EFH.js.map} +1 -1
  88. package/dist/{chunk-DZUJ46DO.js → chunk-AUO2LJ3K.js} +2 -2
  89. package/dist/{chunk-ZO6AXLEH.js → chunk-AYDDB3XI.js} +2 -2
  90. package/dist/{chunk-NTWN6HB2.js → chunk-AYYGRVRP.js} +2 -2
  91. package/dist/{chunk-7YQ4IYS2.js → chunk-AZAA5DNP.js} +2 -2
  92. package/dist/{chunk-4KYOLI6M.js → chunk-BKYPJUQL.js} +120 -14
  93. package/dist/chunk-BKYPJUQL.js.map +1 -0
  94. package/dist/{chunk-Z7PBQPJ4.js → chunk-BQUEAVNW.js} +2 -2
  95. package/dist/{chunk-35NN3ZFA.js → chunk-CTVWELNK.js} +21 -3
  96. package/dist/chunk-CTVWELNK.js.map +1 -0
  97. package/dist/{chunk-5YQ63T4B.js → chunk-D27J626P.js} +2 -2
  98. package/dist/{chunk-LZH5FR2W.js → chunk-DHTQP334.js} +2 -2
  99. package/dist/{chunk-Y7DK7HHJ.js → chunk-E4MVQQVX.js} +2 -2
  100. package/dist/{chunk-JYYBA7TF.js → chunk-EIVIB73I.js} +2 -2
  101. package/dist/{chunk-S2DPMJXH.js → chunk-EV3YFLCB.js} +2 -2
  102. package/dist/{chunk-TZNQUNKL.js → chunk-FC7TIRFS.js} +15 -1
  103. package/dist/chunk-FC7TIRFS.js.map +1 -0
  104. package/dist/{chunk-3I7ASZN3.js → chunk-G57LQRP6.js} +2 -2
  105. package/dist/{chunk-UIN2BWDD.js → chunk-GN55KU2P.js} +2 -2
  106. package/dist/{chunk-PE255F4T.js → chunk-GUXS322H.js} +2 -2
  107. package/dist/{chunk-V3MXUL3D.js → chunk-H5FW4S5Q.js} +319 -643
  108. package/dist/chunk-H5FW4S5Q.js.map +1 -0
  109. package/dist/chunk-I32NKXE2.js +879 -0
  110. package/dist/chunk-I32NKXE2.js.map +1 -0
  111. package/dist/{chunk-YB42WZCY.js → chunk-IQSC3V2E.js} +2 -2
  112. package/dist/{chunk-MN4KB2A4.js → chunk-MBDJJTAT.js} +3 -3
  113. package/dist/{chunk-SQI57UCJ.js → chunk-MRTUN665.js} +2 -2
  114. package/dist/{chunk-SBDCZ2AX.js → chunk-NXKJHSDN.js} +1 -1
  115. package/dist/chunk-NXKJHSDN.js.map +1 -0
  116. package/dist/{chunk-SPUJNJJC.js → chunk-NZWEEALH.js} +2 -2
  117. package/dist/{chunk-2XDWWPTN.js → chunk-OJD4WS2E.js} +2 -2
  118. package/dist/{chunk-ZWXJBFZU.js → chunk-OLWTCWQ2.js} +8 -8
  119. package/dist/{chunk-XRYZRW54.js → chunk-P4DHENRE.js} +2 -2
  120. package/dist/{chunk-J275IYMG.js → chunk-PAYGC3BD.js} +29 -2
  121. package/dist/chunk-PAYGC3BD.js.map +1 -0
  122. package/dist/{chunk-IID2CMUU.js → chunk-PDVQ5JU3.js} +2 -2
  123. package/dist/{chunk-7BY7V4YX.js → chunk-Q4WONDMJ.js} +4 -3
  124. package/dist/{chunk-7BY7V4YX.js.map → chunk-Q4WONDMJ.js.map} +1 -1
  125. package/dist/{chunk-5NM4OH4P.js → chunk-QFMO32TO.js} +3 -3
  126. package/dist/{chunk-SIHSCCUQ.js → chunk-QXIQPCCN.js} +1 -1
  127. package/dist/{chunk-2YI72KM3.js → chunk-R47WINCY.js} +2 -2
  128. package/dist/{chunk-ZQHI2BZB.js → chunk-RK4WXUI2.js} +2 -2
  129. package/dist/{chunk-QOS5LBZN.js → chunk-S7Q5CM7E.js} +2 -2
  130. package/dist/{chunk-GDFVPUJ5.js → chunk-TDKSCV62.js} +2 -2
  131. package/dist/{chunk-OCZIYAE5.js → chunk-TYUS5TLG.js} +3 -3
  132. package/dist/{chunk-GNCCUR6K.js → chunk-URHCUXKI.js} +2 -2
  133. package/dist/{chunk-TF77C7SV.js → chunk-VA5KMSAE.js} +7 -5
  134. package/dist/chunk-VA5KMSAE.js.map +1 -0
  135. package/dist/{chunk-SB7D4BT7.js → chunk-WN5FSGLE.js} +1545 -105
  136. package/dist/chunk-WN5FSGLE.js.map +1 -0
  137. package/dist/{chunk-YLDXWCZP.js → chunk-YF6UHWOV.js} +14 -9
  138. package/dist/chunk-YF6UHWOV.js.map +1 -0
  139. package/dist/{chunk-CT56C22C.js → chunk-Z4RPXHJH.js} +4 -4
  140. package/dist/{cli-cShQ13XG.d.ts → cli-ChKeYMZv.d.ts} +5 -5
  141. package/dist/cli.d.ts +25 -25
  142. package/dist/cli.js +44 -43
  143. package/dist/coding/pre-action-gate.d.ts +2 -60
  144. package/dist/compounding/engine.d.ts +4 -2
  145. package/dist/compounding/engine.js +3 -3
  146. package/dist/compounding/preference-consolidator.d.ts +3 -1
  147. package/dist/compression-optimizer.d.ts +3 -1
  148. package/dist/config.d.ts +3 -1
  149. package/dist/config.js +6 -1
  150. package/dist/connectors/codex-materialize-runner.d.ts +3 -1
  151. package/dist/connectors/codex-materialize-runner.js +3 -3
  152. package/dist/connectors/codex-materialize.d.ts +3 -1
  153. package/dist/connectors/index.d.ts +3 -1
  154. package/dist/connectors/index.js +3 -3
  155. package/dist/consolidation-provenance-check.d.ts +4 -2
  156. package/dist/consolidation-undo.d.ts +4 -2
  157. package/dist/contradiction/index.d.ts +10 -270
  158. package/dist/contradiction/index.js +11 -6
  159. package/dist/{contradiction-review-QKJH5DKD.js → contradiction-review-WRVLRWHS.js} +6 -2
  160. package/dist/{contradiction-scan-VOTQRRSX.js → contradiction-scan-AKUWPX5N.js} +5 -3
  161. package/dist/converge-config.d.ts +3 -1
  162. package/dist/convergence-refresh.d.ts +4 -2
  163. package/dist/convergence-refresh.js +5 -5
  164. package/dist/conversation-index/backend.d.ts +3 -1
  165. package/dist/conversation-index/chunker.d.ts +3 -1
  166. package/dist/conversation-index/faiss-adapter.d.ts +3 -1
  167. package/dist/conversation-index/indexer.d.ts +3 -1
  168. package/dist/conversation-index/search.d.ts +3 -1
  169. package/dist/corpus-watermark.d.ts +3 -1
  170. package/dist/corpus-watermark.js +5 -5
  171. package/dist/cross-lingual-recall.d.ts +3 -1
  172. package/dist/day-summary.d.ts +3 -1
  173. package/dist/delinearize.d.ts +3 -1
  174. package/dist/dependency-propagation-config.d.ts +3 -1
  175. package/dist/{dependency-propagation-delivery-CsGg-VwS.d.ts → dependency-propagation-delivery-B8ZMBBCY.d.ts} +1 -1
  176. package/dist/direct-answer-wiring.d.ts +3 -1
  177. package/dist/direct-answer.d.ts +3 -1
  178. package/dist/embedding-fallback.d.ts +3 -1
  179. package/dist/enrichment/index.d.ts +3 -1
  180. package/dist/entity-origin-fields.d.ts +3 -1
  181. package/dist/entity-retrieval.d.ts +4 -2
  182. package/dist/entity-retrieval.js +3 -3
  183. package/dist/entity-schema.d.ts +3 -1
  184. package/dist/episodic-context.d.ts +3 -1
  185. package/dist/explicit-capture.d.ts +12 -12
  186. package/dist/external-wiki-access.d.ts +40 -40
  187. package/dist/external-wiki-access.js +15 -15
  188. package/dist/external-wiki-collection-registration.d.ts +3 -1
  189. package/dist/external-wiki-collection.d.ts +3 -1
  190. package/dist/external-wiki-mcp-tools.d.ts +40 -40
  191. package/dist/extraction-error-classification.d.ts +3 -1
  192. package/dist/extraction-faithfulness.d.ts +3 -1
  193. package/dist/extraction-judge-telemetry.d.ts +3 -1
  194. package/dist/extraction-judge-training.d.ts +3 -1
  195. package/dist/extraction-judge.d.ts +3 -1
  196. package/dist/extraction-liveness.d.ts +3 -1
  197. package/dist/extraction-normalization.d.ts +3 -1
  198. package/dist/extraction-prompt.d.ts +3 -1
  199. package/dist/extraction-source-grounding-rules.d.ts +3 -1
  200. package/dist/extraction-source-grounding.d.ts +3 -1
  201. package/dist/extraction.d.ts +3 -1
  202. package/dist/extraction.js +3 -3
  203. package/dist/fallback-llm.d.ts +3 -1
  204. package/dist/graph-dashboard-diff.d.ts +3 -1
  205. package/dist/graph-dashboard-key.d.ts +3 -1
  206. package/dist/graph-dashboard-parser.d.ts +3 -1
  207. package/dist/graph-edge-reinforcement.d.ts +3 -1
  208. package/dist/graph-path-reconstruction.d.ts +3 -1
  209. package/dist/graph-path-scoring.d.ts +3 -1
  210. package/dist/graph-snapshot.d.ts +3 -1
  211. package/dist/graph.d.ts +3 -1
  212. package/dist/harmonic-retrieval.js +1 -1
  213. package/dist/importance.d.ts +3 -1
  214. package/dist/importers/index.d.ts +3 -1
  215. package/dist/in-flight-reads.d.ts +3 -1
  216. package/dist/index-CexDrJzC.d.ts +284 -0
  217. package/dist/index.d.ts +251 -29
  218. package/dist/index.js +129 -75
  219. package/dist/intent.d.ts +3 -1
  220. package/dist/lcm/engine.d.ts +3 -1
  221. package/dist/lcm/index.d.ts +3 -1
  222. package/dist/lcm/tools.d.ts +3 -1
  223. package/dist/lifecycle.d.ts +3 -1
  224. package/dist/live-connectors-runner.d.ts +3 -1
  225. package/dist/local-llm.d.ts +3 -1
  226. package/dist/local-model-endpoint.d.ts +3 -1
  227. package/dist/maintenance/memory-governance.d.ts +3 -1
  228. package/dist/maintenance/memory-governance.js +3 -3
  229. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +4 -2
  230. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
  231. package/dist/maintenance/rebuild-memory-projection.d.ts +4 -2
  232. package/dist/maintenance/rebuild-memory-projection.js +4 -4
  233. package/dist/{maintenance-jhMpeGne.d.ts → maintenance-nkdtSrVr.d.ts} +3 -3
  234. package/dist/mcp-memory-inspector-app.d.ts +37 -37
  235. package/dist/memory-action-policy.d.ts +3 -1
  236. package/dist/memory-cache.d.ts +3 -1
  237. package/dist/memory-lifecycle-ledger-utils.d.ts +3 -1
  238. package/dist/memory-projection-store.d.ts +3 -1
  239. package/dist/memory-provenance.d.ts +3 -1
  240. package/dist/memory-snapshot.d.ts +3 -1
  241. package/dist/memory-subject-cli.d.ts +40 -40
  242. package/dist/memory-subject.d.ts +42 -42
  243. package/dist/memory-worth-outcomes.d.ts +4 -2
  244. package/dist/models-json.d.ts +3 -1
  245. package/dist/namespaces/migrate.d.ts +5 -3
  246. package/dist/namespaces/migrate.js +4 -4
  247. package/dist/namespaces/principal.d.ts +3 -1
  248. package/dist/namespaces/search.d.ts +3 -1
  249. package/dist/namespaces/storage.d.ts +5 -3
  250. package/dist/namespaces/storage.js +3 -3
  251. package/dist/native-knowledge.d.ts +3 -1
  252. package/dist/offline-sync-impression-drain.d.ts +3 -1
  253. package/dist/operator-doctor-corpus.d.ts +3 -1
  254. package/dist/operator-doctor-corpus.js +6 -6
  255. package/dist/operator-doctor-replica.d.ts +3 -1
  256. package/dist/operator-toolkit.d.ts +5 -3
  257. package/dist/operator-toolkit.js +15 -12
  258. package/dist/orchestration/compression-guideline-coordinator.d.ts +4 -2
  259. package/dist/orchestration/maintenance.d.ts +6 -4
  260. package/dist/orchestration/maintenance.js +9 -9
  261. package/dist/{orchestrator-DyGUC7re.d.ts → orchestrator-Bvq1-RQs.d.ts} +23 -9
  262. package/dist/orchestrator.d.ts +12 -12
  263. package/dist/orchestrator.js +52 -52
  264. package/dist/patterns-cli.d.ts +3 -1
  265. package/dist/{pipeline-C25Oxtp1.d.ts → pipeline-C8vfIiTX.d.ts} +1 -1
  266. package/dist/policy-runtime.d.ts +3 -1
  267. package/dist/proactive-contention.d.ts +3 -1
  268. package/dist/provenance.d.ts +3 -1
  269. package/dist/{public-http-CMe7NQzj.d.ts → public-http-Cy0aYbys.d.ts} +1 -1
  270. package/dist/{qmd-DkDVCbgF.d.ts → qmd-B9p1SZTZ.d.ts} +1 -1
  271. package/dist/qmd-preflight.d.ts +4 -2
  272. package/dist/qmd-recall-cache.d.ts +3 -1
  273. package/dist/qmd.d.ts +4 -2
  274. package/dist/recall-concurrency-config.d.ts +3 -1
  275. package/dist/recall-disclosure-escalation.d.ts +3 -1
  276. package/dist/recall-explain-renderer.d.ts +3 -1
  277. package/dist/recall-explain-renderer.js +3 -3
  278. package/dist/recall-memory-map.d.ts +3 -1
  279. package/dist/recall-planner-llm.d.ts +3 -1
  280. package/dist/recall-state.d.ts +3 -1
  281. package/dist/recall-tag-filter.d.ts +3 -1
  282. package/dist/recall-timings.d.ts +3 -1
  283. package/dist/recall-xray-cli.d.ts +3 -1
  284. package/dist/recall-xray-cli.js +4 -4
  285. package/dist/recall-xray-renderer.d.ts +3 -1
  286. package/dist/recall-xray-renderer.js +3 -3
  287. package/dist/recall-xray.d.ts +3 -1
  288. package/dist/recall-xray.js +2 -2
  289. package/dist/reconcile/cursor.d.ts +3 -1
  290. package/dist/reconcile/manifest.d.ts +3 -1
  291. package/dist/reconcile/plan.d.ts +3 -1
  292. package/dist/replay/normalizers/chatgpt.d.ts +3 -1
  293. package/dist/replay/normalizers/claude.d.ts +3 -1
  294. package/dist/replay/normalizers/openclaw.d.ts +3 -1
  295. package/dist/replay/normalizers/shared.d.ts +3 -1
  296. package/dist/replay/runner.d.ts +3 -1
  297. package/dist/replay/types.d.ts +3 -1
  298. package/dist/replica-divergence.d.ts +3 -1
  299. package/dist/replica-peers-config.d.ts +3 -1
  300. package/dist/{resolution-MFY72STR.js → resolution-4552BNRV.js} +13 -3
  301. package/dist/resolve-auth-token.d.ts +3 -1
  302. package/dist/resume-bundles.js +4 -2
  303. package/dist/retrieval-agents.d.ts +4 -2
  304. package/dist/retrieval-tiers.d.ts +3 -1
  305. package/dist/routing/engine.d.ts +3 -1
  306. package/dist/routing/store.d.ts +3 -1
  307. package/dist/salvage-envelope.d.ts +3 -1
  308. package/dist/schemas.d.ts +44 -44
  309. package/dist/{scope-profiles-B9xMoFO-.d.ts → scope-profiles-DLrRxFWR.d.ts} +1 -1
  310. package/dist/search/embed-helper.d.ts +3 -1
  311. package/dist/search/factory.d.ts +3 -1
  312. package/dist/search/index.d.ts +3 -1
  313. package/dist/search/lancedb-backend.d.ts +3 -1
  314. package/dist/search/meilisearch-backend.d.ts +3 -1
  315. package/dist/search/noop-backend.d.ts +3 -1
  316. package/dist/search/orama-backend.d.ts +3 -1
  317. package/dist/search/port.d.ts +3 -1
  318. package/dist/search/remote-backend.d.ts +3 -1
  319. package/dist/{semantic-TddhF0y7.d.ts → semantic-BalR6EXU.d.ts} +1 -1
  320. package/dist/{semantic-consolidation-C4uykW84.d.ts → semantic-consolidation-DlN6xe20.d.ts} +1 -1
  321. package/dist/semantic-consolidation.d.ts +4 -2
  322. package/dist/semantic-consolidation.js +4 -4
  323. package/dist/semantic-rule-promotion.js +3 -3
  324. package/dist/semantic-rule-verifier.d.ts +3 -1
  325. package/dist/semantic-rule-verifier.js +3 -3
  326. package/dist/{service-DCZDZNcV.d.ts → service-GkYyVfm9.d.ts} +2 -2
  327. package/dist/session-observer-bands.d.ts +3 -1
  328. package/dist/session-observer-state.d.ts +3 -1
  329. package/dist/shared-context/manager.d.ts +3 -1
  330. package/dist/signal.d.ts +3 -1
  331. package/dist/source-agent-qualifier.d.ts +3 -1
  332. package/dist/source-agent-qualifier.js +3 -3
  333. package/dist/{storage-CcKmEjL8.d.ts → storage-BIDzuKIn.d.ts} +1 -1
  334. package/dist/storage.d.ts +4 -2
  335. package/dist/storage.js +2 -2
  336. package/dist/subject-config.d.ts +3 -1
  337. package/dist/summarizer.d.ts +3 -1
  338. package/dist/summary-snapshot.d.ts +3 -1
  339. package/dist/support-passport/index.d.ts +43 -43
  340. package/dist/support-passport/index.js +17 -17
  341. package/dist/temporal-supersession.d.ts +4 -2
  342. package/dist/temporal-timeline-recall.d.ts +3 -1
  343. package/dist/temporal-validity.d.ts +3 -1
  344. package/dist/threading.d.ts +3 -1
  345. package/dist/tier-migration.d.ts +4 -2
  346. package/dist/tier-routing.d.ts +3 -1
  347. package/dist/topics.d.ts +3 -1
  348. package/dist/transcript.d.ts +3 -1
  349. package/dist/transfer/types.d.ts +20 -20
  350. package/dist/trust-score-stage.d.ts +3 -1
  351. package/dist/trust-score.d.ts +3 -1
  352. package/dist/{types-Pi0lfaEt.d.ts → types-BxAcOl5Q.d.ts} +323 -4
  353. package/dist/types.d.ts +3 -1
  354. package/dist/types.js +1 -1
  355. package/dist/utility-runtime.d.ts +3 -1
  356. package/dist/verified-recall.js +3 -3
  357. package/dist/who-knows-cli.d.ts +40 -40
  358. package/dist/who-knows-cli.js +4 -4
  359. package/dist/who-knows.d.ts +42 -42
  360. package/dist/who-knows.js +3 -3
  361. package/dist/write-envelope.d.ts +3 -1
  362. package/package.json +2 -2
  363. package/src/access-boundary.ts +4 -0
  364. package/src/access-http.ts +6 -5
  365. package/src/access-mcp-admin-tools.ts +24 -0
  366. package/src/access-mcp-output-schemas.ts +14 -0
  367. package/src/access-mcp.ts +2 -2
  368. package/src/access-operations-batch.ts +5 -0
  369. package/src/access-service.ts +27 -0
  370. package/src/access-surface-catalog.test.ts +24 -0
  371. package/src/access-surface-catalog.ts +4 -0
  372. package/src/coding/action-gate.test.ts +341 -0
  373. package/src/coding/action-gate.ts +556 -0
  374. package/src/config.ts +5 -0
  375. package/src/contradiction/contradiction-review.ts +50 -4
  376. package/src/contradiction/contradiction-scan.ts +14 -3
  377. package/src/contradiction/resolution.ts +50 -2
  378. package/src/index.ts +4 -3
  379. package/src/orchestration/recall-rerank-coordinator.ts +123 -4
  380. package/src/orchestration/recall-result-formatter.ts +6 -2
  381. package/src/orchestration/recall-search-pipeline.ts +14 -1
  382. package/src/preferences/drift-config.ts +118 -0
  383. package/src/preferences/drift-recall.ts +133 -0
  384. package/src/preferences/drift-types.ts +87 -0
  385. package/src/preferences/index.ts +12 -0
  386. package/src/preferences/preference-drift.test.ts +690 -0
  387. package/src/preferences/preference-drift.ts +724 -0
  388. package/src/review/review-deck-access.test.ts +325 -0
  389. package/src/review/review-deck-http-base.ts +133 -0
  390. package/src/review/review-deck-mutation.test.ts +417 -0
  391. package/src/review/review-deck-mutation.ts +677 -0
  392. package/src/review/review-deck-snapshot.ts +196 -0
  393. package/src/review/review-deck-surface.ts +117 -0
  394. package/src/review/review-deck.test.ts +347 -0
  395. package/src/review/review-deck.ts +311 -0
  396. package/src/storage.ts +4 -6
  397. package/src/types.ts +7 -3
  398. package/dist/chunk-35NN3ZFA.js.map +0 -1
  399. package/dist/chunk-4KYOLI6M.js.map +0 -1
  400. package/dist/chunk-BWLRUMOG.js.map +0 -1
  401. package/dist/chunk-J275IYMG.js.map +0 -1
  402. package/dist/chunk-SB7D4BT7.js.map +0 -1
  403. package/dist/chunk-SBDCZ2AX.js.map +0 -1
  404. package/dist/chunk-TF77C7SV.js.map +0 -1
  405. package/dist/chunk-TZNQUNKL.js.map +0 -1
  406. package/dist/chunk-V3MXUL3D.js.map +0 -1
  407. package/dist/chunk-XCTXS7VY.js +0 -402
  408. package/dist/chunk-XCTXS7VY.js.map +0 -1
  409. package/dist/chunk-YLDXWCZP.js.map +0 -1
  410. /package/dist/{chunk-R7JAM2XF.js.map → chunk-2VXWFYJE.js.map} +0 -0
  411. /package/dist/{chunk-UXO5IMBK.js.map → chunk-4XDGYCZI.js.map} +0 -0
  412. /package/dist/{chunk-OTHZWLUD.js.map → chunk-57HVIG5U.js.map} +0 -0
  413. /package/dist/{chunk-EILZG5VC.js.map → chunk-6TAX66IA.js.map} +0 -0
  414. /package/dist/{chunk-NKKD4ZAU.js.map → chunk-6VALIZKG.js.map} +0 -0
  415. /package/dist/{chunk-2E36UXVW.js.map → chunk-7KFIMGMP.js.map} +0 -0
  416. /package/dist/{chunk-LGO6A7GJ.js.map → chunk-7QOO4LGC.js.map} +0 -0
  417. /package/dist/{chunk-DZUJ46DO.js.map → chunk-AUO2LJ3K.js.map} +0 -0
  418. /package/dist/{chunk-ZO6AXLEH.js.map → chunk-AYDDB3XI.js.map} +0 -0
  419. /package/dist/{chunk-NTWN6HB2.js.map → chunk-AYYGRVRP.js.map} +0 -0
  420. /package/dist/{chunk-7YQ4IYS2.js.map → chunk-AZAA5DNP.js.map} +0 -0
  421. /package/dist/{chunk-Z7PBQPJ4.js.map → chunk-BQUEAVNW.js.map} +0 -0
  422. /package/dist/{chunk-5YQ63T4B.js.map → chunk-D27J626P.js.map} +0 -0
  423. /package/dist/{chunk-LZH5FR2W.js.map → chunk-DHTQP334.js.map} +0 -0
  424. /package/dist/{chunk-Y7DK7HHJ.js.map → chunk-E4MVQQVX.js.map} +0 -0
  425. /package/dist/{chunk-JYYBA7TF.js.map → chunk-EIVIB73I.js.map} +0 -0
  426. /package/dist/{chunk-S2DPMJXH.js.map → chunk-EV3YFLCB.js.map} +0 -0
  427. /package/dist/{chunk-3I7ASZN3.js.map → chunk-G57LQRP6.js.map} +0 -0
  428. /package/dist/{chunk-UIN2BWDD.js.map → chunk-GN55KU2P.js.map} +0 -0
  429. /package/dist/{chunk-PE255F4T.js.map → chunk-GUXS322H.js.map} +0 -0
  430. /package/dist/{chunk-YB42WZCY.js.map → chunk-IQSC3V2E.js.map} +0 -0
  431. /package/dist/{chunk-MN4KB2A4.js.map → chunk-MBDJJTAT.js.map} +0 -0
  432. /package/dist/{chunk-SQI57UCJ.js.map → chunk-MRTUN665.js.map} +0 -0
  433. /package/dist/{chunk-SPUJNJJC.js.map → chunk-NZWEEALH.js.map} +0 -0
  434. /package/dist/{chunk-2XDWWPTN.js.map → chunk-OJD4WS2E.js.map} +0 -0
  435. /package/dist/{chunk-ZWXJBFZU.js.map → chunk-OLWTCWQ2.js.map} +0 -0
  436. /package/dist/{chunk-XRYZRW54.js.map → chunk-P4DHENRE.js.map} +0 -0
  437. /package/dist/{chunk-IID2CMUU.js.map → chunk-PDVQ5JU3.js.map} +0 -0
  438. /package/dist/{chunk-5NM4OH4P.js.map → chunk-QFMO32TO.js.map} +0 -0
  439. /package/dist/{chunk-SIHSCCUQ.js.map → chunk-QXIQPCCN.js.map} +0 -0
  440. /package/dist/{chunk-2YI72KM3.js.map → chunk-R47WINCY.js.map} +0 -0
  441. /package/dist/{chunk-ZQHI2BZB.js.map → chunk-RK4WXUI2.js.map} +0 -0
  442. /package/dist/{chunk-QOS5LBZN.js.map → chunk-S7Q5CM7E.js.map} +0 -0
  443. /package/dist/{chunk-GDFVPUJ5.js.map → chunk-TDKSCV62.js.map} +0 -0
  444. /package/dist/{chunk-OCZIYAE5.js.map → chunk-TYUS5TLG.js.map} +0 -0
  445. /package/dist/{chunk-GNCCUR6K.js.map → chunk-URHCUXKI.js.map} +0 -0
  446. /package/dist/{chunk-CT56C22C.js.map → chunk-Z4RPXHJH.js.map} +0 -0
  447. /package/dist/{contradiction-review-QKJH5DKD.js.map → contradiction-review-WRVLRWHS.js.map} +0 -0
  448. /package/dist/{contradiction-scan-VOTQRRSX.js.map → contradiction-scan-AKUWPX5N.js.map} +0 -0
  449. /package/dist/{resolution-MFY72STR.js.map → resolution-4552BNRV.js.map} +0 -0
@@ -18,7 +18,7 @@ import {
18
18
  computeWhoKnows,
19
19
  loadWhoKnowsEntities,
20
20
  validateWhoKnowsInput
21
- } from "./chunk-SPUJNJJC.js";
21
+ } from "./chunk-NZWEEALH.js";
22
22
  import {
23
23
  WriteQuarantineStore
24
24
  } from "./chunk-PJSK6OJM.js";
@@ -45,13 +45,13 @@ import {
45
45
  } from "./chunk-H7XKCNR6.js";
46
46
  import {
47
47
  toRecallExplainJson
48
- } from "./chunk-7YQ4IYS2.js";
48
+ } from "./chunk-AZAA5DNP.js";
49
49
  import {
50
50
  estimateRecallTokens
51
- } from "./chunk-3I7ASZN3.js";
51
+ } from "./chunk-G57LQRP6.js";
52
52
  import {
53
53
  readAggregateExtractionWatermark
54
- } from "./chunk-PE255F4T.js";
54
+ } from "./chunk-GUXS322H.js";
55
55
  import {
56
56
  ReplicaDivergenceMonitor
57
57
  } from "./chunk-CVILPI77.js";
@@ -117,11 +117,11 @@ import {
117
117
  listMemoryGovernanceRuns,
118
118
  readMemoryGovernanceRunArtifact,
119
119
  runMemoryGovernance
120
- } from "./chunk-JYYBA7TF.js";
120
+ } from "./chunk-EIVIB73I.js";
121
121
  import {
122
122
  CorpusWatermarkCache,
123
123
  computeServiceCorpusCensus
124
- } from "./chunk-XRYZRW54.js";
124
+ } from "./chunk-P4DHENRE.js";
125
125
  import {
126
126
  ExtractionDeadlineError,
127
127
  isActivityDigestPath,
@@ -132,31 +132,27 @@ import {
132
132
  import {
133
133
  defaultCapsulesDir
134
134
  } from "./chunk-ZY2MNJR6.js";
135
- import {
136
- filterTrajectoriesByLookbackDays,
137
- readCausalTrajectoryRecords
138
- } from "./chunk-PP7R754B.js";
139
135
  import {
140
136
  FileCalendarSource,
141
137
  buildBriefing,
142
138
  enqueuePassiveCorrectionNotification,
143
139
  parseBriefingFocus,
144
140
  parseBriefingWindow
145
- } from "./chunk-NTWN6HB2.js";
141
+ } from "./chunk-AYYGRVRP.js";
146
142
  import {
147
143
  parseEntityFile,
148
144
  parseFrontmatter,
149
145
  qmdCollectionPathParts,
150
146
  qmdResultPathCandidates,
151
147
  selfDeps
152
- } from "./chunk-J275IYMG.js";
148
+ } from "./chunk-PAYGC3BD.js";
153
149
  import {
154
150
  namespaceCollectionName
155
151
  } from "./chunk-YHCBJULX.js";
156
152
  import {
157
153
  DEFAULT_RECALL_DISCLOSURE,
158
154
  isRecallDisclosure
159
- } from "./chunk-SBDCZ2AX.js";
155
+ } from "./chunk-NXKJHSDN.js";
160
156
  import {
161
157
  normalizeProjectionPreview,
162
158
  normalizeProjectionTags
@@ -174,11 +170,19 @@ import {
174
170
  parseTagMatch
175
171
  } from "./chunk-BT7NVCML.js";
176
172
  import {
177
- createVersion
173
+ createVersion,
174
+ getVersion,
175
+ revertToVersion
178
176
  } from "./chunk-UFKPQBXH.js";
179
177
  import {
178
+ MEMORY_CORPUS_VERSION_SENTINEL,
180
179
  bumpMemoryCorpusVersionForDir
181
180
  } from "./chunk-XCB6QDL6.js";
181
+ import {
182
+ HistoricalEntityCanonicalIdCache,
183
+ canonicalizeEntityRefFrontmatter,
184
+ repairContentAfterJournalMoveSync
185
+ } from "./chunk-ZVPVTPGI.js";
182
186
  import {
183
187
  supersessionKeysForFact
184
188
  } from "./chunk-5WITETWU.js";
@@ -198,6 +202,10 @@ import {
198
202
  import {
199
203
  isExternalWikiCollectionName
200
204
  } from "./chunk-JV3C2MNQ.js";
205
+ import {
206
+ filterTrajectoriesByLookbackDays,
207
+ readCausalTrajectoryRecords
208
+ } from "./chunk-PP7R754B.js";
201
209
  import {
202
210
  computePromotionCandidates
203
211
  } from "./chunk-RIAM7DND.js";
@@ -399,7 +407,8 @@ import {
399
407
  SecureStoreLockedError
400
408
  } from "./chunk-XQ3HXAQH.js";
401
409
  import {
402
- ALL_CATEGORY_DIRS
410
+ ALL_CATEGORY_DIRS,
411
+ getCategoryDir
403
412
  } from "./chunk-VS2IYZRU.js";
404
413
  import {
405
414
  recordCitationUsage
@@ -409,7 +418,7 @@ import {
409
418
  } from "./chunk-3WCASNQZ.js";
410
419
 
411
420
  // src/access-service.ts
412
- import { createHash as createHash10 } from "crypto";
421
+ import { createHash as createHash13 } from "crypto";
413
422
  import { constants as fsConstants2 } from "fs";
414
423
  import { readdirSync, unlinkSync } from "fs";
415
424
  import { stat as stat3 } from "fs/promises";
@@ -5451,6 +5460,7 @@ var OPERATION_NAMES = [
5451
5460
  "review_list",
5452
5461
  "review_resolve",
5453
5462
  "contradiction_scan_run",
5463
+ "preference_drift_scan",
5454
5464
  "memory_summarize_hourly",
5455
5465
  "conversation_index_update",
5456
5466
  "profiling_report",
@@ -5495,6 +5505,9 @@ var OPERATION_NAMES = [
5495
5505
  "trust_zones_status",
5496
5506
  "trust_zones_records",
5497
5507
  "review_disposition",
5508
+ "review_deck_list",
5509
+ "review_deck_action",
5510
+ "review_deck_undo",
5498
5511
  "trust_zones_promote",
5499
5512
  "trust_zones_demo_seed",
5500
5513
  "citations_observed",
@@ -5572,10 +5585,10 @@ function formatZodIssues(error) {
5572
5585
  const parts = [];
5573
5586
  for (const issue of error.issues) {
5574
5587
  const hasNumeric = issue.path.some((p) => typeof p === "number");
5575
- const path17 = 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)";
5576
5589
  const options = enumOptionsFromIssue(issue);
5577
5590
  const suffix = options ? `. Valid: ${options.join(", ")}` : "";
5578
- parts.push(`${path17}: ${issue.message}${suffix}`);
5591
+ parts.push(`${path20}: ${issue.message}${suffix}`);
5579
5592
  }
5580
5593
  return parts.length > 0 ? `request validation failed: ${parts.join("; ")}` : "request validation failed";
5581
5594
  }
@@ -9151,14 +9164,15 @@ ${snippet}`;
9151
9164
  const withHandle = handle ? `${head.trimEnd()} ${handle}` : head.trimEnd();
9152
9165
  const connectorLabel = renderConnectorLabel(r.sourceConnector);
9153
9166
  const withConnector = connectorLabel ? `${withHandle} [agent: ${connectorLabel}]` : withHandle;
9167
+ const withDrift = r.driftNote ? `${withConnector} ${r.driftNote}` : withConnector;
9154
9168
  if (hedgeMap) {
9155
9169
  const item = trustResultFor(hedgeMap, r);
9156
9170
  if (item) {
9157
9171
  const hedge = renderEpistemicHedge(item.trust);
9158
- if (hedge.length > 0) return `${withConnector} ${hedge}`;
9172
+ if (hedge.length > 0) return `${withDrift} ${hedge}`;
9159
9173
  }
9160
9174
  }
9161
- return withConnector;
9175
+ return withDrift;
9162
9176
  });
9163
9177
  return { heading: `## ${title}`, entries };
9164
9178
  }
@@ -10351,8 +10365,1403 @@ var AccessRecallSurface = class {
10351
10365
  }
10352
10366
  };
10353
10367
 
10368
+ // src/review/review-deck-surface.ts
10369
+ import { createHash as createHash8 } from "crypto";
10370
+
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") {
10375
+ super(message);
10376
+ this.name = "ReviewDeckCursorError";
10377
+ }
10378
+ };
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")}`;
10395
+ }
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
+ };
10418
+ }
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 } : {}
10468
+ };
10469
+ }
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
+ });
10497
+ }
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;
10509
+ }
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();
10519
+ }
10520
+ return fields;
10521
+ }
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);
10525
+ }
10526
+ function nonempty(value) {
10527
+ if (value === void 0) return void 0;
10528
+ return value.trim().length > 0 ? value : void 0;
10529
+ }
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");
10546
+ }
10547
+ return { v: 1, p: record.p, n: record.n, f: record.f, c: record.c, k: record.k };
10548
+ }
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;
10589
+ }
10590
+ }
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
+ }
10600
+ }
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
+
10354
11763
  // src/support-passport/card-service.ts
10355
- import { randomUUID as randomUUID2 } from "crypto";
11764
+ import { randomUUID as randomUUID3 } from "crypto";
10356
11765
 
10357
11766
  // src/support-passport/errors.ts
10358
11767
  var SupportPassportError = class extends Error {
@@ -10542,14 +11951,14 @@ async function completeSupportPassportReplacementPrior(input) {
10542
11951
  }
10543
11952
 
10544
11953
  // src/support-passport/generated-batch.ts
10545
- import path13 from "path";
11954
+ import path16 from "path";
10546
11955
  import { z as z2 } from "zod";
10547
11956
 
10548
11957
  // src/support-passport/private-file.ts
10549
- import { randomUUID } from "crypto";
11958
+ import { randomUUID as randomUUID2 } from "crypto";
10550
11959
  import { constants as fsConstants } from "fs";
10551
11960
  import { lstat as lstat3, mkdir as mkdir3, open, rename as rename2, rm as rm2, stat as stat2 } from "fs/promises";
10552
- import path12 from "path";
11961
+ import path15 from "path";
10553
11962
  var UNSUPPORTED_DIRECTORY_SYNC_ERRORS = /* @__PURE__ */ new Set(["EINVAL", "ENOSYS", "ENOTSUP", "EOPNOTSUPP"]);
10554
11963
  var NON_WRITABLE_ANCESTOR_SYNC_ERRORS = /* @__PURE__ */ new Set(["EROFS", "EPERM", "EACCES"]);
10555
11964
  function assertStableDirectory(before, opened, after, errorMessage) {
@@ -10575,8 +11984,8 @@ function openFlags(...flags) {
10575
11984
  return combined;
10576
11985
  }
10577
11986
  function assertContainedPath(trustedRoot, directory, errorMessage) {
10578
- const relative2 = path12.relative(path12.resolve(trustedRoot), path12.resolve(directory));
10579
- if (relative2 === ".." || relative2.startsWith(`..${path12.sep}`) || path12.isAbsolute(relative2)) {
11987
+ const relative2 = path15.relative(path15.resolve(trustedRoot), path15.resolve(directory));
11988
+ if (relative2 === ".." || relative2.startsWith(`..${path15.sep}`) || path15.isAbsolute(relative2)) {
10580
11989
  throw new Error(errorMessage);
10581
11990
  }
10582
11991
  }
@@ -10609,7 +12018,7 @@ async function syncDirectoryHandle(handle) {
10609
12018
  }
10610
12019
  async function resolvePrivateDirectoryPath(directory, handle, opened, errorMessage, platform = process.platform) {
10611
12020
  const descriptorRoot = requirePrivateFileDescriptorRoot(platform, errorMessage);
10612
- const pinnedPath = path12.join(descriptorRoot, String(handle.fd));
12021
+ const pinnedPath = path15.join(descriptorRoot, String(handle.fd));
10613
12022
  const metadata = await stat2(pinnedPath);
10614
12023
  if (!metadata.isDirectory() || metadata.dev !== opened.dev || metadata.ino !== opened.ino) {
10615
12024
  throw new Error(errorMessage);
@@ -10625,12 +12034,12 @@ function requirePrivateFileDescriptorRoot(platform, errorMessage) {
10625
12034
  throw new Error(errorMessage);
10626
12035
  }
10627
12036
  async function openStableDirectoryFromRoot(trustedRoot, directory, errorMessage, platform = process.platform) {
10628
- const root = path12.resolve(trustedRoot);
10629
- const target = path12.resolve(directory);
12037
+ const root = path15.resolve(trustedRoot);
12038
+ const target = path15.resolve(directory);
10630
12039
  assertContainedPath(root, target, errorMessage);
10631
12040
  requirePrivateFileDescriptorRoot(platform, errorMessage);
10632
- const relative2 = path12.relative(root, target);
10633
- const components = relative2 === "" ? [] : relative2.split(path12.sep);
12041
+ const relative2 = path15.relative(root, target);
12042
+ const components = relative2 === "" ? [] : relative2.split(path15.sep);
10634
12043
  const handles = [];
10635
12044
  let currentPath = root;
10636
12045
  try {
@@ -10638,10 +12047,10 @@ async function openStableDirectoryFromRoot(trustedRoot, directory, errorMessage,
10638
12047
  handles.push(current.handle);
10639
12048
  for (const component of components) {
10640
12049
  const pinnedParent = await resolvePrivateDirectoryPath(currentPath, current.handle, current.opened, errorMessage);
10641
- const child = await openDirectoryNoFollow(path12.join(pinnedParent, component), errorMessage);
12050
+ const child = await openDirectoryNoFollow(path15.join(pinnedParent, component), errorMessage);
10642
12051
  handles.push(child.handle);
10643
12052
  assertStableDirectory(current.before, current.opened, await lstat3(currentPath), errorMessage);
10644
- currentPath = path12.join(currentPath, component);
12053
+ currentPath = path15.join(currentPath, component);
10645
12054
  current = child;
10646
12055
  }
10647
12056
  assertStableDirectory(current.before, current.opened, await lstat3(target), errorMessage);
@@ -10662,12 +12071,12 @@ async function openStableDirectoryFromRoot(trustedRoot, directory, errorMessage,
10662
12071
  }
10663
12072
  }
10664
12073
  async function ensurePrivateDirectoryNoFollow(trustedRoot, directory, errorMessage, syncVerifiedParent = syncDirectoryHandle, hardenExistingChildren = true, platform = process.platform) {
10665
- const root = path12.resolve(trustedRoot);
10666
- const target = path12.resolve(directory);
12074
+ const root = path15.resolve(trustedRoot);
12075
+ const target = path15.resolve(directory);
10667
12076
  assertContainedPath(root, target, errorMessage);
10668
- const relative2 = path12.relative(root, target);
12077
+ const relative2 = path15.relative(root, target);
10669
12078
  requirePrivateFileDescriptorRoot(platform, errorMessage);
10670
- const components = relative2 === "" ? [] : relative2.split(path12.sep);
12079
+ const components = relative2 === "" ? [] : relative2.split(path15.sep);
10671
12080
  const handles = [];
10672
12081
  let currentPath = root;
10673
12082
  try {
@@ -10675,7 +12084,7 @@ async function ensurePrivateDirectoryNoFollow(trustedRoot, directory, errorMessa
10675
12084
  handles.push(current.handle);
10676
12085
  for (const component of components) {
10677
12086
  const pinnedParent = await resolvePrivateDirectoryPath(currentPath, current.handle, current.opened, errorMessage);
10678
- const childPath = path12.join(pinnedParent, component);
12087
+ const childPath = path15.join(pinnedParent, component);
10679
12088
  let created = false;
10680
12089
  try {
10681
12090
  await mkdir3(childPath, { mode: 448 });
@@ -10690,7 +12099,7 @@ async function ensurePrivateDirectoryNoFollow(trustedRoot, directory, errorMessa
10690
12099
  await child.handle.chmod(448);
10691
12100
  }
10692
12101
  assertStableDirectory(current.before, current.opened, await lstat3(currentPath), errorMessage);
10693
- currentPath = path12.join(currentPath, component);
12102
+ currentPath = path15.join(currentPath, component);
10694
12103
  current = child;
10695
12104
  }
10696
12105
  assertStableDirectory(current.before, current.opened, await lstat3(target), errorMessage);
@@ -10699,8 +12108,8 @@ async function ensurePrivateDirectoryNoFollow(trustedRoot, directory, errorMessa
10699
12108
  }
10700
12109
  }
10701
12110
  async function ensurePrivateDirectoryTreeNoFollow(directory, errorMessage, syncVerifiedParent = syncDirectoryHandle, platform = process.platform) {
10702
- const target = path12.resolve(directory);
10703
- const filesystemRoot = path12.parse(target).root;
12111
+ const target = path15.resolve(directory);
12112
+ const filesystemRoot = path15.parse(target).root;
10704
12113
  const rootMetadata = await stat2(filesystemRoot);
10705
12114
  await ensurePrivateDirectoryNoFollow(
10706
12115
  filesystemRoot,
@@ -10735,15 +12144,15 @@ async function withPrivateDirectoryNoFollow(trustedRoot, directory, errorMessage
10735
12144
  }
10736
12145
  }
10737
12146
  async function readPrivateFileNoFollow(directory, filePath, errorMessage, trustedRoot = directory, platform = process.platform) {
10738
- if (path12.dirname(filePath) !== path12.resolve(directory)) throw new Error(errorMessage);
10739
- const targetName = path12.basename(filePath);
12147
+ if (path15.dirname(filePath) !== path15.resolve(directory)) throw new Error(errorMessage);
12148
+ const targetName = path15.basename(filePath);
10740
12149
  let directoryHandles = [];
10741
12150
  let fileHandle;
10742
12151
  try {
10743
12152
  const stableDirectory = await openStableDirectoryFromRoot(trustedRoot, directory, errorMessage, platform);
10744
12153
  directoryHandles = stableDirectory.handles;
10745
12154
  const pinnedDirectory = stableDirectory.pinnedDirectory;
10746
- const targetPath = path12.join(pinnedDirectory, targetName);
12155
+ const targetPath = path15.join(pinnedDirectory, targetName);
10747
12156
  const before = await lstat3(targetPath);
10748
12157
  if (before.isSymbolicLink() || !before.isFile()) throw new Error(errorMessage);
10749
12158
  try {
@@ -10762,10 +12171,10 @@ async function readPrivateFileNoFollow(directory, filePath, errorMessage, truste
10762
12171
  }
10763
12172
  }
10764
12173
  async function appendPrivateFileAtPinnedDirectory(pinnedDirectory, targetName, content, errorMessage, directoryHandle, openFile) {
10765
- if (targetName.length === 0 || targetName === "." || targetName === ".." || path12.basename(targetName) !== targetName) {
12174
+ if (targetName.length === 0 || targetName === "." || targetName === ".." || path15.basename(targetName) !== targetName) {
10766
12175
  throw new Error(errorMessage);
10767
12176
  }
10768
- const targetPath = path12.join(pinnedDirectory, targetName);
12177
+ const targetPath = path15.join(pinnedDirectory, targetName);
10769
12178
  let fileHandle;
10770
12179
  try {
10771
12180
  try {
@@ -10801,8 +12210,8 @@ async function appendPrivateFileAtPinnedDirectory(pinnedDirectory, targetName, c
10801
12210
  }
10802
12211
  async function appendPrivateFileInPinnedDirectory(pinnedDirectory, fileName, content, errorMessage, platform = process.platform) {
10803
12212
  const descriptorRoot = requirePrivateFileDescriptorRoot(platform, errorMessage);
10804
- const resolvedDirectory = path12.resolve(pinnedDirectory);
10805
- const descriptor = path12.relative(descriptorRoot, resolvedDirectory);
12213
+ const resolvedDirectory = path15.resolve(pinnedDirectory);
12214
+ const descriptor = path15.relative(descriptorRoot, resolvedDirectory);
10806
12215
  if (!/^\d+$/.test(descriptor)) throw new Error(errorMessage);
10807
12216
  const before = await stat2(resolvedDirectory);
10808
12217
  if (!before.isDirectory()) throw new Error(errorMessage);
@@ -10818,9 +12227,9 @@ async function appendPrivateFileInPinnedDirectory(pinnedDirectory, fileName, con
10818
12227
  }
10819
12228
  }
10820
12229
  async function writePrivateFileAtomicallyNoFollow(directory, filePath, content, errorMessage, trustedRoot = directory, platform = process.platform, syncVerifiedDirectory = syncDirectoryHandle) {
10821
- if (path12.dirname(filePath) !== path12.resolve(directory)) throw new Error(errorMessage);
10822
- const targetName = path12.basename(filePath);
10823
- 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`;
10824
12233
  let tempPath;
10825
12234
  let directoryHandles = [];
10826
12235
  let fileHandle;
@@ -10828,8 +12237,8 @@ async function writePrivateFileAtomicallyNoFollow(directory, filePath, content,
10828
12237
  const stableDirectory = await openStableDirectoryFromRoot(trustedRoot, directory, errorMessage, platform);
10829
12238
  directoryHandles = stableDirectory.handles;
10830
12239
  const pinnedDirectory = stableDirectory.pinnedDirectory;
10831
- tempPath = path12.join(pinnedDirectory, tempName);
10832
- const targetPath = path12.join(pinnedDirectory, targetName);
12240
+ tempPath = path15.join(pinnedDirectory, tempName);
12241
+ const targetPath = path15.join(pinnedDirectory, targetName);
10833
12242
  try {
10834
12243
  fileHandle = await open(
10835
12244
  tempPath,
@@ -10866,7 +12275,7 @@ async function writePrivateFileAtomicallyNoFollow(directory, filePath, content,
10866
12275
  }
10867
12276
  async function removePrivateFilesNoFollow(directory, fileNames, errorMessage, trustedRoot = directory, platform = process.platform) {
10868
12277
  if (fileNames.some(
10869
- (fileName) => fileName.length === 0 || fileName === "." || fileName === ".." || path12.basename(fileName) !== fileName
12278
+ (fileName) => fileName.length === 0 || fileName === "." || fileName === ".." || path15.basename(fileName) !== fileName
10870
12279
  )) {
10871
12280
  throw new Error(errorMessage);
10872
12281
  }
@@ -10876,7 +12285,7 @@ async function removePrivateFilesNoFollow(directory, fileNames, errorMessage, tr
10876
12285
  directoryHandles = stableDirectory.handles;
10877
12286
  const pinnedDirectory = stableDirectory.pinnedDirectory;
10878
12287
  for (const fileName of fileNames) {
10879
- await rm2(path12.join(pinnedDirectory, fileName), { force: true });
12288
+ await rm2(path15.join(pinnedDirectory, fileName), { force: true });
10880
12289
  }
10881
12290
  assertStableDirectory(stableDirectory.before, stableDirectory.opened, await lstat3(directory), errorMessage);
10882
12291
  if (stableDirectory.handle) await syncDirectoryHandle(stableDirectory.handle);
@@ -10897,13 +12306,13 @@ var GeneratedBatchMarkerSchema = z2.object({
10897
12306
  }).strict();
10898
12307
  var BATCH_ERROR = "The generated draft batch state is not safe.";
10899
12308
  function batchDirectory(storage) {
10900
- return path13.join(storage.dir, "state", "support-passport", "generated-batches");
12309
+ return path16.join(storage.dir, "state", "support-passport", "generated-batches");
10901
12310
  }
10902
12311
  function batchFileName(batchId) {
10903
12312
  return `${BatchIdSchema.parse(batchId)}.json`;
10904
12313
  }
10905
12314
  function batchPath(storage, batchId) {
10906
- return path13.join(batchDirectory(storage), batchFileName(batchId));
12315
+ return path16.join(batchDirectory(storage), batchFileName(batchId));
10907
12316
  }
10908
12317
  function markerFor(context, batchId, size, complete) {
10909
12318
  return GeneratedBatchMarkerSchema.parse({
@@ -11327,19 +12736,19 @@ var SupportPassportAnswerModelInputSchema = z4.object({
11327
12736
  }).strict();
11328
12737
 
11329
12738
  // src/support-passport/owner-lock.ts
11330
- import { createHash as createHash6 } from "crypto";
11331
- import path14 from "path";
12739
+ import { createHash as createHash9 } from "crypto";
12740
+ import path17 from "path";
11332
12741
  var CARD_MUTATION_LOCK_STALE_MS = 6e4;
11333
12742
  var CARD_MUTATION_LOCK_MAX_WAIT_MS = 3e4;
11334
12743
  function computeSupportPassportOwnerLockKey(namespace, principal) {
11335
- return createHash6("sha256").update(JSON.stringify([namespace, principal])).digest("hex");
12744
+ return createHash9("sha256").update(JSON.stringify([namespace, principal])).digest("hex");
11336
12745
  }
11337
12746
  function supportPassportOwnerLockPath(storage, scope) {
11338
12747
  const ownerLockKey = scope.ownerKey ?? computeSupportPassportOwnerLockKey(scope.namespace, scope.principal);
11339
12748
  if (!/^[a-f0-9]{64}$/.test(ownerLockKey)) {
11340
12749
  throw new SupportPassportError("card_data_invalid", "The support passport owner scope is invalid.", 500);
11341
12750
  }
11342
- return path14.join(storage.dir, "state", `support-passport-cards-${ownerLockKey}.lock`);
12751
+ return path17.join(storage.dir, "state", `support-passport-cards-${ownerLockKey}.lock`);
11343
12752
  }
11344
12753
  async function withSupportPassportOwnerLock(storage, scope, task) {
11345
12754
  const lockPath = supportPassportOwnerLockPath(storage, scope);
@@ -11447,7 +12856,7 @@ var SupportPassportCardService = class {
11447
12856
  const onCommitted = once(input.onCommitted);
11448
12857
  return await withSupportPassportOwnerLock(storage, { namespace, principal }, async (lock) => {
11449
12858
  const batchContext = this.generatedBatchContext(storage, lock, principal, namespace, onCommitted);
11450
- const batchId = randomUUID2();
12859
+ const batchId = randomUUID3();
11451
12860
  const created = [];
11452
12861
  const createdIds = [];
11453
12862
  const createdRecords = [];
@@ -12235,9 +13644,9 @@ var SupportPassportCardService = class {
12235
13644
  };
12236
13645
 
12237
13646
  // src/support-passport/grant-store.ts
12238
- import { createHash as createHash7, randomBytes, randomUUID as randomUUID3, timingSafeEqual } from "crypto";
13647
+ import { createHash as createHash10, randomBytes, randomUUID as randomUUID4, timingSafeEqual } from "crypto";
12239
13648
  import { lstat as lstat4, open as open2, readdir as readdir4 } from "fs/promises";
12240
- import path15 from "path";
13649
+ import path18 from "path";
12241
13650
  var GRANT_LOCK_STALE_MS = 3e4;
12242
13651
  var GRANT_LOCK_WAIT_MS = 5e3;
12243
13652
  var GRANT_LOCK_HEARTBEAT_MS = 1e4;
@@ -12260,7 +13669,7 @@ var MalformedGrantStateError = class extends Error {
12260
13669
  }
12261
13670
  };
12262
13671
  function sha256(domain, value) {
12263
- return createHash7("sha256").update(domain).update("\0").update(value).digest("hex");
13672
+ return createHash10("sha256").update(domain).update("\0").update(value).digest("hex");
12264
13673
  }
12265
13674
  function hashesMatch(left, right) {
12266
13675
  const leftBytes = Buffer.from(left, "hex");
@@ -12329,12 +13738,12 @@ var SupportPassportGrantStore = class {
12329
13738
  runWithHeldFileLock;
12330
13739
  syncDirectory;
12331
13740
  constructor(options) {
12332
- this.memoryDir = path15.resolve(expandTildePath(options.memoryDir));
12333
- this.grantsDir = path15.join(this.memoryDir, "state", "support-passport", "grants");
12334
- this.ownerIndexesDir = path15.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");
12335
13744
  this.now = options.now ?? (() => /* @__PURE__ */ new Date());
12336
13745
  this.makeSecret = options.makeSecret ?? (() => randomBytes(32));
12337
- this.makeGrantId = options.makeGrantId ?? randomUUID3;
13746
+ this.makeGrantId = options.makeGrantId ?? randomUUID4;
12338
13747
  this.runWithHeldFileLock = options.withHeldFileLock ?? withHeldFileLock;
12339
13748
  this.syncDirectory = options.syncDirectory ?? syncDirectoryForDurability;
12340
13749
  }
@@ -12544,11 +13953,11 @@ var SupportPassportGrantStore = class {
12544
13953
  }
12545
13954
  filePath(grantId) {
12546
13955
  const normalizedGrantId = normalizeGrantId(grantId);
12547
- return path15.join(this.grantsDir, `${normalizedGrantId}.json`);
13956
+ return path18.join(this.grantsDir, `${normalizedGrantId}.json`);
12548
13957
  }
12549
13958
  ownerIndexPath(ownerHash) {
12550
13959
  if (!SAFE_OWNER_INDEX_HASH.test(ownerHash)) throw new Error("support passport owner index hash is invalid");
12551
- return path15.join(this.ownerIndexesDir, `${ownerHash}.json`);
13960
+ return path18.join(this.ownerIndexesDir, `${ownerHash}.json`);
12552
13961
  }
12553
13962
  ownerHash(namespace, principalHash) {
12554
13963
  return sha256("support-passport-owner-index:v1", `${namespace}\0${principalHash}`);
@@ -12604,12 +14013,12 @@ var SupportPassportGrantStore = class {
12604
14013
  this.grantsDir,
12605
14014
  grantIds.map((grantId) => `${grantId}.json`),
12606
14015
  "support passport grant files must be regular files in a stable directory",
12607
- path15.parse(this.memoryDir).root
14016
+ path18.parse(this.memoryDir).root
12608
14017
  );
12609
14018
  }
12610
14019
  ownerMembershipDirectory(ownerHash) {
12611
14020
  if (!SAFE_OWNER_INDEX_HASH.test(ownerHash)) throw new Error("support passport owner index hash is invalid");
12612
- return path15.join(this.ownerIndexesDir, ownerHash);
14021
+ return path18.join(this.ownerIndexesDir, ownerHash);
12613
14022
  }
12614
14023
  async ensureOwnerMembershipDirectory(ownerHash) {
12615
14024
  const directory = this.ownerMembershipDirectory(ownerHash);
@@ -12624,11 +14033,11 @@ var SupportPassportGrantStore = class {
12624
14033
  const directory = await this.ensureOwnerMembershipDirectory(ownerHash);
12625
14034
  await writePrivateFileAtomicallyNoFollow(
12626
14035
  directory,
12627
- path15.join(directory, `${state.grantId}.json`),
14036
+ path18.join(directory, `${state.grantId}.json`),
12628
14037
  `${JSON.stringify({ schemaVersion: 1, grantId: state.grantId })}
12629
14038
  `,
12630
14039
  "support passport owner membership must be regular files in a stable directory",
12631
- path15.parse(this.memoryDir).root
14040
+ path18.parse(this.memoryDir).root
12632
14041
  );
12633
14042
  }
12634
14043
  async removeOwnerMembership(state) {
@@ -12638,7 +14047,7 @@ var SupportPassportGrantStore = class {
12638
14047
  directory,
12639
14048
  [`${state.grantId}.json`],
12640
14049
  "support passport owner membership must be regular files in a stable directory",
12641
- path15.parse(this.memoryDir).root
14050
+ path18.parse(this.memoryDir).root
12642
14051
  );
12643
14052
  }
12644
14053
  async removeStoredGrant(state) {
@@ -12739,7 +14148,7 @@ var SupportPassportGrantStore = class {
12739
14148
  const ownerHash = this.ownerHash(namespace, principalHash);
12740
14149
  const directory = await this.ensureOwnerMembershipDirectory(ownerHash);
12741
14150
  const grantIds = await withPrivateDirectoryNoFollow(
12742
- path15.parse(this.memoryDir).root,
14151
+ path18.parse(this.memoryDir).root,
12743
14152
  directory,
12744
14153
  "support passport owner membership must be regular files in a stable directory",
12745
14154
  async (pinnedDirectory) => {
@@ -12770,7 +14179,7 @@ var SupportPassportGrantStore = class {
12770
14179
  this.ownerIndexesDir,
12771
14180
  filePath,
12772
14181
  "support passport owner indexes must be regular files in a stable directory",
12773
- path15.parse(this.memoryDir).root
14182
+ path18.parse(this.memoryDir).root
12774
14183
  );
12775
14184
  } catch (error) {
12776
14185
  if (error.code === "ENOENT") return [];
@@ -12810,7 +14219,7 @@ var SupportPassportGrantStore = class {
12810
14219
  `${JSON.stringify({ schemaVersion: 1, ownerHash, grantIds }, null, 2)}
12811
14220
  `,
12812
14221
  "support passport owner indexes must be regular files in a stable directory",
12813
- path15.parse(this.memoryDir).root
14222
+ path18.parse(this.memoryDir).root
12814
14223
  );
12815
14224
  }
12816
14225
  async readState(grantId) {
@@ -12820,7 +14229,7 @@ var SupportPassportGrantStore = class {
12820
14229
  this.grantsDir,
12821
14230
  filePath,
12822
14231
  "support passport grant files must be regular files in a stable directory",
12823
- path15.parse(this.memoryDir).root
14232
+ path18.parse(this.memoryDir).root
12824
14233
  );
12825
14234
  try {
12826
14235
  const state = SupportPassportGrantStateSchema.parse(JSON.parse(content));
@@ -12854,7 +14263,7 @@ var SupportPassportGrantStore = class {
12854
14263
  `${JSON.stringify(state, null, 2)}
12855
14264
  `,
12856
14265
  "support passport grant files must be regular files in a stable directory",
12857
- path15.parse(this.memoryDir).root
14266
+ path18.parse(this.memoryDir).root
12858
14267
  );
12859
14268
  }
12860
14269
  async ensureSafeDirectories() {
@@ -12888,8 +14297,8 @@ var SupportPassportGrantStore = class {
12888
14297
  void 0
12889
14298
  );
12890
14299
  this.memoryDir = configuredMemoryDir;
12891
- this.grantsDir = path15.join(configuredMemoryDir, "state", "support-passport", "grants");
12892
- this.ownerIndexesDir = path15.join(this.grantsDir, "owners");
14300
+ this.grantsDir = path18.join(configuredMemoryDir, "state", "support-passport", "grants");
14301
+ this.ownerIndexesDir = path18.join(this.grantsDir, "owners");
12893
14302
  })();
12894
14303
  }
12895
14304
  const currentAttempt = this.memoryRootReady;
@@ -12903,12 +14312,12 @@ var SupportPassportGrantStore = class {
12903
14312
  async withMutationLock(task) {
12904
14313
  await this.ensureSafeDirectories();
12905
14314
  return await withPrivateDirectoryNoFollow(
12906
- path15.parse(this.memoryDir).root,
14315
+ path18.parse(this.memoryDir).root,
12907
14316
  this.grantsDir,
12908
14317
  "support passport grant lock directory must remain inside the memory directory",
12909
14318
  async (pinnedDirectory) => await this.withExclusiveLock(
12910
14319
  `support-passport-grants:${this.grantsDir}`,
12911
- path15.join(pinnedDirectory, ".grants.lock"),
14320
+ path18.join(pinnedDirectory, ".grants.lock"),
12912
14321
  task
12913
14322
  )
12914
14323
  );
@@ -12917,12 +14326,12 @@ var SupportPassportGrantStore = class {
12917
14326
  const normalizedGrantId = normalizeGrantId(grantId);
12918
14327
  await this.ensureSafeDirectories();
12919
14328
  return await withPrivateDirectoryNoFollow(
12920
- path15.parse(this.memoryDir).root,
14329
+ path18.parse(this.memoryDir).root,
12921
14330
  this.grantsDir,
12922
14331
  "support passport grant lock directory must remain inside the memory directory",
12923
14332
  async (pinnedDirectory) => await this.withExclusiveLock(
12924
14333
  `support-passport-grant:${this.grantsDir}:${normalizedGrantId}`,
12925
- path15.join(pinnedDirectory, `.${normalizedGrantId}.lock`),
14334
+ path18.join(pinnedDirectory, `.${normalizedGrantId}.lock`),
12926
14335
  task
12927
14336
  )
12928
14337
  );
@@ -12930,12 +14339,12 @@ var SupportPassportGrantStore = class {
12930
14339
  async withOwnerIndexLock(ownerHash, task) {
12931
14340
  await this.ensureSafeDirectories();
12932
14341
  return await withPrivateDirectoryNoFollow(
12933
- path15.parse(this.memoryDir).root,
14342
+ path18.parse(this.memoryDir).root,
12934
14343
  this.ownerIndexesDir,
12935
14344
  "support passport owner lock directory must remain inside the memory directory",
12936
14345
  async (pinnedDirectory) => await this.withExclusiveLock(
12937
14346
  `support-passport-owner:${this.ownerIndexesDir}:${ownerHash}`,
12938
- path15.join(pinnedDirectory, `.${ownerHash}.lock`),
14347
+ path18.join(pinnedDirectory, `.${ownerHash}.lock`),
12939
14348
  task
12940
14349
  )
12941
14350
  );
@@ -13772,8 +15181,8 @@ var SupportPassportModelAdapter = class {
13772
15181
  };
13773
15182
 
13774
15183
  // src/support-passport/model-audit.ts
13775
- import { createHash as createHash8 } from "crypto";
13776
- import path16 from "path";
15184
+ import { createHash as createHash11 } from "crypto";
15185
+ import path19 from "path";
13777
15186
  import { z as z5 } from "zod";
13778
15187
  var HashSchema = z5.string().regex(/^[a-f0-9]{64}$/);
13779
15188
  var SupportPassportModelAuditRecordSchema = z5.object({
@@ -13810,7 +15219,7 @@ var SupportPassportModelAuditRecordSchema = z5.object({
13810
15219
  }
13811
15220
  });
13812
15221
  function hashSupportPassportAuditValues(domain, values) {
13813
- 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");
13814
15223
  }
13815
15224
  var SupportPassportModelAuditStore = class {
13816
15225
  memoryDir;
@@ -13818,15 +15227,15 @@ var SupportPassportModelAuditStore = class {
13818
15227
  memoryRootReady;
13819
15228
  runWithHeldFileLock;
13820
15229
  constructor(options) {
13821
- this.memoryDir = path16.resolve(expandTildePath(options.memoryDir));
13822
- this.auditDir = path16.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");
13823
15232
  this.runWithHeldFileLock = options.withHeldFileLock ?? withHeldFileLock;
13824
15233
  }
13825
15234
  async record(input) {
13826
15235
  const record = SupportPassportModelAuditRecordSchema.parse(input);
13827
15236
  await this.ensureSafeDirectories();
13828
15237
  const day = record.occurredAt.slice(0, 10);
13829
- const filePath = path16.join(this.auditDir, `${day}.jsonl`);
15238
+ const filePath = path19.join(this.auditDir, `${day}.jsonl`);
13830
15239
  await serializeMutations(
13831
15240
  `support-passport-audit:${filePath}`,
13832
15241
  () => withPrivateDirectoryNoFollow(
@@ -13834,7 +15243,7 @@ var SupportPassportModelAuditStore = class {
13834
15243
  this.auditDir,
13835
15244
  "support passport audit directory must remain inside the memory directory",
13836
15245
  async (pinnedDirectory) => await this.runWithHeldFileLock(
13837
- path16.join(pinnedDirectory, `.${day}.lock`),
15246
+ path19.join(pinnedDirectory, `.${day}.lock`),
13838
15247
  {
13839
15248
  staleMs: 3e4,
13840
15249
  maxWaitMs: 5e3,
@@ -13871,7 +15280,7 @@ var SupportPassportModelAuditStore = class {
13871
15280
  "support passport memory directory must be a stable directory"
13872
15281
  );
13873
15282
  this.memoryDir = configuredMemoryDir;
13874
- this.auditDir = path16.join(configuredMemoryDir, "state", "support-passport", "audit");
15283
+ this.auditDir = path19.join(configuredMemoryDir, "state", "support-passport", "audit");
13875
15284
  })();
13876
15285
  }
13877
15286
  const currentAttempt = this.memoryRootReady;
@@ -13885,7 +15294,7 @@ var SupportPassportModelAuditStore = class {
13885
15294
  };
13886
15295
 
13887
15296
  // src/support-passport/model-service.ts
13888
- import { createHash as createHash9 } from "crypto";
15297
+ import { createHash as createHash12 } from "crypto";
13889
15298
  import { z as z6 } from "zod";
13890
15299
  var DraftServiceInputSchema = z6.object({
13891
15300
  principal: z6.string().trim().min(1).max(512),
@@ -13921,7 +15330,7 @@ function supportPassportSourceContent(memory) {
13921
15330
  return hasStructuredAttributes(memory.frontmatter.structuredAttributes) ? stripAttributesSuffix(memory.content) : memory.content;
13922
15331
  }
13923
15332
  function computeSupportPassportSourceRevision(content, structuredAttributes) {
13924
- 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");
13925
15334
  }
13926
15335
  function isSupportPassportSourceEligible(memory) {
13927
15336
  const status = memory.frontmatter.status ?? "active";
@@ -14557,6 +15966,7 @@ var EngramAccessService = class extends SupportPassportAccessServiceBase {
14557
15966
  this.idempotency = new AccessIdempotencyStore(orchestrator.config.memoryDir);
14558
15967
  this.replicaDivergenceMonitor = new ReplicaDivergenceMonitor({ resolveSecretRef: options.resolveSecretRef });
14559
15968
  this.injectedSupportPassportGatewayRoute = options.supportPassportGatewayRoute ?? null;
15969
+ this.reviewDeckEnabled = options.reviewDeckEnabled === true;
14560
15970
  const accessCaps = resolveAccessSetupCapabilities(orchestrator.config);
14561
15971
  this.budget = new CrossNamespaceBudget({
14562
15972
  enabled: accessCaps.recallCrossNamespaceBudget,
@@ -14596,6 +16006,7 @@ var EngramAccessService = class extends SupportPassportAccessServiceBase {
14596
16006
  corpusWatermarkCache = new CorpusWatermarkCache();
14597
16007
  replicaDivergenceMonitor;
14598
16008
  injectedSupportPassportGatewayRoute;
16009
+ reviewDeckEnabled;
14599
16010
  /** AccessObserveWriteSurface (access-service decomposition). Lazy; selfDeps live wiring. */
14600
16011
  _accessObserveWriteSurface;
14601
16012
  get accessObserveWriteSurface() {
@@ -14624,6 +16035,15 @@ var EngramAccessService = class extends SupportPassportAccessServiceBase {
14624
16035
  }
14625
16036
  return this._accessAdminOpsSurface;
14626
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
+ }
14627
16047
  /** AccessRecallSurface (access-service decomposition). Lazy; selfDeps live wiring. */
14628
16048
  _accessRecallSurface;
14629
16049
  get accessRecallSurface() {
@@ -17407,8 +18827,8 @@ var EngramAccessService = class extends SupportPassportAccessServiceBase {
17407
18827
  async offlineSyncSnapshot(options = {}) {
17408
18828
  const resolvedNamespace = this.resolveReadableNamespace(options.namespace, options.principal);
17409
18829
  const storage = await offlineSyncStorageForSnapshot(this.orchestrator, resolvedNamespace);
17410
- const storageHash = createHash10("sha256").update(storage.dir).digest("hex").slice(0, 16);
17411
- const deletions = [...await storage.readDeletionRevisions()].map(([path17, mtimeMs]) => ({ path: path17, 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 }));
17412
18832
  const snapshotBuilder = options.includeContent === false && options.baseFiles && options.baseFiles.length > 0 ? buildOfflineSyncSnapshotFromBase : buildOfflineSyncSnapshot;
17413
18833
  const snapshot = await snapshotBuilder({
17414
18834
  root: storage.dir,
@@ -17431,10 +18851,10 @@ var EngramAccessService = class extends SupportPassportAccessServiceBase {
17431
18851
  async offlineSyncSnapshotStream(options = {}) {
17432
18852
  const resolvedNamespace = this.resolveReadableNamespace(options.namespace, options.principal);
17433
18853
  const storage = await offlineSyncStorageForSnapshot(this.orchestrator, resolvedNamespace);
17434
- 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);
17435
18855
  const deletions = await filterOfflineSyncDeletionRevisions({
17436
18856
  root: storage.dir,
17437
- deletions: [...await storage.readDeletionRevisions()].map(([path17, mtimeMs]) => ({ path: path17, mtimeMs })),
18857
+ deletions: [...await storage.readDeletionRevisions()].map(([path20, mtimeMs]) => ({ path: path20, mtimeMs })),
17438
18858
  includeTranscripts: options.includeTranscripts !== false,
17439
18859
  userExcludeRegexps: this.offlineSyncUserExcludes
17440
18860
  });
@@ -17471,7 +18891,7 @@ var EngramAccessService = class extends SupportPassportAccessServiceBase {
17471
18891
  async offlineSyncFiles(options) {
17472
18892
  const resolvedNamespace = this.resolveReadableNamespace(options.namespace, options.principal);
17473
18893
  const storage = await offlineSyncStorageForSnapshot(this.orchestrator, resolvedNamespace);
17474
- 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);
17475
18895
  try {
17476
18896
  const snapshot = await buildOfflineSyncSnapshotForPaths({
17477
18897
  root: storage.dir,
@@ -17710,6 +19130,15 @@ var EngramAccessService = class extends SupportPassportAccessServiceBase {
17710
19130
  async adminPromoteMemory(request) {
17711
19131
  return this.accessAdminOpsSurface.adminPromoteMemory(request);
17712
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
+ }
17713
19142
  };
17714
19143
 
17715
19144
  // src/access-recall-concurrency.ts
@@ -18081,6 +19510,17 @@ export {
18081
19510
  RecallResultFormatter,
18082
19511
  assembleRecallResponse,
18083
19512
  AccessRecallSurface,
19513
+ ReviewDeckCursorError,
19514
+ computeReviewItemRevision,
19515
+ projectReviewDeckItem,
19516
+ compareReviewDeckRows,
19517
+ encodeReviewDeckCursor,
19518
+ decodeReviewDeckCursor,
19519
+ buildReviewDeckPage,
19520
+ listReviewItems,
19521
+ performReview,
19522
+ readReviewDeckSnapshot,
19523
+ readReviewDeckRow,
18084
19524
  SupportPassportError,
18085
19525
  SupportPassportGrantCardRefSchema,
18086
19526
  SupportPassportGrantStateSchema,
@@ -18127,4 +19567,4 @@ export {
18127
19567
  EngramAccessService,
18128
19568
  AccessAdminOpsSurface
18129
19569
  };
18130
- //# sourceMappingURL=chunk-SB7D4BT7.js.map
19570
+ //# sourceMappingURL=chunk-WN5FSGLE.js.map