@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,840 @@
1
+ import assert from "node:assert/strict";
2
+ import { readFile } from "node:fs/promises";
3
+ import { test } from "node:test";
4
+
5
+ import { parseConfig } from "../config.js";
6
+ import { SupportPassportError } from "./errors.js";
7
+ import {
8
+ SupportPassportModelAdapter,
9
+ acceptsSupportPassportModelResponse,
10
+ type SupportPassportModelClients,
11
+ type SupportPassportModelRoute,
12
+ buildSupportPassportDirectGatewayConfig,
13
+ createSupportPassportModelAdapter,
14
+ resolveSupportPassportModelRoutePlan,
15
+ } from "./model-adapter.js";
16
+ import { SUPPORT_PASSPORT_NOT_IN_GUIDE_ANSWER } from "./model-contracts.js";
17
+
18
+ function route(
19
+ kind: SupportPassportModelRoute["kind"],
20
+ content: string | null,
21
+ calls: string[]
22
+ ): SupportPassportModelRoute {
23
+ return {
24
+ kind,
25
+ invoke: async () => {
26
+ calls.push(kind);
27
+ return content === null ? null : { content, modelUsed: `${kind}/test-model` };
28
+ },
29
+ };
30
+ }
31
+
32
+ test("the cross-process response check rejects invented draft and answer citations", () => {
33
+ const draftMessages = [
34
+ { role: "system" as const, content: "Return JSON." },
35
+ {
36
+ role: "user" as const,
37
+ content: JSON.stringify({ sourceNotes: [{ memoryId: "memory-1", content: "Source" }] }),
38
+ },
39
+ ];
40
+ assert.equal(
41
+ acceptsSupportPassportModelResponse(
42
+ "support-passport-draft",
43
+ draftMessages,
44
+ JSON.stringify({
45
+ cards: [{
46
+ title: "Plan changes",
47
+ statement: "Tell me before plans change.",
48
+ category: "transitions",
49
+ sourceMemoryIds: ["invented"],
50
+ }],
51
+ }),
52
+ ),
53
+ false,
54
+ );
55
+ const answerMessages = [
56
+ { role: "system" as const, content: "Return JSON." },
57
+ {
58
+ role: "user" as const,
59
+ content: JSON.stringify({ cards: [{ cardId: "card-1" }], question: "What helps?" }),
60
+ },
61
+ ];
62
+ assert.equal(
63
+ acceptsSupportPassportModelResponse(
64
+ "support-passport-answer",
65
+ answerMessages,
66
+ JSON.stringify({ answer: "Use another card.", citedCardIds: ["invented"], coverage: "grounded" }),
67
+ ),
68
+ false,
69
+ );
70
+ });
71
+
72
+ test("draft generation retries the full job after invalid output", async () => {
73
+ const calls: string[] = [];
74
+ const adapter = new SupportPassportModelAdapter({
75
+ routes: [
76
+ route(
77
+ "local",
78
+ JSON.stringify({
79
+ cards: [
80
+ {
81
+ title: "Bad source",
82
+ statement: "Tell me before plans change.",
83
+ category: "transitions",
84
+ sourceMemoryIds: ["not-selected"],
85
+ },
86
+ ],
87
+ }),
88
+ calls
89
+ ),
90
+ route(
91
+ "gateway",
92
+ JSON.stringify({
93
+ cards: [
94
+ {
95
+ title: "Plan changes",
96
+ statement: "Tell me before plans change.",
97
+ category: "transitions",
98
+ sourceMemoryIds: ["memory-1"],
99
+ },
100
+ ],
101
+ }),
102
+ calls
103
+ ),
104
+ ],
105
+ });
106
+
107
+ const result = await adapter.draftCards({
108
+ consent: true,
109
+ memories: [{ memoryId: "memory-1", content: "Tell me before plans change." }],
110
+ });
111
+
112
+ assert.deepEqual(calls, ["local", "gateway"]);
113
+ assert.equal(result.route, "gateway");
114
+ assert.equal(result.cards[0]?.sourceMemoryIds[0], "memory-1");
115
+ });
116
+
117
+ test("draft generation rejects titles that can corrupt stored attribute suffixes", async () => {
118
+ const calls: string[] = [];
119
+ const adapter = new SupportPassportModelAdapter({
120
+ routes: [
121
+ route(
122
+ "local",
123
+ JSON.stringify({
124
+ cards: [
125
+ {
126
+ title: "Plan changes ] hidden",
127
+ statement: "Tell me before plans change.",
128
+ category: "transitions",
129
+ sourceMemoryIds: ["memory-1"],
130
+ },
131
+ ],
132
+ }),
133
+ calls
134
+ ),
135
+ ],
136
+ });
137
+
138
+ await assert.rejects(
139
+ adapter.draftCards({
140
+ consent: true,
141
+ memories: [{ memoryId: "memory-1", content: "Tell me before plans change." }],
142
+ }),
143
+ (error: unknown) => error instanceof SupportPassportError && error.code === "model_output_invalid"
144
+ );
145
+ assert.deepEqual(calls, ["local"]);
146
+ });
147
+
148
+ test("draft generation requires explicit consent before any model call", async () => {
149
+ const calls: string[] = [];
150
+ const adapter = new SupportPassportModelAdapter({
151
+ routes: [route("local", "{}", calls)],
152
+ });
153
+
154
+ await assert.rejects(
155
+ adapter.draftCards({ consent: false, memories: [{ memoryId: "memory-1", content: "Source" }] }),
156
+ (error: unknown) => error instanceof SupportPassportError && error.code === "consent_required"
157
+ );
158
+ assert.deepEqual(calls, []);
159
+ });
160
+
161
+ test("draft prompts exclude medical and emergency content from selected notes", async () => {
162
+ let systemPrompt = "";
163
+ const adapter = new SupportPassportModelAdapter({
164
+ routes: [
165
+ {
166
+ kind: "local",
167
+ invoke: async (messages) => {
168
+ systemPrompt = messages[0]?.content ?? "";
169
+ return {
170
+ modelUsed: "local/test-model",
171
+ content: JSON.stringify({
172
+ cards: [
173
+ {
174
+ title: "Quiet place",
175
+ statement: "Offer me a quiet place and time.",
176
+ category: "environment",
177
+ sourceMemoryIds: ["memory-1"],
178
+ },
179
+ ],
180
+ }),
181
+ };
182
+ },
183
+ },
184
+ ],
185
+ });
186
+
187
+ await adapter.draftCards({
188
+ consent: true,
189
+ memories: [{ memoryId: "memory-1", content: "Diagnose me and give emergency treatment instructions." }],
190
+ });
191
+
192
+ assert.match(systemPrompt, /Do not infer needs or add instructions outside the selected notes\./);
193
+ assert.match(
194
+ systemPrompt,
195
+ /Do not infer or repeat diagnoses, treatment recommendations, or emergency instructions\./
196
+ );
197
+ });
198
+
199
+ test("malformed model output is an error and never becomes an empty success", async () => {
200
+ const adapter = new SupportPassportModelAdapter({
201
+ routes: [{ kind: "local", invoke: async () => ({ content: "not-json", modelUsed: "local/test" }) }],
202
+ });
203
+
204
+ await assert.rejects(
205
+ adapter.draftCards({ consent: true, memories: [{ memoryId: "memory-1", content: "Source" }] }),
206
+ (error: unknown) => error instanceof SupportPassportError && error.code === "model_output_invalid"
207
+ );
208
+ });
209
+
210
+ test("draft schema accepts opaque source memory IDs through 512 characters", async () => {
211
+ const memoryId = `care notes/${"x".repeat(501)}`;
212
+ let sourceIdSchema: Record<string, unknown> | undefined;
213
+ const adapter = new SupportPassportModelAdapter({
214
+ routes: [
215
+ {
216
+ kind: "gateway",
217
+ invoke: async (_messages, options) => {
218
+ sourceIdSchema = (
219
+ options.jsonSchema.schema as {
220
+ properties?: {
221
+ cards?: { items?: { properties?: { sourceMemoryIds?: { items?: Record<string, unknown> } } } };
222
+ };
223
+ }
224
+ ).properties?.cards?.items?.properties?.sourceMemoryIds?.items;
225
+ return {
226
+ content: JSON.stringify({
227
+ cards: [
228
+ {
229
+ title: "Plan changes",
230
+ statement: "Tell me before plans change.",
231
+ category: "transitions",
232
+ sourceMemoryIds: [memoryId],
233
+ },
234
+ ],
235
+ }),
236
+ modelUsed: "gateway/test",
237
+ };
238
+ },
239
+ },
240
+ ],
241
+ });
242
+
243
+ const result = await adapter.draftCards({ consent: true, memories: [{ memoryId, content: "Selected note" }] });
244
+
245
+ assert.equal(result.cards[0]?.sourceMemoryIds[0], memoryId);
246
+ assert.deepEqual(sourceIdSchema, { type: "string", minLength: 1, maxLength: 512 });
247
+ });
248
+
249
+ test("provider-neutral prompts include every category and the exact uncovered answer", async () => {
250
+ const systemPrompts: Record<string, string> = {};
251
+ const adapter = new SupportPassportModelAdapter({
252
+ routes: [
253
+ {
254
+ kind: "local",
255
+ invoke: async (messages, options) => {
256
+ systemPrompts[options.operation] = messages.find((message) => message.role === "system")?.content ?? "";
257
+ return {
258
+ content:
259
+ options.operation === "support-passport-draft"
260
+ ? JSON.stringify({
261
+ cards: [
262
+ {
263
+ title: "Plan changes",
264
+ statement: "Tell me before plans change.",
265
+ category: "transitions",
266
+ sourceMemoryIds: ["memory-1"],
267
+ },
268
+ ],
269
+ })
270
+ : JSON.stringify({
271
+ answer: SUPPORT_PASSPORT_NOT_IN_GUIDE_ANSWER,
272
+ citedCardIds: [],
273
+ coverage: "not_in_guide",
274
+ }),
275
+ modelUsed: "local/test",
276
+ };
277
+ },
278
+ },
279
+ ],
280
+ });
281
+
282
+ await adapter.draftCards({
283
+ consent: true,
284
+ memories: [{ memoryId: "memory-1", content: "Tell me before plans change." }],
285
+ });
286
+ await adapter.answerQuestion({
287
+ guide: {
288
+ schemaVersion: 1,
289
+ grantId: "00000000-0000-4000-8000-000000000001",
290
+ expiresAt: "2026-08-11T13:00:00.000Z",
291
+ updatedAt: "2026-08-11T12:00:00.000Z",
292
+ cards: [
293
+ {
294
+ cardId: "card-1",
295
+ title: "Quiet space",
296
+ statement: "Offer me a quiet place and time.",
297
+ category: "environment",
298
+ updatedAt: "2026-08-11T12:00:00.000Z",
299
+ },
300
+ ],
301
+ },
302
+ question: "What food helps?",
303
+ });
304
+
305
+ assert.match(
306
+ systemPrompts["support-passport-draft"] ?? "",
307
+ /communication, environment, transitions, sensory, regulation, interests, or other/
308
+ );
309
+ assert.ok(systemPrompts["support-passport-answer"]?.includes(SUPPORT_PASSPORT_NOT_IN_GUIDE_ANSWER));
310
+ });
311
+
312
+ test("helper answers cite only shared cards and use the exact uncovered fallback", async () => {
313
+ const guide = {
314
+ schemaVersion: 1 as const,
315
+ grantId: "00000000-0000-4000-8000-000000000001",
316
+ expiresAt: "2026-08-11T13:00:00.000Z",
317
+ updatedAt: "2026-08-11T12:00:00.000Z",
318
+ cards: [
319
+ {
320
+ cardId: "card-1",
321
+ title: "Quiet space",
322
+ statement: "Offer me a quiet place and time.",
323
+ category: "environment" as const,
324
+ updatedAt: "2026-08-11T12:00:00.000Z",
325
+ },
326
+ ],
327
+ };
328
+ const adapter = new SupportPassportModelAdapter({
329
+ routes: [
330
+ {
331
+ kind: "gateway",
332
+ invoke: async () => ({
333
+ content: JSON.stringify({ answer: "Offer a quiet place.", citedCardIds: ["card-1"], coverage: "grounded" }),
334
+ modelUsed: "gateway/test",
335
+ }),
336
+ },
337
+ ],
338
+ });
339
+ const grounded = await adapter.answerQuestion({ guide, question: "What can help?" });
340
+ assert.deepEqual(grounded.answer, "Offer a quiet place.");
341
+ assert.deepEqual(grounded.citedCardIds, ["card-1"]);
342
+
343
+ const uncovered = new SupportPassportModelAdapter({
344
+ routes: [
345
+ {
346
+ kind: "local",
347
+ invoke: async () => ({
348
+ content: JSON.stringify({
349
+ answer: "That is not covered in this person's support guide.",
350
+ citedCardIds: [],
351
+ coverage: "not_in_guide",
352
+ }),
353
+ modelUsed: "local/test",
354
+ }),
355
+ },
356
+ ],
357
+ });
358
+ assert.equal((await uncovered.answerQuestion({ guide, question: "What food helps?" })).coverage, "not_in_guide");
359
+ });
360
+
361
+ test("helper model calls send only shared cards and the question", async () => {
362
+ const guide = {
363
+ schemaVersion: 1 as const,
364
+ grantId: "00000000-0000-4000-8000-000000000001",
365
+ expiresAt: "2026-08-11T13:00:00.000Z",
366
+ updatedAt: "2026-08-11T12:00:00.000Z",
367
+ cards: [
368
+ {
369
+ cardId: "card-1",
370
+ title: "Quiet space",
371
+ statement: "Offer me a quiet place and time.",
372
+ category: "environment" as const,
373
+ updatedAt: "2026-08-11T12:00:00.000Z",
374
+ },
375
+ ],
376
+ };
377
+ let payload: unknown;
378
+ const adapter = new SupportPassportModelAdapter({
379
+ routes: [
380
+ {
381
+ kind: "gateway",
382
+ invoke: async (messages) => {
383
+ payload = JSON.parse(messages.find((message) => message.role === "user")?.content ?? "null");
384
+ return {
385
+ content: JSON.stringify({
386
+ answer: "Offer a quiet place.",
387
+ citedCardIds: ["card-1"],
388
+ coverage: "grounded",
389
+ }),
390
+ modelUsed: "gateway/test",
391
+ };
392
+ },
393
+ },
394
+ ],
395
+ });
396
+
397
+ await adapter.answerQuestion({ guide, question: "What can help?" });
398
+
399
+ assert.deepEqual(payload, { cards: guide.cards, question: "What can help?" });
400
+ });
401
+
402
+ test("helper answer output rejects foreign citations and invented uncovered answers", async () => {
403
+ const guide = {
404
+ schemaVersion: 1 as const,
405
+ grantId: "00000000-0000-4000-8000-000000000001",
406
+ expiresAt: "2026-08-11T13:00:00.000Z",
407
+ updatedAt: "2026-08-11T12:00:00.000Z",
408
+ cards: [
409
+ {
410
+ cardId: "card-1",
411
+ title: "Quiet space",
412
+ statement: "Offer me a quiet place and time.",
413
+ category: "environment" as const,
414
+ updatedAt: "2026-08-11T12:00:00.000Z",
415
+ },
416
+ ],
417
+ };
418
+ for (const output of [
419
+ { answer: "Use another card.", citedCardIds: ["card-2"], coverage: "grounded" },
420
+ { answer: "I do not know.", citedCardIds: [], coverage: "not_in_guide" },
421
+ ]) {
422
+ const adapter = new SupportPassportModelAdapter({
423
+ routes: [
424
+ { kind: "gateway", invoke: async () => ({ content: JSON.stringify(output), modelUsed: "gateway/test" }) },
425
+ ],
426
+ });
427
+ await assert.rejects(
428
+ adapter.answerQuestion({ guide, question: "What helps?" }),
429
+ (error: unknown) => error instanceof SupportPassportError && error.code === "model_output_invalid"
430
+ );
431
+ }
432
+ });
433
+
434
+ test("route planning preserves Remnic model-source and local fallback rules", () => {
435
+ assert.deepEqual(
436
+ resolveSupportPassportModelRoutePlan(
437
+ {
438
+ modelSource: "gateway",
439
+ localLlmEnabled: true,
440
+ localLlmFallback: true,
441
+ openaiApiKey: "direct-key",
442
+ },
443
+ { gateway: true }
444
+ ),
445
+ ["gateway"]
446
+ );
447
+ assert.deepEqual(
448
+ resolveSupportPassportModelRoutePlan(
449
+ {
450
+ modelSource: "plugin",
451
+ localLlmEnabled: true,
452
+ localLlmFallback: true,
453
+ openaiApiKey: "direct-key",
454
+ },
455
+ { gateway: true }
456
+ ),
457
+ ["local", "direct", "gateway"]
458
+ );
459
+ assert.deepEqual(
460
+ resolveSupportPassportModelRoutePlan(
461
+ {
462
+ modelSource: "plugin",
463
+ localLlmEnabled: true,
464
+ localLlmFallback: false,
465
+ openaiApiKey: "direct-key",
466
+ },
467
+ { gateway: true }
468
+ ),
469
+ ["local"]
470
+ );
471
+ assert.deepEqual(
472
+ resolveSupportPassportModelRoutePlan(
473
+ {
474
+ modelSource: "gateway",
475
+ localLlmEnabled: false,
476
+ localLlmFallback: false,
477
+ openaiApiKey: undefined,
478
+ },
479
+ { gateway: false }
480
+ ),
481
+ []
482
+ );
483
+ });
484
+
485
+ test("local support models work with direct OpenAI disabled", async () => {
486
+ let optionsSeen: Record<string, unknown> | undefined;
487
+ const localLlm = {
488
+ chatCompletion: async (_messages: unknown, options: Record<string, unknown>) => {
489
+ optionsSeen = options;
490
+ return {
491
+ content: JSON.stringify({
492
+ cards: [
493
+ {
494
+ title: "Plan changes",
495
+ statement: "Tell me before plans change.",
496
+ category: "transitions",
497
+ sourceMemoryIds: ["memory-1"],
498
+ },
499
+ ],
500
+ }),
501
+ };
502
+ },
503
+ } as unknown as NonNullable<SupportPassportModelClients["localLlm"]>;
504
+ const adapter = createSupportPassportModelAdapter(
505
+ parseConfig({
506
+ openaiApiKey: false,
507
+ localLlmEnabled: true,
508
+ localLlmFallback: false,
509
+ localLlmModel: "local-test-model",
510
+ localLlmTimeoutMs: 180_000,
511
+ }),
512
+ { localLlm }
513
+ );
514
+
515
+ const result = await adapter.draftCards({
516
+ consent: true,
517
+ memories: [{ memoryId: "memory-1", content: "Tell me before plans change." }],
518
+ });
519
+
520
+ assert.equal(result.route, "local");
521
+ assert.equal(result.modelUsed, "local/local-test-model");
522
+ assert.deepEqual(optionsSeen?.responseFormat, { type: "json_object" });
523
+ assert.equal(optionsSeen?.timeoutMs, 180_000);
524
+ assert.equal(optionsSeen?.redactProviderErrors, true);
525
+ });
526
+
527
+ test("gateway support models work with direct OpenAI disabled", async () => {
528
+ let optionsSeen: Record<string, unknown> | undefined;
529
+ const gatewayRoute: NonNullable<SupportPassportModelClients["gatewayRoute"]> = {
530
+ kind: "gateway",
531
+ invoke: async (_messages, options) => {
532
+ optionsSeen = options;
533
+ return {
534
+ content: JSON.stringify({
535
+ cards: [
536
+ {
537
+ title: "Plan changes",
538
+ statement: "Tell me before plans change.",
539
+ category: "transitions",
540
+ sourceMemoryIds: ["memory-1"],
541
+ },
542
+ ],
543
+ }),
544
+ modelUsed: "gateway/test-model",
545
+ };
546
+ },
547
+ };
548
+ const adapter = createSupportPassportModelAdapter(
549
+ parseConfig({
550
+ modelSource: "gateway",
551
+ openaiApiKey: false,
552
+ gatewayConfig: {
553
+ agents: { defaults: { model: { primary: "gateway/test-model" } } },
554
+ models: {
555
+ providers: {
556
+ gateway: {
557
+ baseUrl: "https://models.example.test/v1",
558
+ api: "openai-completions",
559
+ models: [{ id: "test-model", name: "test-model" }],
560
+ },
561
+ },
562
+ },
563
+ },
564
+ }),
565
+ { gatewayRoute }
566
+ );
567
+
568
+ const result = await adapter.draftCards({
569
+ consent: true,
570
+ memories: [{ memoryId: "memory-1", content: "Tell me before plans change." }],
571
+ });
572
+
573
+ assert.equal(result.route, "gateway");
574
+ assert.equal(result.modelUsed, "gateway/test-model");
575
+ assert.equal(optionsSeen?.timeoutMs, 30_000);
576
+ assert.equal((optionsSeen?.jsonSchema as { name?: string } | undefined)?.name, "support_passport_drafts");
577
+ });
578
+
579
+ test("gateway model chains preserve invalid output when a later fallback times out", async () => {
580
+ const adapter = new SupportPassportModelAdapter({
581
+ timeoutMs: 20,
582
+ routes: [
583
+ {
584
+ kind: "gateway",
585
+ invoke: async (_messages, options) => {
586
+ const rejected = {
587
+ content: JSON.stringify({ cards: [] }),
588
+ modelUsed: "gateway/primary",
589
+ usage: { totalTokens: 12 },
590
+ };
591
+ assert.equal(options.acceptResponse?.(rejected), false);
592
+ return await new Promise<never>((_resolve, reject) => {
593
+ options.signal?.addEventListener("abort", () => reject(options.signal?.reason), { once: true });
594
+ });
595
+ },
596
+ },
597
+ ],
598
+ });
599
+
600
+ await assert.rejects(
601
+ adapter.draftCards({ consent: true, memories: [{ memoryId: "memory-1", content: "Source" }] }),
602
+ (error: unknown) =>
603
+ error instanceof SupportPassportError &&
604
+ error.code === "model_output_invalid" &&
605
+ "metadata" in error &&
606
+ (error.metadata as { modelUsed?: string; usage?: { totalTokens?: number } }).modelUsed === "gateway/primary" &&
607
+ (error.metadata as { usage?: { totalTokens?: number } }).usage?.totalTokens === 12
608
+ );
609
+ });
610
+
611
+ test("direct OpenAI models use the existing Responses API transport", () => {
612
+ const config = buildSupportPassportDirectGatewayConfig({
613
+ openaiApiKey: "test-key",
614
+ openaiBaseUrl: undefined,
615
+ model: "test-model",
616
+ });
617
+ assert.deepEqual(config?.models?.providers?.["remnic-direct"], {
618
+ baseUrl: "https://api.openai.com/v1",
619
+ apiKey: "test-key",
620
+ api: "openai-responses",
621
+ models: [{ id: "test-model", name: "test-model" }],
622
+ });
623
+ });
624
+
625
+ test("direct model routing rejects whitespace-only API keys", () => {
626
+ assert.deepEqual(
627
+ resolveSupportPassportModelRoutePlan({
628
+ modelSource: "plugin",
629
+ localLlmEnabled: false,
630
+ localLlmFallback: false,
631
+ openaiApiKey: " ",
632
+ }),
633
+ []
634
+ );
635
+ assert.equal(
636
+ buildSupportPassportDirectGatewayConfig({
637
+ openaiApiKey: " ",
638
+ openaiBaseUrl: undefined,
639
+ model: "test-model",
640
+ }),
641
+ undefined
642
+ );
643
+ });
644
+
645
+ test("direct OpenAI route detection ignores repeated trailing slashes", () => {
646
+ const config = buildSupportPassportDirectGatewayConfig({
647
+ openaiApiKey: "test-key",
648
+ openaiBaseUrl: "https://api.openai.com/v1////",
649
+ model: "test-model",
650
+ });
651
+ assert.equal(config?.models?.providers?.["remnic-direct"]?.api, "openai-responses");
652
+ assert.equal(config?.models?.providers?.["remnic-direct"]?.baseUrl, "https://api.openai.com/v1");
653
+ });
654
+
655
+ test("direct compatible APIs keep their configured fallback transport", () => {
656
+ const config = buildSupportPassportDirectGatewayConfig({
657
+ openaiApiKey: "test-key",
658
+ openaiBaseUrl: "https://models.example.test/v1",
659
+ model: "test-model",
660
+ });
661
+ assert.equal(config?.agents?.defaults?.model?.primary, "remnic-direct/test-model");
662
+ assert.deepEqual(config?.models?.providers?.["remnic-direct"], {
663
+ baseUrl: "https://models.example.test/v1",
664
+ apiKey: "test-key",
665
+ api: "openai-completions",
666
+ models: [{ id: "test-model", name: "test-model" }],
667
+ });
668
+ });
669
+
670
+ test("direct compatible APIs reject base URLs with credentials, queries, or fragments", () => {
671
+ for (const openaiBaseUrl of [
672
+ "https://user:password@models.example.test/v1",
673
+ "https://models.example.test/v1?token=secret",
674
+ "https://models.example.test/v1#endpoint",
675
+ ]) {
676
+ assert.equal(
677
+ buildSupportPassportDirectGatewayConfig({
678
+ openaiApiKey: "test-key",
679
+ openaiBaseUrl,
680
+ model: "test-model",
681
+ }),
682
+ undefined
683
+ );
684
+ }
685
+ });
686
+
687
+ test(
688
+ "direct OpenAI requests use the shared Responses transport without storage or tools",
689
+ { concurrency: false },
690
+ async () => {
691
+ const originalFetch = globalThis.fetch;
692
+ let requestUrl = "";
693
+ let requestBody: Record<string, unknown> = {};
694
+ globalThis.fetch = (async (url, init) => {
695
+ requestUrl = String(url);
696
+ requestBody = JSON.parse(String(init?.body ?? "{}")) as Record<string, unknown>;
697
+ return new Response(
698
+ JSON.stringify({
699
+ output_text: JSON.stringify({
700
+ cards: [
701
+ {
702
+ title: "Plan changes",
703
+ statement: "Tell me before plans change.",
704
+ category: "transitions",
705
+ sourceMemoryIds: ["memory-1"],
706
+ },
707
+ ],
708
+ }),
709
+ usage: { input_tokens: 10, output_tokens: 12, total_tokens: 22 },
710
+ }),
711
+ { status: 200, headers: { "content-type": "application/json" } }
712
+ );
713
+ }) as typeof fetch;
714
+ try {
715
+ const adapter = createSupportPassportModelAdapter(
716
+ parseConfig({
717
+ modelSource: "plugin",
718
+ openaiApiKey: "test-key",
719
+ openaiBaseUrl: "https://api.openai.com/v1",
720
+ model: "gpt-test",
721
+ })
722
+ );
723
+ await adapter.draftCards({
724
+ consent: true,
725
+ memories: [{ memoryId: "memory-1", content: "Tell me before plans change." }],
726
+ });
727
+ assert.equal(requestUrl, "https://api.openai.com/v1/responses");
728
+ assert.equal(requestBody.store, false);
729
+ assert.equal(Object.hasOwn(requestBody, "tools"), false);
730
+ assert.equal(Object.hasOwn(requestBody, "parallel_tool_calls"), false);
731
+ const textFormat = (requestBody.text as { format?: Record<string, unknown> } | undefined)?.format;
732
+ assert.equal(textFormat?.type, "json_schema");
733
+ assert.equal(textFormat?.strict, true);
734
+ assert.equal((textFormat?.schema as Record<string, unknown>)?.additionalProperties, false);
735
+ const cards = (textFormat?.schema as { properties?: { cards?: { items?: Record<string, unknown> } } })?.properties
736
+ ?.cards;
737
+ assert.equal(cards?.items?.additionalProperties, false);
738
+ } finally {
739
+ globalThis.fetch = originalFetch;
740
+ }
741
+ }
742
+ );
743
+
744
+ test("missing model routes return provider_unavailable", async () => {
745
+ const adapter = new SupportPassportModelAdapter({ routes: [] });
746
+ await assert.rejects(
747
+ adapter.draftCards({ consent: true, memories: [{ memoryId: "memory-1", content: "Source" }] }),
748
+ (error: unknown) =>
749
+ error instanceof SupportPassportError && error.code === "provider_unavailable" && error.status === 503
750
+ );
751
+ });
752
+
753
+ test("the model deadline aborts provider work", async () => {
754
+ const aborted = Promise.withResolvers<boolean>();
755
+ const adapter = new SupportPassportModelAdapter({
756
+ timeoutMs: 20,
757
+ routes: [
758
+ {
759
+ kind: "gateway",
760
+ invoke: async (_messages, options) =>
761
+ await new Promise<never>((_resolve, reject) => {
762
+ options.signal?.addEventListener(
763
+ "abort",
764
+ () => {
765
+ aborted.resolve(true);
766
+ reject(options.signal?.reason);
767
+ },
768
+ { once: true }
769
+ );
770
+ }),
771
+ },
772
+ ],
773
+ });
774
+
775
+ await assert.rejects(
776
+ adapter.draftCards({ consent: true, memories: [{ memoryId: "memory-1", content: "Source" }] }),
777
+ (error: unknown) => error instanceof SupportPassportError && error.code === "provider_unavailable"
778
+ );
779
+ assert.equal(await aborted.promise, true);
780
+ });
781
+
782
+ test("a timed-out route does not consume the fallback route timeout", async () => {
783
+ const calls: string[] = [];
784
+ const firstRouteAborted = Promise.withResolvers<boolean>();
785
+ const adapter = new SupportPassportModelAdapter({
786
+ timeoutMs: 20,
787
+ routes: [
788
+ {
789
+ kind: "local",
790
+ invoke: async (_messages, options) => {
791
+ calls.push("local");
792
+ return await new Promise<never>((_resolve, reject) => {
793
+ options.signal?.addEventListener(
794
+ "abort",
795
+ () => {
796
+ firstRouteAborted.resolve(true);
797
+ reject(options.signal?.reason);
798
+ },
799
+ { once: true }
800
+ );
801
+ });
802
+ },
803
+ },
804
+ {
805
+ kind: "gateway",
806
+ invoke: async () => {
807
+ calls.push("gateway");
808
+ return {
809
+ modelUsed: "gateway/test-model",
810
+ content: JSON.stringify({
811
+ cards: [
812
+ {
813
+ title: "Plan changes",
814
+ statement: "Tell me before plans change.",
815
+ category: "transitions",
816
+ sourceMemoryIds: ["memory-1"],
817
+ },
818
+ ],
819
+ }),
820
+ };
821
+ },
822
+ },
823
+ ],
824
+ });
825
+
826
+ const result = await adapter.draftCards({
827
+ consent: true,
828
+ memories: [{ memoryId: "memory-1", content: "Tell me before plans change." }],
829
+ });
830
+
831
+ assert.equal(await firstRouteAborted.promise, true);
832
+ assert.deepEqual(calls, ["local", "gateway"]);
833
+ assert.equal(result.route, "gateway");
834
+ });
835
+
836
+ test("the support passport model adapter has no custom OpenAI transport", async () => {
837
+ const source = await readFile(new URL("./model-adapter.ts", import.meta.url), "utf8");
838
+ assert.equal(source.includes('from "openai"'), false);
839
+ assert.equal(source.includes("fetch("), false);
840
+ });