@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
@@ -367,25 +367,25 @@ test("Relay write quota releases the exact reservation when timestamps collide",
367
367
  adminConsoleEnabled: false,
368
368
  });
369
369
  const internals = server as unknown as {
370
- writeLimiter: { slotsFor(principal?: string): ReadonlyArray<{ readonly recordedAt: number }> };
371
- reserveWriteRateLimitSlot: () => () => void;
370
+ writeLimiter: {
371
+ slotsFor(principal?: string): ReadonlyArray<{ readonly recordedAt: number }>;
372
+ inFlightFor(principal?: string): number;
373
+ };
374
+ reserveWriteRateLimitSlot: () => { commit(): void; release(): void };
372
375
  };
373
376
  const originalNow = Date.now;
374
377
  try {
375
378
  Date.now = () => 1_754_000_000_000;
376
- const releaseCommitted = internals.reserveWriteRateLimitSlot();
379
+ const committed = internals.reserveWriteRateLimitSlot();
380
+ committed.commit();
377
381
  const committedSlot = internals.writeLimiter.slotsFor()[0];
378
- const releaseFailed = internals.reserveWriteRateLimitSlot();
379
- const failedSlot = internals.writeLimiter.slotsFor()[1];
382
+ const failed = internals.reserveWriteRateLimitSlot();
380
383
  assert.ok(committedSlot);
381
- assert.ok(failedSlot);
382
- assert.notEqual(committedSlot, failedSlot);
384
+ assert.equal(internals.writeLimiter.inFlightFor(), 1);
383
385
 
384
- releaseFailed();
386
+ failed.release();
385
387
  assert.deepEqual(internals.writeLimiter.slotsFor(), [committedSlot]);
386
-
387
- releaseCommitted();
388
- assert.deepEqual(internals.writeLimiter.slotsFor(), []);
388
+ assert.equal(internals.writeLimiter.inFlightFor(), 0);
389
389
  } finally {
390
390
  Date.now = originalNow;
391
391
  }
@@ -62,7 +62,9 @@ test("Relay Mission Control serves both aliases from one exact static allow-list
62
62
  });
63
63
  assert.equal(authorizedShell.status, 200);
64
64
  assert.equal(authorizedShell.headers.get("cache-control"), "private, no-store");
65
- assert.match(await authorizedShell.text(), /__REMNIC_ADMIN_CONSOLE_PREFILL_TOKEN__="relay-token"/);
65
+ const authorizedShellText = await authorizedShell.text();
66
+ assert.match(authorizedShellText, /Object\.defineProperty\(window,key/);
67
+ assert.match(authorizedShellText, /\}\)\("relay-token",document\.currentScript\)/);
66
68
 
67
69
  const expectedAssets = new Map([
68
70
  ["relay.css", /^text\/css/],
@@ -11,6 +11,7 @@ import { pathMayCarryEntityRefs, requestEntityCanonicalIdReconcile } from "./ent
11
11
  import { withRawEntityPageMutation } from "./entity-canonical-id-lock.js";
12
12
  import { readMaybeEncryptedFileFromChunks, writeMaybeEncryptedFileFromChunks } from "../secure-store/secure-fs.js";
13
13
  import * as archiveMutation from "../archive-mutation-version.js";
14
+ import { invalidationCommitFingerprint } from "./deletion-revision-store.js";
14
15
  import {
15
16
  buildExplicitCaptureDedupKey,
16
17
  buildCapturePathLockIdentity,
@@ -236,6 +237,36 @@ export abstract class TombstoneBlockedCaptureIndexHost {
236
237
  return await this.getTombstoneBlockedCaptureIndex().withCaptureWriteLock(task, identity);
237
238
  }
238
239
 
240
+ /** Read selected memories while their mutation locks remain held. */
241
+ async readMemorySnapshotsIfUnchanged(expected: readonly MemoryFile[]): Promise<MemoryFile[] | null> {
242
+ return await this.withMemorySnapshotsIfUnchanged(expected, async (memories) => memories);
243
+ }
244
+
245
+ async withMemorySnapshotsIfUnchanged<T>(
246
+ expected: readonly MemoryFile[],
247
+ task: (memories: MemoryFile[]) => Promise<T>,
248
+ ): Promise<T | null> {
249
+ if (expected.length === 0) return await task([]);
250
+ const pathnames = [...new Set(expected.map((memory) => memory.path))];
251
+ if (pathnames.length !== expected.length) return null;
252
+ return await this.withTombstoneBlockedCaptureWriteLock(async () => {
253
+ const current = await Promise.all(pathnames.map((pathname) => this.readMemoryByPath(pathname)));
254
+ for (let index = 0; index < expected.length; index += 1) {
255
+ const actual = current[index];
256
+ const snapshot = expected[index];
257
+ if (
258
+ !actual ||
259
+ !snapshot ||
260
+ actual.frontmatter.id !== snapshot.frontmatter.id ||
261
+ invalidationCommitFingerprint(actual) !== invalidationCommitFingerprint(snapshot)
262
+ ) {
263
+ return null;
264
+ }
265
+ }
266
+ return await task(current as MemoryFile[]);
267
+ }, pathnames.map(buildCapturePathLockIdentity));
268
+ }
269
+
239
270
  protected async withTombstoneBlockedCaptureWriteLockAndHashes<T>(
240
271
  task: () => Promise<T>,
241
272
  identity: string | readonly string[] | undefined,
@@ -52,6 +52,108 @@ test("failure-semantics: getMemoryById on empty store returns null (not throw)",
52
52
  }
53
53
  });
54
54
 
55
+ test("failure-semantics: selected memory snapshots reject a changed member", async () => {
56
+ const { storage, cleanup } = await makeStorage();
57
+ try {
58
+ const first = await storage.writeMemory("preference", "First source");
59
+ const second = await storage.writeMemory("preference", "Second source");
60
+ const firstSnapshot = await storage.readMemoryByPath(first.memory.path);
61
+ const secondSnapshot = await storage.readMemoryByPath(second.memory.path);
62
+ assert.ok(firstSnapshot);
63
+ assert.ok(secondSnapshot);
64
+ assert.equal(await storage.updateMemory(second.id, "Changed source"), true);
65
+
66
+ assert.equal(await storage.readMemorySnapshotsIfUnchanged([firstSnapshot, secondSnapshot]), null);
67
+ assert.deepEqual(
68
+ (await storage.readMemorySnapshotsIfUnchanged([firstSnapshot]))?.map((memory) => memory.frontmatter.id),
69
+ [first.id]
70
+ );
71
+ } finally {
72
+ await cleanup();
73
+ }
74
+ });
75
+
76
+ test("failure-semantics: selected memory snapshots block member writes until every read completes", async () => {
77
+ const { storage, cleanup } = await makeStorage();
78
+ const secondReadStarted = Promise.withResolvers<void>();
79
+ const releaseSecondRead = Promise.withResolvers<void>();
80
+ try {
81
+ const first = await storage.writeMemory("preference", "First source");
82
+ const second = await storage.writeMemory("preference", "Second source");
83
+ const firstSnapshot = await storage.readMemoryByPath(first.memory.path);
84
+ const secondSnapshot = await storage.readMemoryByPath(second.memory.path);
85
+ assert.ok(firstSnapshot);
86
+ assert.ok(secondSnapshot);
87
+ const readMemoryByPath = storage.readMemoryByPath.bind(storage);
88
+ let pauseSecond = true;
89
+ storage.readMemoryByPath = async (filePath) => {
90
+ const memory = await readMemoryByPath(filePath);
91
+ if (pauseSecond && filePath === second.memory.path) {
92
+ pauseSecond = false;
93
+ secondReadStarted.resolve();
94
+ await releaseSecondRead.promise;
95
+ }
96
+ return memory;
97
+ };
98
+
99
+ const snapshotPromise = storage.readMemorySnapshotsIfUnchanged([firstSnapshot, secondSnapshot]);
100
+ await secondReadStarted.promise;
101
+ let writeSettled = false;
102
+ const writePromise = storage.updateMemory(first.id, "Changed source").finally(() => {
103
+ writeSettled = true;
104
+ });
105
+ await new Promise<void>((resolve) => setImmediate(resolve));
106
+ assert.equal(writeSettled, false);
107
+
108
+ releaseSecondRead.resolve();
109
+ assert.deepEqual(
110
+ (await snapshotPromise)?.map((memory) => memory.frontmatter.id),
111
+ [first.id, second.id]
112
+ );
113
+ assert.equal(await writePromise, true);
114
+ } finally {
115
+ releaseSecondRead.resolve();
116
+ await cleanup();
117
+ }
118
+ });
119
+
120
+ test("failure-semantics: selected memory snapshot tasks hold every member lock", async () => {
121
+ const { storage, cleanup } = await makeStorage();
122
+ const taskStarted = Promise.withResolvers<void>();
123
+ const releaseTask = Promise.withResolvers<void>();
124
+ try {
125
+ const first = await storage.writeMemory("preference", "First source");
126
+ const second = await storage.writeMemory("preference", "Second source");
127
+ const firstSnapshot = await storage.readMemoryByPath(first.memory.path);
128
+ const secondSnapshot = await storage.readMemoryByPath(second.memory.path);
129
+ assert.ok(firstSnapshot);
130
+ assert.ok(secondSnapshot);
131
+
132
+ const snapshotTask = storage.withMemorySnapshotsIfUnchanged(
133
+ [firstSnapshot, secondSnapshot],
134
+ async (memories) => {
135
+ taskStarted.resolve();
136
+ await releaseTask.promise;
137
+ return memories.map((memory) => memory.frontmatter.id);
138
+ },
139
+ );
140
+ await taskStarted.promise;
141
+ let writeSettled = false;
142
+ const writePromise = storage.updateMemoryIfUnchanged(firstSnapshot, "Changed source").finally(() => {
143
+ writeSettled = true;
144
+ });
145
+ await new Promise<void>((resolve) => setImmediate(resolve));
146
+ assert.equal(writeSettled, false);
147
+
148
+ releaseTask.resolve();
149
+ assert.deepEqual(await snapshotTask, [first.id, second.id]);
150
+ assert.equal(await writePromise, true);
151
+ } finally {
152
+ releaseTask.resolve();
153
+ await cleanup();
154
+ }
155
+ });
156
+
55
157
  test("failure-semantics: readMemoryByPath on a non-existent file returns null (not throw)", async () => {
56
158
  const { storage, baseDir, cleanup } = await makeStorage();
57
159
  try {
@@ -0,0 +1,143 @@
1
+ import type { IncomingMessage, ServerResponse } from "node:http";
2
+ import path from "node:path";
3
+
4
+ import { EngramAccessForbiddenError } from "../access-errors.js";
5
+ import type { EngramAccessService } from "../access-service.js";
6
+ import { enforceNamespaceAllowList, tokenCapabilityStore } from "../access-token-capabilities.js";
7
+ import type { WriteRateLimitReservation } from "../write-rate-limiter.js";
8
+ import { handleSupportPassportOwnerHttp } from "./access-http.js";
9
+ import { buildSupportPassportPublicRequestHandler } from "./public-http.js";
10
+
11
+ const SUPPORT_PASSPORT_QUOTA_LIMITED_WRITE_TOOLS = new Set([
12
+ "engram.support_passport_draft_create",
13
+ "remnic.support_passport_draft_create",
14
+ "engram.support_passport_drafts_generate",
15
+ "remnic.support_passport_drafts_generate",
16
+ "engram.support_passport_card_replace",
17
+ "remnic.support_passport_card_replace",
18
+ "engram.support_passport_card_approve",
19
+ "remnic.support_passport_card_approve",
20
+ "engram.support_passport_card_reject",
21
+ "remnic.support_passport_card_reject",
22
+ "engram.support_passport_card_withdraw",
23
+ "remnic.support_passport_card_withdraw",
24
+ "engram.support_passport_grant_create",
25
+ "remnic.support_passport_grant_create",
26
+ "engram.support_passport_grant_revoke",
27
+ "remnic.support_passport_grant_revoke",
28
+ ]);
29
+ const SUPPORT_PASSPORT_ADMIN_CONSOLE_ASSETS = new Map<string, string>([
30
+ ["what-helps-me.css", "text/css; charset=utf-8"],
31
+ ["model.js", "application/javascript; charset=utf-8"],
32
+ ["app.js", "application/javascript; charset=utf-8"],
33
+ ]);
34
+
35
+ export abstract class SupportPassportAccessHttpBase {
36
+ private supportPassportPublicHandler: ReturnType<typeof buildSupportPassportPublicRequestHandler> | undefined;
37
+ protected abstract readonly service: EngramAccessService;
38
+ protected abstract readonly adminConsolePublicDir: string;
39
+ protected abstract resolveRequestPrincipal(req: IncomingMessage): string | undefined;
40
+ protected abstract readJsonBody(req: IncomingMessage, maxBodyBytes?: number): Promise<Record<string, unknown>>;
41
+ protected abstract respondJson(res: ServerResponse, status: number, payload: unknown): void;
42
+ protected abstract reserveWriteRateLimitSlot(req?: IncomingMessage): WriteRateLimitReservation;
43
+ protected abstract respondAdminConsoleShell(
44
+ req: IncomingMessage,
45
+ res: ServerResponse,
46
+ pathname: string,
47
+ relativePath?: string,
48
+ allowPrefill?: boolean,
49
+ ): Promise<void>;
50
+ protected abstract respondStatic(res: ServerResponse, filePath: string, contentType: string): Promise<void>;
51
+
52
+ protected handleSupportPassportOwnerRequest(
53
+ req: IncomingMessage,
54
+ res: ServerResponse,
55
+ pathname: string,
56
+ hasQuery: boolean,
57
+ abortSignal: AbortSignal
58
+ ): Promise<boolean> {
59
+ return handleSupportPassportOwnerHttp({
60
+ req,
61
+ res,
62
+ pathname,
63
+ hasQuery,
64
+ service: this.service,
65
+ principal: this.resolveRequestPrincipal(req),
66
+ abortSignal,
67
+ readJsonBody: () => this.readJsonBody(req),
68
+ respondJson: (status, payload) => {
69
+ res.setHeader("cache-control", "private, no-store");
70
+ res.setHeader("vary", "Authorization");
71
+ this.respondJson(res, status, payload);
72
+ },
73
+ reserveWriteRateLimitSlot: () => this.reserveWriteRateLimitSlot(req),
74
+ });
75
+ }
76
+
77
+ protected handleSupportPassportPublicRequest(req: IncomingMessage, res: ServerResponse): Promise<boolean> {
78
+ this.supportPassportPublicHandler ??= buildSupportPassportPublicRequestHandler(this.service, {
79
+ trustedProxyAddresses: this.service.configRef?.supportPassport?.trustedProxyAddresses ?? [],
80
+ });
81
+ return this.supportPassportPublicHandler(req, res, {
82
+ authorized: false,
83
+ tokenAuthorized: false,
84
+ });
85
+ }
86
+
87
+ protected async enforceSupportPassportAuthorizationProbe(req: IncomingMessage): Promise<void> {
88
+ const principal = this.resolveRequestPrincipal(req)?.trim();
89
+ if (!principal) {
90
+ throw new EngramAccessForbiddenError("A trusted principal is required for support passport access.");
91
+ }
92
+ const owner = await this.service.getWritableStorageForNamespace(undefined, principal);
93
+ enforceNamespaceAllowList(
94
+ tokenCapabilityStore.getStore(),
95
+ owner.namespace,
96
+ this.service.configRef.defaultNamespace
97
+ );
98
+ }
99
+
100
+ protected isSupportPassportQuotaLimitedWriteTool(toolName: string): boolean {
101
+ return SUPPORT_PASSPORT_QUOTA_LIMITED_WRITE_TOOLS.has(toolName);
102
+ }
103
+
104
+ protected async handleSupportPassportUi(
105
+ req: IncomingMessage,
106
+ res: ServerResponse,
107
+ pathname: string
108
+ ): Promise<boolean> {
109
+ if (req.method !== "GET") return false;
110
+ const isSupportPassportPath =
111
+ pathname === "/remnic/ui/what-helps-me" ||
112
+ pathname === "/engram/ui/what-helps-me" ||
113
+ pathname.startsWith("/remnic/ui/what-helps-me/") ||
114
+ pathname.startsWith("/engram/ui/what-helps-me/");
115
+ if (!isSupportPassportPath) return false;
116
+ if (!this.service.supportPassportEnabled) {
117
+ this.respondJson(res, 404, { error: "not_found" });
118
+ return true;
119
+ }
120
+ if (pathname === "/remnic/ui/what-helps-me" || pathname === "/engram/ui/what-helps-me") {
121
+ const search = new URL(req.url ?? pathname, "http://placeholder").search;
122
+ res.statusCode = 301;
123
+ res.setHeader("location", `${pathname}/${search}`);
124
+ res.end();
125
+ return true;
126
+ }
127
+ if (pathname === "/remnic/ui/what-helps-me/" || pathname === "/engram/ui/what-helps-me/") {
128
+ const helperRequest = new URL(req.url ?? pathname, "http://placeholder").searchParams.has("grant");
129
+ res.setHeader("content-security-policy", "frame-ancestors 'none'");
130
+ res.setHeader("x-frame-options", "DENY");
131
+ await this.respondAdminConsoleShell(req, res, pathname, "what-helps-me/index.html", !helperRequest);
132
+ return true;
133
+ }
134
+ const fileName = pathname.split("/").at(-1) ?? "";
135
+ const assetType = SUPPORT_PASSPORT_ADMIN_CONSOLE_ASSETS.get(fileName);
136
+ if (assetType && pathname.split("/").length === 5) {
137
+ await this.respondStatic(res, path.join(this.adminConsolePublicDir, "what-helps-me", fileName), assetType);
138
+ return true;
139
+ }
140
+ this.respondJson(res, 404, { error: "not_found" });
141
+ return true;
142
+ }
143
+ }
@@ -0,0 +1,172 @@
1
+ import type { IncomingMessage, ServerResponse } from "node:http";
2
+
3
+ import { type OperationName, getOperation } from "../access-boundary.js";
4
+ import type { EngramAccessService } from "../access-service.js";
5
+ import { SupportPassportError } from "./errors.js";
6
+ import { SupportPassportOwnerCreateGrantRequestSchema } from "./grant-contracts.js";
7
+
8
+ export interface SupportPassportOwnerHttpDependencies {
9
+ req: IncomingMessage;
10
+ res: ServerResponse;
11
+ pathname: string;
12
+ hasQuery: boolean;
13
+ service: EngramAccessService;
14
+ principal?: string;
15
+ abortSignal: AbortSignal;
16
+ readJsonBody(): Promise<Record<string, unknown>>;
17
+ respondJson(status: number, payload: unknown): void;
18
+ reserveWriteRateLimitSlot(): { commit(): void; release(): void };
19
+ }
20
+
21
+ const OWNER_ROOT = "/engram/v1/support-passport";
22
+
23
+ export const SUPPORT_PASSPORT_OWNER_HTTP_ROUTES = [
24
+ { method: "GET", pathname: `${OWNER_ROOT}/cards`, operation: "support_passport_cards_list" },
25
+ { method: "POST", pathname: `${OWNER_ROOT}/drafts`, operation: "support_passport_draft_create" },
26
+ { method: "POST", pathname: `${OWNER_ROOT}/drafts/generate`, operation: "support_passport_drafts_generate" },
27
+ { method: "GET", pathname: `${OWNER_ROOT}/grants`, operation: "support_passport_grants_list" },
28
+ { method: "POST", pathname: `${OWNER_ROOT}/grants`, operation: "support_passport_grant_create" },
29
+ { method: "GET", pathname: `${OWNER_ROOT}/memories/:id`, operation: "support_passport_memory_preview" },
30
+ { method: "PUT", pathname: `${OWNER_ROOT}/cards/:id`, operation: "support_passport_card_replace" },
31
+ { method: "POST", pathname: `${OWNER_ROOT}/cards/:id/approve`, operation: "support_passport_card_approve" },
32
+ { method: "POST", pathname: `${OWNER_ROOT}/cards/:id/reject`, operation: "support_passport_card_reject" },
33
+ { method: "POST", pathname: `${OWNER_ROOT}/cards/:id/withdraw`, operation: "support_passport_card_withdraw" },
34
+ { method: "POST", pathname: `${OWNER_ROOT}/grants/:id/revoke`, operation: "support_passport_grant_revoke" },
35
+ ] as const satisfies ReadonlyArray<{ method: string; pathname: string; operation: OperationName }>;
36
+
37
+ function decodeId(value: string, label: string): string {
38
+ try {
39
+ return decodeURIComponent(value);
40
+ } catch {
41
+ throw new SupportPassportError("invalid_input", `${label} is invalid.`, 400);
42
+ }
43
+ }
44
+
45
+ function closeUnreadRequestAfterResponse(req: IncomingMessage, res: ServerResponse): void {
46
+ const contentLength = req.headers["content-length"];
47
+ const declaresBody =
48
+ req.headers["transfer-encoding"] !== undefined ||
49
+ (contentLength !== undefined && contentLength !== "0");
50
+ if (!declaresBody || req.readableEnded || req.destroyed) return;
51
+ res.shouldKeepAlive = false;
52
+ res.setHeader("connection", "close");
53
+ res.once("finish", () => req.destroy());
54
+ }
55
+
56
+ async function runOperation(
57
+ name: OperationName,
58
+ input: Record<string, unknown>,
59
+ dependencies: SupportPassportOwnerHttpDependencies,
60
+ recordWriteCommit?: () => void
61
+ ): Promise<unknown> {
62
+ const operation = getOperation(name);
63
+ if (!operation) throw new Error(`access-boundary: operation not registered: ${name}`);
64
+ const output = (await operation.run(input, {
65
+ service: dependencies.service,
66
+ authenticatedPrincipal: dependencies.principal,
67
+ abortSignal: dependencies.abortSignal,
68
+ ...(recordWriteCommit ? { hooks: { recordWriteCommit } } : {}),
69
+ })) as { result: unknown };
70
+ return output.result;
71
+ }
72
+
73
+ async function runWrite(
74
+ name: OperationName,
75
+ input: Record<string, unknown>,
76
+ dependencies: SupportPassportOwnerHttpDependencies
77
+ ): Promise<unknown> {
78
+ const writeQuota = dependencies.reserveWriteRateLimitSlot();
79
+ try {
80
+ const result = await runOperation(name, input, dependencies, writeQuota.commit);
81
+ writeQuota.commit();
82
+ return result;
83
+ } catch (error) {
84
+ writeQuota.release();
85
+ throw error;
86
+ }
87
+ }
88
+
89
+ export async function handleSupportPassportOwnerHttp(
90
+ dependencies: SupportPassportOwnerHttpDependencies
91
+ ): Promise<boolean> {
92
+ const { req, pathname } = dependencies;
93
+ try {
94
+ let operation: OperationName | undefined;
95
+ let input: Record<string, unknown> = {};
96
+ let quotaLimitedWrite = false;
97
+
98
+ if (req.method === "GET" && pathname === `${OWNER_ROOT}/cards`) {
99
+ operation = "support_passport_cards_list";
100
+ } else if (req.method === "POST" && pathname === `${OWNER_ROOT}/drafts`) {
101
+ operation = "support_passport_draft_create";
102
+ quotaLimitedWrite = true;
103
+ } else if (req.method === "POST" && pathname === `${OWNER_ROOT}/drafts/generate`) {
104
+ operation = "support_passport_drafts_generate";
105
+ quotaLimitedWrite = true;
106
+ } else if (pathname === `${OWNER_ROOT}/grants` && req.method === "GET") {
107
+ operation = "support_passport_grants_list";
108
+ } else if (pathname === `${OWNER_ROOT}/grants` && req.method === "POST") {
109
+ operation = "support_passport_grant_create";
110
+ quotaLimitedWrite = true;
111
+ } else {
112
+ const memoryMatch = new RegExp(`^${OWNER_ROOT}/memories/([^/]+)$`).exec(pathname);
113
+ const cardMatch = new RegExp(`^${OWNER_ROOT}/cards/([^/]+)(?:/(approve|reject|withdraw))?$`).exec(pathname);
114
+ const grantMatch = new RegExp(`^${OWNER_ROOT}/grants/([^/]+)/revoke$`).exec(pathname);
115
+ if (memoryMatch && req.method === "GET") {
116
+ operation = "support_passport_memory_preview";
117
+ input.memoryId = decodeId(memoryMatch[1] ?? "", "memoryId");
118
+ } else if (cardMatch && req.method === "PUT" && !cardMatch[2]) {
119
+ operation = "support_passport_card_replace";
120
+ input.cardId = decodeId(cardMatch[1] ?? "", "cardId");
121
+ quotaLimitedWrite = true;
122
+ } else if (cardMatch && req.method === "POST" && cardMatch[2]) {
123
+ operation = `support_passport_card_${cardMatch[2]}` as OperationName;
124
+ input.cardId = decodeId(cardMatch[1] ?? "", "cardId");
125
+ quotaLimitedWrite = true;
126
+ } else if (grantMatch && req.method === "POST") {
127
+ operation = "support_passport_grant_revoke";
128
+ input.grantId = decodeId(grantMatch[1] ?? "", "grantId");
129
+ quotaLimitedWrite = true;
130
+ }
131
+ }
132
+
133
+ if (!operation) return false;
134
+ dependencies.res.setHeader("cache-control", "private, no-store");
135
+ dependencies.res.setHeader("vary", "Authorization");
136
+ if (dependencies.hasQuery) {
137
+ throw new SupportPassportError("invalid_input", "Support passport routes do not accept query values.", 400);
138
+ }
139
+ if (req.method !== "GET") {
140
+ const body = await dependencies.readJsonBody();
141
+ for (const pathField of Object.keys(input)) {
142
+ if (Object.hasOwn(body, pathField)) {
143
+ throw new SupportPassportError("invalid_input", `${pathField} belongs in the URL path.`, 400);
144
+ }
145
+ }
146
+ input = { ...input, ...body };
147
+ }
148
+ if (operation === "support_passport_drafts_generate" && !Object.hasOwn(input, "sourceMemoryRevisions")) {
149
+ throw new SupportPassportError("invalid_input", "Review the selected notes again before drafting.", 400);
150
+ }
151
+ if (operation === "support_passport_grant_create") {
152
+ const grant = SupportPassportOwnerCreateGrantRequestSchema.safeParse(input);
153
+ if (!grant.success) throw new SupportPassportError("invalid_input", "The share link request is invalid.", 400);
154
+ input = {
155
+ cardIds: grant.data.cardIds,
156
+ cardRevisions: grant.data.cardRevisions,
157
+ ...(grant.data.expiresAt !== undefined
158
+ ? { expiresAt: grant.data.expiresAt }
159
+ : { durationMs: grant.data.durationMs }),
160
+ };
161
+ }
162
+ const result = quotaLimitedWrite
163
+ ? await runWrite(operation, input, dependencies)
164
+ : await runOperation(operation, input, dependencies);
165
+ dependencies.respondJson(200, result);
166
+ } catch (error) {
167
+ if (!(error instanceof SupportPassportError)) throw error;
168
+ closeUnreadRequestAfterResponse(req, dependencies.res);
169
+ dependencies.respondJson(error.status, { error: error.message, code: error.code });
170
+ }
171
+ return true;
172
+ }