@remnic/core 9.54.5 → 9.54.7

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 (548) hide show
  1. package/dist/access-admin-ops-surface.d.ts +24 -24
  2. package/dist/access-admin-ops-surface.js +32 -29
  3. package/dist/access-authorization-probe.d.ts +25 -23
  4. package/dist/access-authorization-probe.js +35 -30
  5. package/dist/access-boundary.d.ts +26 -24
  6. package/dist/access-boundary.js +36 -31
  7. package/dist/access-cli.js +86 -80
  8. package/dist/access-cli.js.map +1 -1
  9. package/dist/access-coding-context-resolution.d.ts +1 -1
  10. package/dist/access-extraction-force-flush.d.ts +19 -19
  11. package/dist/access-extraction-force-flush.js +32 -29
  12. package/dist/access-health-types.d.ts +1 -1
  13. package/dist/access-http-lcm-compaction.d.ts +22 -22
  14. package/dist/access-http-lifecycle-flush.d.ts +22 -22
  15. package/dist/access-http-offline-stream.d.ts +18 -18
  16. package/dist/access-http-query.js +32 -29
  17. package/dist/access-http.d.ts +55 -37
  18. package/dist/access-http.js +52 -43
  19. package/dist/access-identity-continuity-surface.d.ts +9 -9
  20. package/dist/access-identity-continuity-surface.js +32 -29
  21. package/dist/access-lcm-surface.d.ts +21 -21
  22. package/dist/access-lcm-surface.js +32 -29
  23. package/dist/access-mcp.d.ts +22 -22
  24. package/dist/access-mcp.js +40 -36
  25. package/dist/access-memory-search-fanout.d.ts +2 -2
  26. package/dist/{access-namespace-preflight-BdHlGd_T.d.ts → access-namespace-preflight-CCNn_6NE.d.ts} +1 -1
  27. package/dist/access-namespace-preflight.d.ts +3 -3
  28. package/dist/access-namespace-preflight.js +32 -29
  29. package/dist/access-observe-write-surface.d.ts +22 -22
  30. package/dist/access-observe-write-surface.js +32 -29
  31. package/dist/access-offline-manifest.d.ts +9 -9
  32. package/dist/access-offline-manifest.js +2 -2
  33. package/dist/access-operations-batch.js +34 -31
  34. package/dist/access-operations.d.ts +23 -23
  35. package/dist/access-operations.js +38 -34
  36. package/dist/access-recall-concurrency.d.ts +21 -21
  37. package/dist/access-recall-concurrency.js +32 -29
  38. package/dist/access-recall-response.d.ts +19 -19
  39. package/dist/access-recall-response.js +32 -29
  40. package/dist/access-recall-surface.d.ts +19 -19
  41. package/dist/access-recall-surface.js +32 -29
  42. package/dist/access-schema.js +3 -3
  43. package/dist/{access-service-DL7X9hrg.d.ts → access-service-DK82xdNi.d.ts} +1314 -83
  44. package/dist/access-service-helpers.d.ts +22 -22
  45. package/dist/access-service.d.ts +31 -31
  46. package/dist/access-service.js +32 -29
  47. package/dist/access-surface-catalog.d.ts +22 -22
  48. package/dist/access-surface-catalog.js +209 -2
  49. package/dist/access-surface-catalog.js.map +1 -1
  50. package/dist/access-wearables-meetings-surface.d.ts +3 -3
  51. package/dist/action-confidence.d.ts +1 -1
  52. package/dist/active-memory-bridge.d.ts +6 -5
  53. package/dist/active-memory-bridge.js +2 -2
  54. package/dist/active-recall.d.ts +1 -1
  55. package/dist/active-recall.js +2 -1
  56. package/dist/active-recall.js.map +1 -1
  57. package/dist/adapters/index.js +4 -4
  58. package/dist/adapters/registry.js +2 -2
  59. package/dist/admin-console/public/what-helps-me/app.js +1594 -0
  60. package/dist/admin-console/public/what-helps-me/index.html +339 -0
  61. package/dist/admin-console/public/what-helps-me/model.js +685 -0
  62. package/dist/admin-console/public/what-helps-me/what-helps-me.css +1296 -0
  63. package/dist/ambient-provenance.d.ts +1 -1
  64. package/dist/artifact-search.d.ts +1 -1
  65. package/dist/{auto-sync-TDHLZPVP.js → auto-sync-NR3GPCOA.js} +4 -4
  66. package/dist/behavior-learner.d.ts +1 -1
  67. package/dist/behavior-signals.d.ts +1 -1
  68. package/dist/bootstrap.d.ts +9 -9
  69. package/dist/briefing.d.ts +2 -2
  70. package/dist/briefing.js +14 -14
  71. package/dist/buffer-surprise-report.d.ts +1 -1
  72. package/dist/buffer-turn-helpers.d.ts +1 -1
  73. package/dist/buffer.d.ts +2 -2
  74. package/dist/buffer.js +2 -2
  75. package/dist/bulk-import/index.d.ts +3 -3
  76. package/dist/calibration.d.ts +1 -1
  77. package/dist/calibration.js +1 -1
  78. package/dist/capabilities.d.ts +1 -1
  79. package/dist/{catalog-B90is4d8.d.ts → catalog-DGFf8mD9.d.ts} +1 -1
  80. package/dist/causal-behavior.d.ts +1 -1
  81. package/dist/causal-consolidation.d.ts +1 -1
  82. package/dist/causal-consolidation.js +15 -15
  83. package/dist/causal-trajectory-graph.d.ts +1 -1
  84. package/dist/{chunk-CSY44OKU.js → chunk-26ZXBTYN.js} +4 -4
  85. package/dist/chunk-26ZXBTYN.js.map +1 -0
  86. package/dist/{chunk-LLJMAULE.js → chunk-2FKEIPIT.js} +5 -5
  87. package/dist/{chunk-AU7Q3LSC.js → chunk-2QSZNTDO.js} +4 -4
  88. package/dist/chunk-37DZZFFM.js +502 -0
  89. package/dist/chunk-37DZZFFM.js.map +1 -0
  90. package/dist/chunk-3HSRWJTC.js +9 -0
  91. package/dist/chunk-3HSRWJTC.js.map +1 -0
  92. package/dist/{chunk-TKFGFDPJ.js → chunk-3TIZPSJC.js} +4 -4
  93. package/dist/{chunk-B4T3FQMT.js → chunk-43SEBY2M.js} +1 -1
  94. package/dist/{chunk-LVKYLMSM.js → chunk-46SZBVDS.js} +2 -2
  95. package/dist/{chunk-YKZLOPTC.js → chunk-5FD7JMTX.js} +2 -2
  96. package/dist/{chunk-2PNXOQ4P.js → chunk-5NB726GV.js} +3 -7
  97. package/dist/chunk-5NB726GV.js.map +1 -0
  98. package/dist/chunk-62OKGIJA.js +39 -0
  99. package/dist/chunk-62OKGIJA.js.map +1 -0
  100. package/dist/{chunk-WM5LD6AT.js → chunk-6CYHUWCO.js} +2 -2
  101. package/dist/{chunk-BIF4SHMD.js → chunk-76JJSXK7.js} +1 -1
  102. package/dist/chunk-76JJSXK7.js.map +1 -0
  103. package/dist/{chunk-3SXLD5T3.js → chunk-7BD6O7ZV.js} +189 -4
  104. package/dist/chunk-7BD6O7ZV.js.map +1 -0
  105. package/dist/chunk-7TBXNYLO.js +346 -0
  106. package/dist/chunk-7TBXNYLO.js.map +1 -0
  107. package/dist/{chunk-YR65W7BV.js → chunk-BRR5EUTF.js} +3 -3
  108. package/dist/{chunk-JKW663ZN.js → chunk-CIAI24TQ.js} +2 -2
  109. package/dist/{chunk-3WGI7F4V.js → chunk-D3LBIUWV.js} +9219 -5233
  110. package/dist/chunk-D3LBIUWV.js.map +1 -0
  111. package/dist/{chunk-YDWPYDML.js → chunk-EKTP7MNS.js} +4 -4
  112. package/dist/{chunk-6LEIWWAF.js → chunk-F2JRDPON.js} +2 -2
  113. package/dist/{chunk-VYQ4URQB.js → chunk-FFRTNF3L.js} +2 -2
  114. package/dist/{chunk-TY6MKIWP.js → chunk-FONWBCVY.js} +3 -3
  115. package/dist/{chunk-XSV2YDCJ.js → chunk-FPLM2TKD.js} +2 -2
  116. package/dist/{chunk-VTU5IEKY.js → chunk-FTPONF6B.js} +2 -2
  117. package/dist/{chunk-6PZGKGAO.js → chunk-FWX7W5PM.js} +2 -2
  118. package/dist/{chunk-QPW3PAIH.js → chunk-G6DFSS6A.js} +2 -2
  119. package/dist/{chunk-2DD6ZHOM.js → chunk-GJ776BC2.js} +3 -3
  120. package/dist/{chunk-XKAR4RF6.js → chunk-GN3WRFJY.js} +6 -6
  121. package/dist/{chunk-RG426DJO.js → chunk-H7NAZ3UB.js} +2 -2
  122. package/dist/{chunk-BSXGTDVJ.js → chunk-HBUFQRIM.js} +2 -2
  123. package/dist/{chunk-FFEBSFVT.js → chunk-HGJ6NJ4E.js} +2 -2
  124. package/dist/{chunk-WB7JSQCP.js → chunk-HIEWDJ2O.js} +5 -2
  125. package/dist/{chunk-WB7JSQCP.js.map → chunk-HIEWDJ2O.js.map} +1 -1
  126. package/dist/{chunk-QTO6BMQZ.js → chunk-I3MSGFGD.js} +17 -6
  127. package/dist/chunk-I3MSGFGD.js.map +1 -0
  128. package/dist/{chunk-5JKUSBMX.js → chunk-IKP5OYQQ.js} +2 -2
  129. package/dist/{chunk-KQAFEZQX.js → chunk-IPLYGWQF.js} +5 -5
  130. package/dist/{chunk-DBY26JJJ.js → chunk-IQ4NVWEF.js} +2 -2
  131. package/dist/{chunk-7Q7JWLQ4.js → chunk-JYG4OLWH.js} +2 -2
  132. package/dist/{chunk-3OTSVCPK.js → chunk-K26NWEOC.js} +4 -4
  133. package/dist/{chunk-WZWZRZ2V.js → chunk-K2UGPTYY.js} +484 -43
  134. package/dist/chunk-K2UGPTYY.js.map +1 -0
  135. package/dist/{chunk-L6CQ7WIW.js → chunk-KFBOPMF6.js} +11 -11
  136. package/dist/chunk-KFBOPMF6.js.map +1 -0
  137. package/dist/{chunk-HOIRB77A.js → chunk-L6Z5OAS4.js} +2 -2
  138. package/dist/{chunk-7RZJWZ46.js → chunk-LEPOP46W.js} +5 -5
  139. package/dist/{chunk-QQXWFDRD.js → chunk-M4YHAODQ.js} +270 -684
  140. package/dist/chunk-M4YHAODQ.js.map +1 -0
  141. package/dist/{chunk-NGT35IGQ.js → chunk-MIH3CJPN.js} +3 -3
  142. package/dist/{chunk-QPAQSG3F.js → chunk-MK5VEWCR.js} +2 -2
  143. package/dist/chunk-NISZQW72.js +140 -0
  144. package/dist/chunk-NISZQW72.js.map +1 -0
  145. package/dist/{chunk-L7RTUEDG.js → chunk-OCIP6YMD.js} +2 -2
  146. package/dist/{chunk-2INWPC6E.js → chunk-PG4QBPVG.js} +20 -10
  147. package/dist/chunk-PG4QBPVG.js.map +1 -0
  148. package/dist/{chunk-DDA55IVB.js → chunk-PT54WISF.js} +189 -55
  149. package/dist/chunk-PT54WISF.js.map +1 -0
  150. package/dist/{chunk-UWJNKGBA.js → chunk-QZLDRQ4I.js} +5 -5
  151. package/dist/{chunk-UYOXFFEY.js → chunk-RUNORG2P.js} +3 -3
  152. package/dist/{chunk-LC3FD4BV.js → chunk-RZQ6W2W4.js} +39 -39
  153. package/dist/{chunk-MRGJZ75M.js → chunk-SMNYAMJD.js} +3 -3
  154. package/dist/{chunk-MKQBXQKU.js → chunk-TB6CBZ5V.js} +22 -15
  155. package/dist/chunk-TB6CBZ5V.js.map +1 -0
  156. package/dist/{chunk-DN2IDKI5.js → chunk-TO7ZTWJW.js} +2 -2
  157. package/dist/{chunk-K2TDK7GG.js → chunk-TWTUGCTY.js} +2 -2
  158. package/dist/{chunk-CUTFSLSD.js → chunk-UCTS3DDH.js} +2 -2
  159. package/dist/{chunk-JYIJNNN3.js → chunk-UG6VXIOK.js} +2 -2
  160. package/dist/{chunk-QOQQMVR2.js → chunk-UKYS3NU5.js} +2 -2
  161. package/dist/{chunk-VZRFGJCH.js → chunk-UPLZNJKN.js} +2 -2
  162. package/dist/{chunk-C23BYTJV.js → chunk-UW5NPZJ2.js} +40 -12
  163. package/dist/chunk-UW5NPZJ2.js.map +1 -0
  164. package/dist/{chunk-DOOWFDWN.js → chunk-V6ERBR7U.js} +2 -2
  165. package/dist/{chunk-7HG7MGAP.js → chunk-W5ZKPI34.js} +462 -2673
  166. package/dist/chunk-W5ZKPI34.js.map +1 -0
  167. package/dist/{chunk-HNDIND7P.js → chunk-XX4HPFFM.js} +54 -15
  168. package/dist/chunk-XX4HPFFM.js.map +1 -0
  169. package/dist/{chunk-N7CXQ5TA.js → chunk-XZHE2DEN.js} +1 -1
  170. package/dist/chunk-YXQEKCZM.js +223 -0
  171. package/dist/chunk-YXQEKCZM.js.map +1 -0
  172. package/dist/{chunk-6NNNURLK.js → chunk-Z54EM5YZ.js} +4 -4
  173. package/dist/{chunk-F2Y6I74C.js → chunk-ZRZVLB7O.js} +2 -2
  174. package/dist/{chunk-CLKBV3Z3.js → chunk-ZUKIUXHQ.js} +9 -9
  175. package/dist/{cli-jfuZXixq.d.ts → cli-BPDUXnAl.d.ts} +5 -5
  176. package/dist/cli.d.ts +22 -22
  177. package/dist/cli.js +66 -58
  178. package/dist/coding/pre-action-gate.d.ts +1 -1
  179. package/dist/compounding/engine.d.ts +2 -2
  180. package/dist/compounding/engine.js +14 -14
  181. package/dist/compounding/preference-consolidator.d.ts +1 -1
  182. package/dist/compression-optimizer.d.ts +1 -1
  183. package/dist/config.d.ts +1 -1
  184. package/dist/config.js +2 -1
  185. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  186. package/dist/connectors/codex-materialize-runner.js +14 -14
  187. package/dist/connectors/codex-materialize.d.ts +1 -1
  188. package/dist/connectors/index.d.ts +1 -1
  189. package/dist/connectors/index.js +14 -14
  190. package/dist/consolidation-provenance-check.d.ts +2 -2
  191. package/dist/consolidation-undo.d.ts +2 -2
  192. package/dist/contradiction/index.d.ts +2 -2
  193. package/dist/contradiction/index.js +2 -2
  194. package/dist/{contradiction-scan-KCADHXPE.js → contradiction-scan-JDTBXRGW.js} +3 -3
  195. package/dist/converge-config.d.ts +1 -1
  196. package/dist/convergence-refresh.d.ts +2 -2
  197. package/dist/convergence-refresh.js +16 -16
  198. package/dist/conversation-index/backend.d.ts +1 -1
  199. package/dist/conversation-index/backend.js +2 -2
  200. package/dist/conversation-index/chunker.d.ts +1 -1
  201. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  202. package/dist/conversation-index/indexer.d.ts +1 -1
  203. package/dist/conversation-index/search.d.ts +1 -1
  204. package/dist/corpus-watermark.d.ts +1 -1
  205. package/dist/corpus-watermark.js +16 -16
  206. package/dist/day-summary.d.ts +1 -1
  207. package/dist/delinearize.d.ts +1 -1
  208. package/dist/dependency-propagation-config.d.ts +1 -1
  209. package/dist/{dependency-propagation-delivery-CTDuAVJc.d.ts → dependency-propagation-delivery-CzEfB31P.d.ts} +1 -1
  210. package/dist/direct-answer-wiring.d.ts +1 -1
  211. package/dist/direct-answer.d.ts +1 -1
  212. package/dist/embedding-fallback.d.ts +1 -1
  213. package/dist/enrichment/index.d.ts +1 -1
  214. package/dist/entity-retrieval.d.ts +2 -2
  215. package/dist/entity-retrieval.js +14 -14
  216. package/dist/entity-schema.d.ts +1 -1
  217. package/dist/explicit-capture.d.ts +9 -9
  218. package/dist/explicit-capture.js +4 -3
  219. package/dist/external-wiki-access.d.ts +22 -22
  220. package/dist/external-wiki-access.js +33 -30
  221. package/dist/external-wiki-collection-registration.d.ts +1 -1
  222. package/dist/external-wiki-collection.d.ts +1 -1
  223. package/dist/external-wiki-mcp-tools.d.ts +22 -22
  224. package/dist/extraction-error-classification.d.ts +1 -1
  225. package/dist/extraction-faithfulness.d.ts +1 -1
  226. package/dist/extraction-faithfulness.js +2 -2
  227. package/dist/extraction-judge-telemetry.d.ts +1 -1
  228. package/dist/extraction-judge-training.d.ts +1 -1
  229. package/dist/extraction-judge.d.ts +1 -1
  230. package/dist/extraction-judge.js +2 -2
  231. package/dist/extraction-liveness.d.ts +1 -1
  232. package/dist/extraction-normalization.d.ts +1 -1
  233. package/dist/extraction-prompt.d.ts +1 -1
  234. package/dist/extraction-source-grounding-rules.d.ts +1 -1
  235. package/dist/extraction-source-grounding.d.ts +1 -1
  236. package/dist/extraction.d.ts +1 -1
  237. package/dist/extraction.js +20 -20
  238. package/dist/fallback-llm.d.ts +14 -1
  239. package/dist/fallback-llm.js +1 -1
  240. package/dist/{first-start-migration-LMMZFLKK.js → first-start-migration-CRZCZAJN.js} +5 -5
  241. package/dist/graph-dashboard-diff.d.ts +1 -1
  242. package/dist/graph-dashboard-key.d.ts +1 -1
  243. package/dist/graph-dashboard-parser.d.ts +1 -1
  244. package/dist/graph-edge-reinforcement.d.ts +1 -1
  245. package/dist/graph-path-reconstruction.d.ts +1 -1
  246. package/dist/graph-path-scoring.d.ts +1 -1
  247. package/dist/graph-snapshot.d.ts +1 -1
  248. package/dist/graph.d.ts +1 -1
  249. package/dist/harmonic-retrieval.js +1 -1
  250. package/dist/importance.d.ts +1 -1
  251. package/dist/importers/index.d.ts +1 -1
  252. package/dist/in-flight-reads.d.ts +1 -1
  253. package/dist/index.d.ts +30 -747
  254. package/dist/index.js +203 -118
  255. package/dist/inline-script.d.ts +3 -0
  256. package/dist/inline-script.js +8 -0
  257. package/dist/inline-script.js.map +1 -0
  258. package/dist/intent.d.ts +1 -1
  259. package/dist/lcm/engine.d.ts +1 -1
  260. package/dist/lcm/engine.js +2 -2
  261. package/dist/lcm/index.d.ts +1 -1
  262. package/dist/lcm/index.js +2 -2
  263. package/dist/lcm/tools.d.ts +1 -1
  264. package/dist/lifecycle.d.ts +1 -1
  265. package/dist/live-connectors-runner.d.ts +1 -1
  266. package/dist/local-llm.d.ts +2 -1
  267. package/dist/local-llm.js +2 -2
  268. package/dist/local-model-endpoint.d.ts +1 -1
  269. package/dist/maintenance/memory-governance.d.ts +1 -1
  270. package/dist/maintenance/memory-governance.js +14 -14
  271. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  272. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +14 -14
  273. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  274. package/dist/maintenance/rebuild-memory-projection.js +15 -15
  275. package/dist/{maintenance-heMZSq7G.d.ts → maintenance-C8aRWfhq.d.ts} +3 -3
  276. package/dist/mcp-memory-inspector-app.d.ts +22 -22
  277. package/dist/mcp-read-only-tools.js +1 -1
  278. package/dist/memory-action-policy.d.ts +1 -1
  279. package/dist/memory-cache.d.ts +1 -1
  280. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  281. package/dist/memory-projection-store.d.ts +1 -1
  282. package/dist/memory-provenance.d.ts +1 -1
  283. package/dist/memory-snapshot.d.ts +1 -1
  284. package/dist/memory-worth-outcomes.d.ts +2 -2
  285. package/dist/models-json.d.ts +1 -1
  286. package/dist/namespaces/migrate.d.ts +3 -3
  287. package/dist/namespaces/migrate.js +15 -15
  288. package/dist/namespaces/principal.d.ts +1 -1
  289. package/dist/namespaces/search.d.ts +1 -1
  290. package/dist/namespaces/search.js +6 -6
  291. package/dist/namespaces/storage.d.ts +3 -3
  292. package/dist/namespaces/storage.js +14 -14
  293. package/dist/native-knowledge.d.ts +1 -1
  294. package/dist/offline-sync-impression-drain.d.ts +1 -1
  295. package/dist/operator-doctor-corpus.d.ts +1 -1
  296. package/dist/operator-doctor-corpus.js +17 -17
  297. package/dist/operator-doctor-replica.d.ts +1 -1
  298. package/dist/operator-toolkit.d.ts +3 -3
  299. package/dist/operator-toolkit.js +23 -22
  300. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  301. package/dist/orchestration/maintenance.d.ts +4 -4
  302. package/dist/orchestration/maintenance.js +19 -19
  303. package/dist/{orchestrator-BQQPsSjs.d.ts → orchestrator-D85CzDDY.d.ts} +8 -8
  304. package/dist/orchestrator.d.ts +9 -9
  305. package/dist/orchestrator.js +86 -80
  306. package/dist/patterns-cli.d.ts +1 -1
  307. package/dist/{pipeline-DFfmsnGk.d.ts → pipeline-DPcUifCO.d.ts} +1 -1
  308. package/dist/policy-runtime.d.ts +1 -1
  309. package/dist/proactive-contention.d.ts +1 -1
  310. package/dist/provenance.d.ts +1 -1
  311. package/dist/public-http-D3GBeII4.d.ts +25 -0
  312. package/dist/{qmd-BF5bcVRs.d.ts → qmd-dFCHp1r0.d.ts} +1 -1
  313. package/dist/qmd-preflight.d.ts +2 -2
  314. package/dist/qmd-recall-cache.d.ts +1 -1
  315. package/dist/qmd.d.ts +2 -2
  316. package/dist/recall-concurrency-config.d.ts +1 -1
  317. package/dist/recall-disclosure-escalation.d.ts +1 -1
  318. package/dist/recall-explain-renderer.d.ts +1 -1
  319. package/dist/recall-explain-renderer.js +3 -3
  320. package/dist/recall-memory-map.d.ts +1 -1
  321. package/dist/recall-planner-llm.d.ts +1 -1
  322. package/dist/recall-planner-llm.js +1 -1
  323. package/dist/recall-state.d.ts +1 -1
  324. package/dist/recall-tag-filter.d.ts +1 -1
  325. package/dist/recall-timings.d.ts +1 -1
  326. package/dist/recall-xray-cli.d.ts +1 -1
  327. package/dist/recall-xray-cli.js +4 -4
  328. package/dist/recall-xray-renderer.d.ts +1 -1
  329. package/dist/recall-xray-renderer.js +3 -3
  330. package/dist/recall-xray.d.ts +1 -1
  331. package/dist/recall-xray.js +2 -2
  332. package/dist/reconcile/cursor.d.ts +1 -1
  333. package/dist/reconcile/manifest.d.ts +1 -1
  334. package/dist/reconcile/plan.d.ts +1 -1
  335. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  336. package/dist/replay/normalizers/claude.d.ts +1 -1
  337. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  338. package/dist/replay/normalizers/shared.d.ts +1 -1
  339. package/dist/replay/runner.d.ts +1 -1
  340. package/dist/replay/types.d.ts +1 -1
  341. package/dist/replica-divergence.d.ts +1 -1
  342. package/dist/replica-peers-config.d.ts +1 -1
  343. package/dist/resolve-auth-token.d.ts +1 -1
  344. package/dist/resume-bundles.js +3 -2
  345. package/dist/retrieval-agents.d.ts +2 -2
  346. package/dist/retrieval-tiers.d.ts +1 -1
  347. package/dist/routing/engine.d.ts +1 -1
  348. package/dist/routing/store.d.ts +1 -1
  349. package/dist/salvage-envelope.d.ts +1 -1
  350. package/dist/{scope-profiles-CbUOsE_E.d.ts → scope-profiles-DICK7GtN.d.ts} +1 -1
  351. package/dist/search/embed-helper.d.ts +1 -1
  352. package/dist/search/factory.d.ts +1 -1
  353. package/dist/search/factory.js +5 -5
  354. package/dist/search/index.d.ts +1 -1
  355. package/dist/search/index.js +9 -9
  356. package/dist/search/lancedb-backend.d.ts +1 -1
  357. package/dist/search/meilisearch-backend.d.ts +1 -1
  358. package/dist/search/noop-backend.d.ts +1 -1
  359. package/dist/search/orama-backend.d.ts +1 -1
  360. package/dist/search/port.d.ts +1 -1
  361. package/dist/search/remote-backend.d.ts +1 -1
  362. package/dist/{semantic-consolidation-DAB3xdKM.d.ts → semantic-consolidation-BP7NAX0N.d.ts} +1 -1
  363. package/dist/semantic-consolidation.d.ts +2 -2
  364. package/dist/semantic-consolidation.js +15 -15
  365. package/dist/semantic-rule-promotion.js +14 -14
  366. package/dist/semantic-rule-verifier.d.ts +1 -1
  367. package/dist/semantic-rule-verifier.js +14 -14
  368. package/dist/{service-DGKg2O6r.d.ts → service-DT-pJyda.d.ts} +660 -660
  369. package/dist/session-observer-bands.d.ts +1 -1
  370. package/dist/session-observer-state.d.ts +1 -1
  371. package/dist/shared-context/manager.d.ts +1 -1
  372. package/dist/signal.d.ts +1 -1
  373. package/dist/source-agent-qualifier.d.ts +1 -1
  374. package/dist/source-agent-qualifier.js +16 -16
  375. package/dist/{storage-CC1jKcWg.d.ts → storage-qOnaJ1Lw.d.ts} +4 -1
  376. package/dist/storage.d.ts +2 -2
  377. package/dist/storage.js +13 -13
  378. package/dist/summarizer.d.ts +1 -1
  379. package/dist/summarizer.js +5 -5
  380. package/dist/summary-snapshot.d.ts +1 -1
  381. package/dist/support-passport/index.d.ts +518 -0
  382. package/dist/support-passport/index.js +357 -0
  383. package/dist/support-passport/index.js.map +1 -0
  384. package/dist/temporal-supersession.d.ts +2 -2
  385. package/dist/temporal-timeline-recall.d.ts +1 -1
  386. package/dist/temporal-validity.d.ts +1 -1
  387. package/dist/threading.d.ts +1 -1
  388. package/dist/tier-migration.d.ts +2 -2
  389. package/dist/tier-routing.d.ts +1 -1
  390. package/dist/tier-routing.js +2 -2
  391. package/dist/{tier-stats-JDN6HRNT.js → tier-stats-EXYSKSVN.js} +3 -3
  392. package/dist/topics.d.ts +1 -1
  393. package/dist/transcript.d.ts +1 -1
  394. package/dist/transfer/autodetect.js +1 -1
  395. package/dist/transfer/backup.js +1 -1
  396. package/dist/transfer/capsule-export.js +2 -2
  397. package/dist/transfer/types.d.ts +24 -24
  398. package/dist/trust-score-stage.d.ts +1 -1
  399. package/dist/trust-score.d.ts +1 -1
  400. package/dist/{types-BnQza1y8.d.ts → types-ed-SvS2t.d.ts} +7 -1
  401. package/dist/types.d.ts +1 -1
  402. package/dist/types.js +1 -1
  403. package/dist/utility-runtime.d.ts +1 -1
  404. package/dist/verified-recall.js +14 -14
  405. package/dist/write-envelope.d.ts +1 -1
  406. package/dist/write-rate-limiter.d.ts +11 -5
  407. package/dist/write-rate-limiter.js +1 -1
  408. package/package.json +12 -2
  409. package/scripts/build-with-heap.mjs +11 -1
  410. package/src/access-authorization-probe.ts +20 -2
  411. package/src/access-boundary.ts +32 -0
  412. package/src/access-http.test.ts +1940 -643
  413. package/src/access-http.ts +81 -74
  414. package/src/access-mcp.ts +3 -1
  415. package/src/access-operations.ts +2 -0
  416. package/src/access-service.ts +612 -845
  417. package/src/access-surface-catalog.test.ts +40 -10
  418. package/src/access-surface-catalog.ts +15 -0
  419. package/src/active-memory-bridge.ts +17 -19
  420. package/src/config.ts +18 -9
  421. package/src/fallback-llm.test.ts +54 -0
  422. package/src/fallback-llm.ts +54 -9
  423. package/src/inline-script.ts +6 -0
  424. package/src/local-llm-headers-timeout.test.ts +42 -0
  425. package/src/local-llm.ts +8 -8
  426. package/src/mcp-read-only-tools.ts +3 -0
  427. package/src/relay/mission-access.test.ts +11 -11
  428. package/src/relay/mission-ui.test.ts +3 -1
  429. package/src/storage/tombstone-blocked-capture-sync.ts +31 -0
  430. package/src/storage-contract/failure-semantics.test.ts +102 -0
  431. package/src/support-passport/access-http-base.ts +143 -0
  432. package/src/support-passport/access-http.ts +172 -0
  433. package/src/support-passport/access-operations.ts +272 -0
  434. package/src/support-passport/access-service-base.test.ts +193 -0
  435. package/src/support-passport/access-service-base.ts +176 -0
  436. package/src/support-passport/access-surface.test.ts +283 -0
  437. package/src/support-passport/access-surface.ts +286 -0
  438. package/src/support-passport/card-projection.test.ts +8 -0
  439. package/src/support-passport/card-projection.ts +77 -16
  440. package/src/support-passport/card-replacement.ts +126 -0
  441. package/src/support-passport/card-service-commit-forwarding.test.ts +160 -0
  442. package/src/support-passport/card-service.test.ts +533 -31
  443. package/src/support-passport/card-service.ts +506 -364
  444. package/src/support-passport/card-state.ts +158 -0
  445. package/src/support-passport/config-model-routing.test.ts +37 -0
  446. package/src/support-passport/config.test.ts +34 -0
  447. package/src/support-passport/config.ts +41 -0
  448. package/src/support-passport/contracts.test.ts +15 -2
  449. package/src/support-passport/contracts.ts +13 -0
  450. package/src/support-passport/errors.ts +6 -0
  451. package/src/support-passport/generated-batch.test.ts +185 -0
  452. package/src/support-passport/generated-batch.ts +338 -0
  453. package/src/support-passport/grant-contracts.ts +45 -1
  454. package/src/support-passport/grant-generated-batch-scope.test.ts +201 -0
  455. package/src/support-passport/grant-service-cache.test.ts +2 -2
  456. package/src/support-passport/grant-service-cancellation.test.ts +2 -0
  457. package/src/support-passport/grant-service-marker-cache.test.ts +62 -0
  458. package/src/support-passport/grant-service.test.ts +853 -239
  459. package/src/support-passport/grant-service.ts +206 -57
  460. package/src/support-passport/grant-store.ts +7 -3
  461. package/src/support-passport/index.ts +10 -0
  462. package/src/support-passport/mcp-tools.test.ts +222 -0
  463. package/src/support-passport/mcp-tools.ts +187 -0
  464. package/src/support-passport/model-adapter.test.ts +840 -0
  465. package/src/support-passport/model-adapter.ts +602 -0
  466. package/src/support-passport/model-audit-pinned-write.test.ts +59 -0
  467. package/src/support-passport/model-audit.ts +152 -0
  468. package/src/support-passport/model-bridge.test.ts +456 -0
  469. package/src/support-passport/model-bridge.ts +439 -0
  470. package/src/support-passport/model-contracts.ts +124 -0
  471. package/src/support-passport/model-service.test.ts +1731 -0
  472. package/src/support-passport/model-service.ts +399 -0
  473. package/src/support-passport/owner-http.test.ts +671 -0
  474. package/src/support-passport/owner-lock.ts +26 -9
  475. package/src/support-passport/private-file.test.ts +99 -0
  476. package/src/support-passport/private-file.ts +139 -12
  477. package/src/support-passport/public-http.test.ts +476 -0
  478. package/src/support-passport/public-http.ts +601 -0
  479. package/src/support-passport/ui.test.ts +181 -0
  480. package/src/types.ts +7 -0
  481. package/src/write-rate-limiter.test.ts +30 -6
  482. package/src/write-rate-limiter.ts +29 -18
  483. package/dist/chunk-2INWPC6E.js.map +0 -1
  484. package/dist/chunk-2PNXOQ4P.js.map +0 -1
  485. package/dist/chunk-3SXLD5T3.js.map +0 -1
  486. package/dist/chunk-3WGI7F4V.js.map +0 -1
  487. package/dist/chunk-7HG7MGAP.js.map +0 -1
  488. package/dist/chunk-BIF4SHMD.js.map +0 -1
  489. package/dist/chunk-C23BYTJV.js.map +0 -1
  490. package/dist/chunk-CSY44OKU.js.map +0 -1
  491. package/dist/chunk-DDA55IVB.js.map +0 -1
  492. package/dist/chunk-HNDIND7P.js.map +0 -1
  493. package/dist/chunk-L6CQ7WIW.js.map +0 -1
  494. package/dist/chunk-MKQBXQKU.js.map +0 -1
  495. package/dist/chunk-QQXWFDRD.js.map +0 -1
  496. package/dist/chunk-QTO6BMQZ.js.map +0 -1
  497. package/dist/chunk-WZWZRZ2V.js.map +0 -1
  498. /package/dist/{auto-sync-TDHLZPVP.js.map → auto-sync-NR3GPCOA.js.map} +0 -0
  499. /package/dist/{chunk-LLJMAULE.js.map → chunk-2FKEIPIT.js.map} +0 -0
  500. /package/dist/{chunk-AU7Q3LSC.js.map → chunk-2QSZNTDO.js.map} +0 -0
  501. /package/dist/{chunk-TKFGFDPJ.js.map → chunk-3TIZPSJC.js.map} +0 -0
  502. /package/dist/{chunk-B4T3FQMT.js.map → chunk-43SEBY2M.js.map} +0 -0
  503. /package/dist/{chunk-LVKYLMSM.js.map → chunk-46SZBVDS.js.map} +0 -0
  504. /package/dist/{chunk-YKZLOPTC.js.map → chunk-5FD7JMTX.js.map} +0 -0
  505. /package/dist/{chunk-WM5LD6AT.js.map → chunk-6CYHUWCO.js.map} +0 -0
  506. /package/dist/{chunk-YR65W7BV.js.map → chunk-BRR5EUTF.js.map} +0 -0
  507. /package/dist/{chunk-JKW663ZN.js.map → chunk-CIAI24TQ.js.map} +0 -0
  508. /package/dist/{chunk-YDWPYDML.js.map → chunk-EKTP7MNS.js.map} +0 -0
  509. /package/dist/{chunk-6LEIWWAF.js.map → chunk-F2JRDPON.js.map} +0 -0
  510. /package/dist/{chunk-VYQ4URQB.js.map → chunk-FFRTNF3L.js.map} +0 -0
  511. /package/dist/{chunk-TY6MKIWP.js.map → chunk-FONWBCVY.js.map} +0 -0
  512. /package/dist/{chunk-XSV2YDCJ.js.map → chunk-FPLM2TKD.js.map} +0 -0
  513. /package/dist/{chunk-VTU5IEKY.js.map → chunk-FTPONF6B.js.map} +0 -0
  514. /package/dist/{chunk-6PZGKGAO.js.map → chunk-FWX7W5PM.js.map} +0 -0
  515. /package/dist/{chunk-QPW3PAIH.js.map → chunk-G6DFSS6A.js.map} +0 -0
  516. /package/dist/{chunk-2DD6ZHOM.js.map → chunk-GJ776BC2.js.map} +0 -0
  517. /package/dist/{chunk-XKAR4RF6.js.map → chunk-GN3WRFJY.js.map} +0 -0
  518. /package/dist/{chunk-RG426DJO.js.map → chunk-H7NAZ3UB.js.map} +0 -0
  519. /package/dist/{chunk-BSXGTDVJ.js.map → chunk-HBUFQRIM.js.map} +0 -0
  520. /package/dist/{chunk-FFEBSFVT.js.map → chunk-HGJ6NJ4E.js.map} +0 -0
  521. /package/dist/{chunk-5JKUSBMX.js.map → chunk-IKP5OYQQ.js.map} +0 -0
  522. /package/dist/{chunk-KQAFEZQX.js.map → chunk-IPLYGWQF.js.map} +0 -0
  523. /package/dist/{chunk-DBY26JJJ.js.map → chunk-IQ4NVWEF.js.map} +0 -0
  524. /package/dist/{chunk-7Q7JWLQ4.js.map → chunk-JYG4OLWH.js.map} +0 -0
  525. /package/dist/{chunk-3OTSVCPK.js.map → chunk-K26NWEOC.js.map} +0 -0
  526. /package/dist/{chunk-HOIRB77A.js.map → chunk-L6Z5OAS4.js.map} +0 -0
  527. /package/dist/{chunk-7RZJWZ46.js.map → chunk-LEPOP46W.js.map} +0 -0
  528. /package/dist/{chunk-NGT35IGQ.js.map → chunk-MIH3CJPN.js.map} +0 -0
  529. /package/dist/{chunk-QPAQSG3F.js.map → chunk-MK5VEWCR.js.map} +0 -0
  530. /package/dist/{chunk-L7RTUEDG.js.map → chunk-OCIP6YMD.js.map} +0 -0
  531. /package/dist/{chunk-UWJNKGBA.js.map → chunk-QZLDRQ4I.js.map} +0 -0
  532. /package/dist/{chunk-UYOXFFEY.js.map → chunk-RUNORG2P.js.map} +0 -0
  533. /package/dist/{chunk-LC3FD4BV.js.map → chunk-RZQ6W2W4.js.map} +0 -0
  534. /package/dist/{chunk-MRGJZ75M.js.map → chunk-SMNYAMJD.js.map} +0 -0
  535. /package/dist/{chunk-DN2IDKI5.js.map → chunk-TO7ZTWJW.js.map} +0 -0
  536. /package/dist/{chunk-K2TDK7GG.js.map → chunk-TWTUGCTY.js.map} +0 -0
  537. /package/dist/{chunk-CUTFSLSD.js.map → chunk-UCTS3DDH.js.map} +0 -0
  538. /package/dist/{chunk-JYIJNNN3.js.map → chunk-UG6VXIOK.js.map} +0 -0
  539. /package/dist/{chunk-QOQQMVR2.js.map → chunk-UKYS3NU5.js.map} +0 -0
  540. /package/dist/{chunk-VZRFGJCH.js.map → chunk-UPLZNJKN.js.map} +0 -0
  541. /package/dist/{chunk-DOOWFDWN.js.map → chunk-V6ERBR7U.js.map} +0 -0
  542. /package/dist/{chunk-N7CXQ5TA.js.map → chunk-XZHE2DEN.js.map} +0 -0
  543. /package/dist/{chunk-6NNNURLK.js.map → chunk-Z54EM5YZ.js.map} +0 -0
  544. /package/dist/{chunk-F2Y6I74C.js.map → chunk-ZRZVLB7O.js.map} +0 -0
  545. /package/dist/{chunk-CLKBV3Z3.js.map → chunk-ZUKIUXHQ.js.map} +0 -0
  546. /package/dist/{contradiction-scan-KCADHXPE.js.map → contradiction-scan-JDTBXRGW.js.map} +0 -0
  547. /package/dist/{first-start-migration-LMMZFLKK.js.map → first-start-migration-CRZCZAJN.js.map} +0 -0
  548. /package/dist/{tier-stats-JDN6HRNT.js.map → tier-stats-EXYSKSVN.js.map} +0 -0
@@ -0,0 +1,338 @@
1
+ import path from "node:path";
2
+
3
+ import { z } from "zod";
4
+
5
+ import type { StorageManager } from "../index.js";
6
+ import type { MemoryFile } from "../types.js";
7
+ import {
8
+ type StoredSupportPassportCard,
9
+ computeSupportPassportOwnerKey,
10
+ projectSupportPassportCard,
11
+ } from "./card-projection.js";
12
+ import { SupportPassportNamespaceSchema } from "./contracts.js";
13
+ import { SupportPassportError } from "./errors.js";
14
+ import {
15
+ ensurePrivateDirectoryNoFollow,
16
+ ensurePrivateDirectoryTreeNoFollow,
17
+ readPrivateFileNoFollow,
18
+ removePrivateFilesNoFollow,
19
+ writePrivateFileAtomicallyNoFollow,
20
+ } from "./private-file.js";
21
+
22
+ const BatchIdSchema = z
23
+ .string()
24
+ .uuid()
25
+ .transform((value) => value.toLowerCase());
26
+ const GeneratedBatchMarkerSchema = z
27
+ .object({
28
+ schemaVersion: z.literal(1),
29
+ batchId: BatchIdSchema,
30
+ size: z.number().int().min(1).max(8),
31
+ namespace: SupportPassportNamespaceSchema,
32
+ owner: z.string().regex(/^[a-f0-9]{64}$/),
33
+ complete: z.boolean(),
34
+ })
35
+ .strict();
36
+
37
+ export type GeneratedBatchMarker = z.infer<typeof GeneratedBatchMarkerSchema>;
38
+
39
+ export interface GeneratedBatchContext {
40
+ storage: StorageManager;
41
+ principal: string;
42
+ namespace: string;
43
+ now: () => Date;
44
+ requireOwnerLock: () => Promise<void>;
45
+ onCommitted?: () => void;
46
+ }
47
+
48
+ type GeneratedBatchMarkerWriter = (storage: StorageManager, marker: GeneratedBatchMarker) => Promise<void>;
49
+
50
+ const BATCH_ERROR = "The generated draft batch state is not safe.";
51
+
52
+ function batchDirectory(storage: StorageManager): string {
53
+ return path.join(storage.dir, "state", "support-passport", "generated-batches");
54
+ }
55
+
56
+ function batchFileName(batchId: string): string {
57
+ return `${BatchIdSchema.parse(batchId)}.json`;
58
+ }
59
+
60
+ function batchPath(storage: StorageManager, batchId: string): string {
61
+ return path.join(batchDirectory(storage), batchFileName(batchId));
62
+ }
63
+
64
+ function markerFor(context: GeneratedBatchContext, batchId: string, size: number, complete: boolean) {
65
+ return GeneratedBatchMarkerSchema.parse({
66
+ schemaVersion: 1,
67
+ batchId,
68
+ size,
69
+ namespace: context.namespace,
70
+ owner: computeSupportPassportOwnerKey(context.principal),
71
+ complete,
72
+ });
73
+ }
74
+
75
+ function sameOwner(marker: GeneratedBatchMarker, context: GeneratedBatchContext): boolean {
76
+ return marker.namespace === context.namespace && marker.owner === computeSupportPassportOwnerKey(context.principal);
77
+ }
78
+
79
+ async function ensureBatchDirectory(storage: StorageManager): Promise<void> {
80
+ const directory = batchDirectory(storage);
81
+ await ensurePrivateDirectoryTreeNoFollow(directory, BATCH_ERROR);
82
+ await ensurePrivateDirectoryNoFollow(storage.dir, directory, BATCH_ERROR);
83
+ }
84
+
85
+ export async function readSupportPassportGeneratedBatchMarker(
86
+ storage: StorageManager,
87
+ batchId: string
88
+ ): Promise<GeneratedBatchMarker | null> {
89
+ const directory = batchDirectory(storage);
90
+ try {
91
+ const content = await readPrivateFileNoFollow(directory, batchPath(storage, batchId), BATCH_ERROR, storage.dir);
92
+ let value: unknown;
93
+ try {
94
+ value = JSON.parse(content);
95
+ } catch {
96
+ throw new SupportPassportError("card_data_invalid", "The generated draft batch state is invalid.", 500);
97
+ }
98
+ const parsed = GeneratedBatchMarkerSchema.safeParse(value);
99
+ if (!parsed.success || parsed.data.batchId !== BatchIdSchema.parse(batchId)) {
100
+ throw new SupportPassportError("card_data_invalid", "The generated draft batch state is invalid.", 500);
101
+ }
102
+ return parsed.data;
103
+ } catch (error) {
104
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") return null;
105
+ throw error;
106
+ }
107
+ }
108
+
109
+ export async function isSupportPassportGeneratedBatchCommitted(
110
+ context: GeneratedBatchContext,
111
+ marker: GeneratedBatchMarker
112
+ ): Promise<boolean> {
113
+ const current = await readSupportPassportGeneratedBatchMarker(context.storage, marker.batchId);
114
+ return Boolean(current?.complete && sameOwner(current, context) && current.size === marker.size);
115
+ }
116
+
117
+ async function writeBatchMarker(storage: StorageManager, marker: GeneratedBatchMarker): Promise<void> {
118
+ const directory = batchDirectory(storage);
119
+ await writePrivateFileAtomicallyNoFollow(
120
+ directory,
121
+ batchPath(storage, marker.batchId),
122
+ `${JSON.stringify(marker)}\n`,
123
+ BATCH_ERROR,
124
+ storage.dir
125
+ );
126
+ }
127
+
128
+ async function removeBatchMarker(storage: StorageManager, batchId: string): Promise<void> {
129
+ await removePrivateFilesNoFollow(batchDirectory(storage), [batchFileName(batchId)], BATCH_ERROR, storage.dir);
130
+ }
131
+
132
+ function projectOwnedCard(memory: MemoryFile, namespace: string, principal: string): StoredSupportPassportCard | null {
133
+ const card = projectSupportPassportCard(memory);
134
+ return card?.namespace === namespace && card.owner === computeSupportPassportOwnerKey(principal) ? card : null;
135
+ }
136
+
137
+ export async function persistSupportPassportGeneratedBatchMarker(
138
+ context: GeneratedBatchContext,
139
+ batchId: string,
140
+ size: number,
141
+ writeMarker: GeneratedBatchMarkerWriter = writeBatchMarker
142
+ ): Promise<GeneratedBatchMarker> {
143
+ const marker = markerFor(context, batchId, size, false);
144
+ await context.requireOwnerLock();
145
+ await ensureBatchDirectory(context.storage);
146
+ await writeMarker(context.storage, marker);
147
+ context.onCommitted?.();
148
+ return marker;
149
+ }
150
+
151
+ export async function commitSupportPassportGeneratedBatch(
152
+ context: GeneratedBatchContext,
153
+ marker: GeneratedBatchMarker,
154
+ cards: readonly StoredSupportPassportCard[],
155
+ writeMarker: GeneratedBatchMarkerWriter = writeBatchMarker
156
+ ): Promise<void> {
157
+ const cardIds = cards.map((card) => card.card.cardId);
158
+ if (!sameOwner(marker, context) || cards.length !== marker.size || new Set(cardIds).size !== cards.length) {
159
+ throw new SupportPassportError("storage_conflict", "The generated draft batch is incomplete.", 409);
160
+ }
161
+ for (const card of cards) {
162
+ if (
163
+ card.namespace !== context.namespace ||
164
+ card.owner !== computeSupportPassportOwnerKey(context.principal) ||
165
+ card.card.status !== "pending_review" ||
166
+ card.generatedBatchId !== marker.batchId ||
167
+ card.generatedBatchSize !== marker.size
168
+ ) {
169
+ throw new SupportPassportError("storage_conflict", "The generated draft batch is incomplete.", 409);
170
+ }
171
+ }
172
+ await context.requireOwnerLock();
173
+ const committed = { ...marker, complete: true };
174
+ try {
175
+ await writeMarker(context.storage, committed);
176
+ } catch (error) {
177
+ if (!(await isSupportPassportGeneratedBatchCommitted(context, marker))) throw error;
178
+ }
179
+ context.onCommitted?.();
180
+ }
181
+
182
+ async function rejectGeneratedDraft(context: GeneratedBatchContext, cardId: string): Promise<boolean> {
183
+ for (let attempt = 0; attempt < 2; attempt += 1) {
184
+ const memory = await context.storage.getMemoryById(cardId);
185
+ if (!memory) return true;
186
+ const stored = projectOwnedCard(memory, context.namespace, context.principal);
187
+ if (!stored) return false;
188
+ if (stored.card.status === "rejected") return true;
189
+ if (stored.card.status !== "pending_review") return false;
190
+ await context.requireOwnerLock();
191
+ if (
192
+ await context.storage.writeMemoryFrontmatterIfUnchanged(
193
+ memory,
194
+ { status: "rejected", updated: context.now().toISOString() },
195
+ { actor: context.principal, reasonCode: "draft-batch-failed" }
196
+ )
197
+ ) {
198
+ context.onCommitted?.();
199
+ return true;
200
+ }
201
+ }
202
+ return false;
203
+ }
204
+
205
+ export async function rollbackSupportPassportGeneratedBatch(
206
+ context: GeneratedBatchContext,
207
+ batchId: string,
208
+ knownCardIds: readonly string[]
209
+ ): Promise<boolean> {
210
+ const marker = await readSupportPassportGeneratedBatchMarker(context.storage, batchId);
211
+ if (marker && !sameOwner(marker, context)) return false;
212
+ if (marker?.complete) return false;
213
+ const cardIds = new Set(knownCardIds);
214
+ let scanComplete = true;
215
+ try {
216
+ for (const memory of await context.storage.readAllMemories()) {
217
+ const card = projectOwnedCard(memory, context.namespace, context.principal);
218
+ if (card?.generatedBatchId === batchId) cardIds.add(card.card.cardId);
219
+ }
220
+ } catch {
221
+ scanComplete = false;
222
+ }
223
+ let complete = scanComplete;
224
+ for (const cardId of cardIds) {
225
+ try {
226
+ if (!(await rejectGeneratedDraft(context, cardId))) complete = false;
227
+ } catch {
228
+ complete = false;
229
+ }
230
+ }
231
+ if (!complete) return false;
232
+ try {
233
+ await removeBatchMarker(context.storage, batchId);
234
+ context.onCommitted?.();
235
+ } catch {
236
+ complete = false;
237
+ }
238
+ return complete;
239
+ }
240
+
241
+ export async function isCommittedGeneratedCard(
242
+ storage: StorageManager,
243
+ card: StoredSupportPassportCard,
244
+ markerCache?: Map<string, GeneratedBatchMarker | null>
245
+ ): Promise<boolean> {
246
+ if (!card.generatedBatchId) return true;
247
+ let marker = markerCache?.get(card.generatedBatchId);
248
+ if (!markerCache?.has(card.generatedBatchId)) {
249
+ marker = await readSupportPassportGeneratedBatchMarker(storage, card.generatedBatchId);
250
+ markerCache?.set(card.generatedBatchId, marker);
251
+ }
252
+ return Boolean(
253
+ marker?.complete &&
254
+ marker.size === card.generatedBatchSize &&
255
+ marker.namespace === card.namespace &&
256
+ marker.owner === card.owner
257
+ );
258
+ }
259
+
260
+ export async function projectCommittedSupportPassportCards(
261
+ storage: StorageManager,
262
+ memories: readonly MemoryFile[],
263
+ namespace: string,
264
+ principal: string
265
+ ): Promise<StoredSupportPassportCard[]> {
266
+ const projected = memories
267
+ .map(projectSupportPassportCard)
268
+ .filter(
269
+ (card): card is StoredSupportPassportCard =>
270
+ card?.namespace === namespace && card.owner === computeSupportPassportOwnerKey(principal)
271
+ );
272
+ const markers = new Map<string, GeneratedBatchMarker | null>();
273
+ const committed: StoredSupportPassportCard[] = [];
274
+ for (const card of projected) {
275
+ if (await isCommittedGeneratedCard(storage, card, markers)) committed.push(card);
276
+ }
277
+ const ids = new Set<string>();
278
+ for (const card of committed) {
279
+ if (ids.has(card.card.cardId)) {
280
+ throw new SupportPassportError("card_data_invalid", "Support card IDs must be unique.", 500);
281
+ }
282
+ ids.add(card.card.cardId);
283
+ }
284
+ return committed;
285
+ }
286
+
287
+ export async function readCommittedSupportPassportCards(
288
+ storage: StorageManager,
289
+ namespace: string,
290
+ principal: string
291
+ ): Promise<StoredSupportPassportCard[]> {
292
+ return await projectCommittedSupportPassportCards(
293
+ storage,
294
+ await storage.readAllMemories(),
295
+ namespace,
296
+ principal
297
+ );
298
+ }
299
+
300
+ export async function recoverSupportPassportGeneratedBatches(
301
+ context: GeneratedBatchContext,
302
+ memories: readonly MemoryFile[]
303
+ ): Promise<void> {
304
+ const cardsByBatch = new Map<string, StoredSupportPassportCard[]>();
305
+ for (const memory of memories) {
306
+ const card = projectOwnedCard(memory, context.namespace, context.principal);
307
+ if (!card?.generatedBatchId) continue;
308
+ const cards = cardsByBatch.get(card.generatedBatchId) ?? [];
309
+ cards.push(card);
310
+ cardsByBatch.set(card.generatedBatchId, cards);
311
+ }
312
+ for (const [batchId, cards] of cardsByBatch) {
313
+ const marker = await readSupportPassportGeneratedBatchMarker(context.storage, batchId);
314
+ if (marker?.complete === true && sameOwner(marker, context)) continue;
315
+ if (!marker) {
316
+ let recovered = true;
317
+ for (const card of cards) {
318
+ if (card.card.status !== "pending_review") continue;
319
+ try {
320
+ if (!(await rejectGeneratedDraft(context, card.card.cardId))) recovered = false;
321
+ } catch {
322
+ recovered = false;
323
+ }
324
+ }
325
+ if (recovered) continue;
326
+ throw new SupportPassportError("storage_conflict", "An incomplete generated draft batch could not recover.", 500);
327
+ }
328
+ if (
329
+ !(await rollbackSupportPassportGeneratedBatch(
330
+ context,
331
+ batchId,
332
+ cards.map((card) => card.card.cardId)
333
+ ))
334
+ ) {
335
+ throw new SupportPassportError("storage_conflict", "An incomplete generated draft batch could not recover.", 500);
336
+ }
337
+ }
338
+ }
@@ -60,7 +60,8 @@ export const SupportPassportCreateGrantInputSchema = z
60
60
  .object({
61
61
  principal: z.string().trim().min(1).max(512),
62
62
  cards: z.array(SupportPassportGrantCardRefSchema).min(1).max(8),
63
- expiresAt: IsoTimestampSchema,
63
+ expiresAt: IsoTimestampSchema.optional(),
64
+ durationMs: z.number().int().min(300_000).max(604_800_000).optional(),
64
65
  })
65
66
  .strict()
66
67
  .superRefine((input, ctx) => {
@@ -75,8 +76,49 @@ export const SupportPassportCreateGrantInputSchema = z
75
76
  }
76
77
  ids.add(card.cardId);
77
78
  }
79
+ if ((input.expiresAt === undefined) === (input.durationMs === undefined)) {
80
+ ctx.addIssue({
81
+ code: z.ZodIssueCode.custom,
82
+ message: "one expiry value is required",
83
+ path: ["expiresAt"],
84
+ });
85
+ }
78
86
  });
79
87
 
88
+ export const SupportPassportCreateGrantRequestSchema = z
89
+ .object({
90
+ cardIds: z.array(SupportPassportMemoryIdSchema).min(1).max(8),
91
+ cardRevisions: z.array(SupportPassportGrantCardRefSchema).min(1).max(8),
92
+ expiresAt: IsoTimestampSchema.optional(),
93
+ durationMs: z.number().int().min(300_000).max(604_800_000).optional(),
94
+ })
95
+ .strict()
96
+ .superRefine((input, ctx) => {
97
+ const cardIds = new Set(input.cardIds);
98
+ const revisionIds = new Set(input.cardRevisions.map((card) => card.cardId));
99
+ if (
100
+ cardIds.size !== input.cardIds.length ||
101
+ revisionIds.size !== input.cardRevisions.length ||
102
+ cardIds.size !== revisionIds.size ||
103
+ input.cardIds.some((cardId) => !revisionIds.has(cardId))
104
+ ) {
105
+ ctx.addIssue({
106
+ code: z.ZodIssueCode.custom,
107
+ message: "card revisions must match the selected card IDs",
108
+ path: ["cardRevisions"],
109
+ });
110
+ }
111
+ if ((input.expiresAt === undefined) === (input.durationMs === undefined)) {
112
+ ctx.addIssue({
113
+ code: z.ZodIssueCode.custom,
114
+ message: "one expiry value is required",
115
+ path: ["expiresAt"],
116
+ });
117
+ }
118
+ });
119
+
120
+ export const SupportPassportOwnerCreateGrantRequestSchema = SupportPassportCreateGrantRequestSchema;
121
+
80
122
  export const SupportPassportOwnerGrantSchema = z
81
123
  .object({
82
124
  grantId: GrantIdSchema,
@@ -133,6 +175,8 @@ export const SupportPassportListGrantsInputSchema = z
133
175
  export type SupportPassportGrantCardRef = z.infer<typeof SupportPassportGrantCardRefSchema>;
134
176
  export type SupportPassportGrantState = z.infer<typeof SupportPassportGrantStateSchema>;
135
177
  export type SupportPassportCreateGrantInput = z.input<typeof SupportPassportCreateGrantInputSchema>;
178
+ export type SupportPassportCreateGrantRequest = z.input<typeof SupportPassportCreateGrantRequestSchema>;
179
+ export type SupportPassportOwnerCreateGrantRequest = z.input<typeof SupportPassportOwnerCreateGrantRequestSchema>;
136
180
  export type SupportPassportOwnerGrant = z.infer<typeof SupportPassportOwnerGrantSchema>;
137
181
  export type SupportPassportCreatedGrant = z.infer<typeof SupportPassportCreatedGrantSchema>;
138
182
  export type SupportPassportPublicGuide = z.infer<typeof SupportPassportPublicGuideSchema>;
@@ -0,0 +1,201 @@
1
+ import assert from "node:assert/strict";
2
+ import { mkdtemp, readFile, rm, unlink, writeFile } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import path from "node:path";
5
+ import { test } from "node:test";
6
+
7
+ import { StorageManager } from "../storage.js";
8
+ import { SUPPORT_PASSPORT_ATTRIBUTE_KEYS, computeSupportPassportOwnerKey } from "./card-projection.js";
9
+ import { SupportPassportCardService } from "./card-service.js";
10
+ import { SupportPassportError } from "./errors.js";
11
+ import { SupportPassportGrantService } from "./grant-service.js";
12
+ import { SupportPassportGrantStore } from "./grant-store.js";
13
+
14
+ test("grant reads do not open another owner's generated batch marker", async () => {
15
+ StorageManager.clearAllStaticCaches();
16
+ const root = await mkdtemp(path.join(tmpdir(), "remnic-support-grant-batch-scope-"));
17
+ try {
18
+ const storage = new StorageManager(path.join(root, "shared"));
19
+ await storage.ensureDirectories();
20
+ const now = () => new Date("2026-08-13T12:00:00.000Z");
21
+ const resolveOwner = async (principal: string) => ({ principal, namespace: "team", storage });
22
+ const cardService = new SupportPassportCardService({ resolveOwner, now });
23
+ const grantStore = new SupportPassportGrantStore({ memoryDir: path.join(root, "grants"), now });
24
+ const grantService = new SupportPassportGrantService({
25
+ grantStore,
26
+ resolveOwner,
27
+ resolveNamespace: async () => storage,
28
+ now,
29
+ });
30
+ const cards = new Map<string, Awaited<ReturnType<typeof cardService.approveCard>>>();
31
+ for (const principal of ["owner:alice", "owner:bob"]) {
32
+ const [draft] = await cardService.createGeneratedDrafts({
33
+ principal,
34
+ cards: [{
35
+ title: `${principal} support`,
36
+ statement: "Give me time to answer.",
37
+ category: "communication",
38
+ sourceMemoryIds: ["source-1"],
39
+ }],
40
+ });
41
+ assert.ok(draft);
42
+ cards.set(principal, await cardService.approveCard({
43
+ principal,
44
+ cardId: draft.cardId,
45
+ expectedRevision: draft.revision,
46
+ }));
47
+ }
48
+ const grants = new Map<string, Awaited<ReturnType<typeof grantService.createGrant>>>();
49
+ for (const principal of ["owner:alice", "owner:bob"]) {
50
+ const card = cards.get(principal);
51
+ assert.ok(card);
52
+ grants.set(principal, await grantService.createGrant({
53
+ principal,
54
+ cards: [{ cardId: card.cardId, revision: card.revision }],
55
+ expiresAt: "2026-08-13T13:00:00.000Z",
56
+ }));
57
+ }
58
+
59
+ const bobCard = cards.get("owner:bob");
60
+ assert.ok(bobCard);
61
+ const bobMemory = await storage.getMemoryById(bobCard.cardId);
62
+ const batchId = bobMemory?.frontmatter.structuredAttributes?.[SUPPORT_PASSPORT_ATTRIBUTE_KEYS.generatedBatchId];
63
+ assert.ok(batchId);
64
+ await writeFile(
65
+ path.join(storage.dir, "state", "support-passport", "generated-batches", `${batchId}.json`),
66
+ "not-json\n",
67
+ "utf8",
68
+ );
69
+ const freshService = new SupportPassportGrantService({
70
+ grantStore,
71
+ resolveOwner,
72
+ resolveNamespace: async () => storage,
73
+ now,
74
+ });
75
+ const aliceGrant = grants.get("owner:alice");
76
+ const bobGrant = grants.get("owner:bob");
77
+ assert.ok(aliceGrant);
78
+ assert.ok(bobGrant);
79
+
80
+ assert.equal(
81
+ (await freshService.readGrant({ grantId: aliceGrant.grant.grantId, secret: aliceGrant.secret })).cards[0]?.cardId,
82
+ cards.get("owner:alice")?.cardId,
83
+ );
84
+ await assert.rejects(
85
+ freshService.readGrant({ grantId: bobGrant.grant.grantId, secret: bobGrant.secret }),
86
+ (error: unknown) => error instanceof SupportPassportError && error.code === "card_data_invalid",
87
+ );
88
+ } finally {
89
+ StorageManager.clearAllStaticCaches();
90
+ await rm(root, { recursive: true, force: true });
91
+ }
92
+ });
93
+
94
+ test("a removed generated batch marker invalidates a cached grant snapshot", async () => {
95
+ StorageManager.clearAllStaticCaches();
96
+ const root = await mkdtemp(path.join(tmpdir(), "remnic-support-grant-batch-cache-"));
97
+ try {
98
+ const storage = new StorageManager(path.join(root, "owner"));
99
+ await storage.ensureDirectories();
100
+ const now = () => new Date("2026-08-13T12:00:00.000Z");
101
+ const resolveOwner = async (principal: string) => ({ principal, namespace: "owner", storage });
102
+ const cardService = new SupportPassportCardService({ resolveOwner, now });
103
+ const grantStore = new SupportPassportGrantStore({ memoryDir: path.join(root, "grants"), now });
104
+ const grantService = new SupportPassportGrantService({
105
+ grantStore,
106
+ resolveOwner,
107
+ resolveNamespace: async () => storage,
108
+ now,
109
+ });
110
+ const [draft] = await cardService.createGeneratedDrafts({
111
+ principal: "owner:alice",
112
+ cards: [{
113
+ title: "Time to answer",
114
+ statement: "Give me time to answer.",
115
+ category: "communication",
116
+ sourceMemoryIds: ["source-1"],
117
+ }],
118
+ });
119
+ assert.ok(draft);
120
+ const card = await cardService.approveCard({
121
+ principal: "owner:alice",
122
+ cardId: draft.cardId,
123
+ expectedRevision: draft.revision,
124
+ });
125
+ const grant = await grantService.createGrant({
126
+ principal: "owner:alice",
127
+ cards: [{ cardId: card.cardId, revision: card.revision }],
128
+ expiresAt: "2026-08-13T13:00:00.000Z",
129
+ });
130
+ await grantService.readGrant({ grantId: grant.grant.grantId, secret: grant.secret });
131
+
132
+ const memory = await storage.getMemoryById(card.cardId);
133
+ const batchId = memory?.frontmatter.structuredAttributes?.[SUPPORT_PASSPORT_ATTRIBUTE_KEYS.generatedBatchId];
134
+ assert.ok(batchId);
135
+ await unlink(path.join(storage.dir, "state", "support-passport", "generated-batches", `${batchId}.json`));
136
+
137
+ await assert.rejects(
138
+ grantService.readGrant({ grantId: grant.grant.grantId, secret: grant.secret }),
139
+ (error: unknown) => error instanceof SupportPassportError && error.code === "grant_stale",
140
+ );
141
+ } finally {
142
+ StorageManager.clearAllStaticCaches();
143
+ await rm(root, { recursive: true, force: true });
144
+ }
145
+ });
146
+
147
+ test("a completed generated batch invalidates a cached omission", async () => {
148
+ StorageManager.clearAllStaticCaches();
149
+ const root = await mkdtemp(path.join(tmpdir(), "remnic-support-grant-batch-complete-"));
150
+ try {
151
+ const storage = new StorageManager(path.join(root, "owner"));
152
+ await storage.ensureDirectories();
153
+ const now = () => new Date("2026-08-13T12:00:00.000Z");
154
+ const principal = "owner:alice";
155
+ const resolveOwner = async () => ({ principal, namespace: "owner", storage });
156
+ const cardService = new SupportPassportCardService({ resolveOwner, now });
157
+ const [draft] = await cardService.createGeneratedDrafts({
158
+ principal,
159
+ cards: [{
160
+ title: "Time to answer",
161
+ statement: "Give me time to answer.",
162
+ category: "communication",
163
+ sourceMemoryIds: ["source-1"],
164
+ }],
165
+ });
166
+ assert.ok(draft);
167
+ const card = await cardService.approveCard({
168
+ principal,
169
+ cardId: draft.cardId,
170
+ expectedRevision: draft.revision,
171
+ });
172
+ const memory = await storage.getMemoryById(card.cardId);
173
+ const batchId = memory?.frontmatter.structuredAttributes?.[SUPPORT_PASSPORT_ATTRIBUTE_KEYS.generatedBatchId];
174
+ assert.ok(batchId);
175
+ const markerPath = path.join(storage.dir, "state", "support-passport", "generated-batches", `${batchId}.json`);
176
+ const completeMarker = JSON.parse(await readFile(markerPath, "utf8")) as Record<string, unknown>;
177
+ await writeFile(markerPath, `${JSON.stringify({ ...completeMarker, complete: false })}\n`, "utf8");
178
+ const service = new SupportPassportGrantService({
179
+ grantStore: {} as SupportPassportGrantStore,
180
+ resolveOwner,
181
+ resolveNamespace: async () => storage,
182
+ now,
183
+ });
184
+ const inspected = service as unknown as {
185
+ readStoredCardSnapshot(
186
+ target: StorageManager,
187
+ namespace: string,
188
+ ownerKey: string,
189
+ ): Promise<{ cardsById: ReadonlyMap<string, unknown> }>;
190
+ };
191
+ const ownerKey = computeSupportPassportOwnerKey(principal);
192
+
193
+ assert.equal((await inspected.readStoredCardSnapshot(storage, "owner", ownerKey)).cardsById.size, 0);
194
+ await writeFile(markerPath, `${JSON.stringify(completeMarker)}\n`, "utf8");
195
+
196
+ assert.equal((await inspected.readStoredCardSnapshot(storage, "owner", ownerKey)).cardsById.size, 1);
197
+ } finally {
198
+ StorageManager.clearAllStaticCaches();
199
+ await rm(root, { recursive: true, force: true });
200
+ }
201
+ });
@@ -79,12 +79,12 @@ test("card snapshots match the storage cache freshness window", async () => {
79
79
  diskMemories = [];
80
80
  nowMs += 1_001;
81
81
  assert.equal((await inspected.readStoredCardSnapshot(storage, "alice", ownerKey)).cardsById.size, 1);
82
- assert.equal(calls, 2);
82
+ assert.equal(calls, 1);
83
83
  assert.equal(diskReads, 1);
84
84
  nowMs += 59_000;
85
85
 
86
86
  assert.equal((await inspected.readStoredCardSnapshot(storage, "alice", ownerKey)).cardsById.size, 0);
87
- assert.equal(calls, 3);
87
+ assert.equal(calls, 2);
88
88
  assert.equal(diskReads, 2);
89
89
  });
90
90
 
@@ -45,6 +45,8 @@ test("grant creation checks cancellation again before commit", async () => {
45
45
  readAllMemories: async () => [memory],
46
46
  getCorpusScanVersion: () => 1,
47
47
  hotCacheKeyId: () => "owner-cache",
48
+ hotCacheTtlMs: () => 60_000,
49
+ isHotCacheEnabled: () => true,
48
50
  } as unknown as StorageManager;
49
51
  const controller = new AbortController();
50
52
  let committed = false;
@@ -0,0 +1,62 @@
1
+ import assert from "node:assert/strict";
2
+ import { mkdtemp, rm, unlink } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import path from "node:path";
5
+ import test from "node:test";
6
+
7
+ import { StorageManager } from "../storage.js";
8
+ import {
9
+ computeSupportPassportOwnerKey,
10
+ type StoredSupportPassportCard,
11
+ } from "./card-projection.js";
12
+ import {
13
+ commitSupportPassportGeneratedBatch,
14
+ isCommittedGeneratedCard,
15
+ persistSupportPassportGeneratedBatchMarker,
16
+ } from "./generated-batch.js";
17
+
18
+ test("generated card checks reuse a marker within one snapshot build", async () => {
19
+ StorageManager.clearAllStaticCaches();
20
+ const root = await mkdtemp(path.join(tmpdir(), "remnic-support-grant-marker-cache-"));
21
+ const storage = new StorageManager(path.join(root, "owner"));
22
+ await storage.ensureDirectories();
23
+ const batchId = "00000000-0000-4000-8000-000000000001";
24
+ const context = {
25
+ storage,
26
+ principal: "owner:alice",
27
+ namespace: "alice",
28
+ now: () => new Date("2026-08-13T12:00:00.000Z"),
29
+ requireOwnerLock: async () => undefined,
30
+ };
31
+ const owner = computeSupportPassportOwnerKey(context.principal);
32
+ const cards = [
33
+ {
34
+ namespace: "alice",
35
+ owner,
36
+ generatedBatchId: batchId,
37
+ generatedBatchSize: 2,
38
+ card: { cardId: "00000000-0000-4000-8000-000000000002", status: "pending_review" },
39
+ },
40
+ {
41
+ namespace: "alice",
42
+ owner,
43
+ generatedBatchId: batchId,
44
+ generatedBatchSize: 2,
45
+ card: { cardId: "00000000-0000-4000-8000-000000000003", status: "pending_review" },
46
+ },
47
+ ] as StoredSupportPassportCard[];
48
+
49
+ try {
50
+ const marker = await persistSupportPassportGeneratedBatchMarker(context, batchId, cards.length);
51
+ await commitSupportPassportGeneratedBatch(context, marker, cards);
52
+ const markerCache = new Map();
53
+
54
+ assert.equal(await isCommittedGeneratedCard(storage, cards[0]!, markerCache), true);
55
+ await unlink(path.join(storage.dir, "state", "support-passport", "generated-batches", `${batchId}.json`));
56
+ assert.equal(await isCommittedGeneratedCard(storage, cards[1]!, markerCache), true);
57
+ assert.equal(await isCommittedGeneratedCard(storage, cards[1]!, new Map()), false);
58
+ } finally {
59
+ StorageManager.clearAllStaticCaches();
60
+ await rm(root, { recursive: true, force: true });
61
+ }
62
+ });