@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,601 @@
1
+ import { createHash } from "node:crypto";
2
+ import type { IncomingMessage, ServerResponse } from "node:http";
3
+ import { isIP } from "node:net";
4
+
5
+ import { abortError, isAbortError } from "../abort-error.js";
6
+ import { type OperationName, getOperation } from "../access-boundary.js";
7
+ import type { EngramAccessService } from "../access-service.js";
8
+ import { SupportPassportError } from "./errors.js";
9
+
10
+ const PUBLIC_RATE_LIMIT_MAX_KEYS = 20_000;
11
+ const PUBLIC_AUTH_MAX_IN_FLIGHT_PER_NETWORK = 8;
12
+ const PUBLIC_AUTH_MAX_IN_FLIGHT_TOTAL = 256;
13
+ const PUBLIC_MODEL_MAX_IN_FLIGHT_PER_NETWORK = 8;
14
+ const PUBLIC_MODEL_MAX_IN_FLIGHT_TOTAL = 256;
15
+
16
+ export const SUPPORT_PASSPORT_PUBLIC_HTTP_ROUTES = [
17
+ {
18
+ method: "GET",
19
+ pathname: "/engram/v1/support-passport/public/grants/:id",
20
+ operation: "support_passport_grant_read",
21
+ },
22
+ {
23
+ method: "POST",
24
+ pathname: "/engram/v1/support-passport/public/grants/:id/ask",
25
+ operation: "support_passport_grant_ask",
26
+ },
27
+ ] as const satisfies ReadonlyArray<{ method: string; pathname: string; operation: OperationName }>;
28
+
29
+ export type SupportPassportExternalRequestHandler = (
30
+ req: IncomingMessage,
31
+ res: ServerResponse,
32
+ ctx: {
33
+ authorized: boolean;
34
+ tokenAuthorized: boolean;
35
+ }
36
+ ) => Promise<boolean>;
37
+
38
+ interface WindowEntry {
39
+ count: number;
40
+ resetAt: number;
41
+ }
42
+
43
+ interface WindowReservation {
44
+ commit(): void;
45
+ release(): void;
46
+ }
47
+
48
+ class UnreadSupportPassportRequestError extends Error {
49
+ constructor(readonly response: SupportPassportError) {
50
+ super(response.message);
51
+ this.name = "UnreadSupportPassportRequestError";
52
+ }
53
+ }
54
+
55
+ class FixedWindowLimiter {
56
+ private readonly entries = new Map<string, WindowEntry>();
57
+
58
+ constructor(
59
+ private readonly limit: number,
60
+ private readonly windowMs: number,
61
+ private readonly now: () => number
62
+ ) {}
63
+
64
+ consume(key: string): boolean {
65
+ const reservation = this.reserve(key);
66
+ if (!reservation) return false;
67
+ reservation.commit();
68
+ return true;
69
+ }
70
+
71
+ reserve(key: string): WindowReservation | undefined {
72
+ const now = this.now();
73
+ let entry = this.entries.get(key);
74
+ if (!entry || entry.resetAt <= now) {
75
+ if (!entry && this.entries.size >= PUBLIC_RATE_LIMIT_MAX_KEYS) {
76
+ this.prune(now);
77
+ if (this.entries.size >= PUBLIC_RATE_LIMIT_MAX_KEYS) return undefined;
78
+ }
79
+ entry = { count: 0, resetAt: now + this.windowMs };
80
+ this.entries.set(key, entry);
81
+ }
82
+ if (entry.count >= this.limit) return undefined;
83
+ entry.count += 1;
84
+ let active = true;
85
+ return {
86
+ commit: () => {
87
+ active = false;
88
+ },
89
+ release: () => {
90
+ if (!active) return;
91
+ active = false;
92
+ if (this.entries.get(key) !== entry) return;
93
+ entry.count -= 1;
94
+ if (entry.count === 0) this.entries.delete(key);
95
+ },
96
+ };
97
+ }
98
+
99
+ allows(key: string): boolean {
100
+ const now = this.now();
101
+ const current = this.entries.get(key);
102
+ if (current && current.resetAt > now) return current.count < this.limit;
103
+ if (!current && this.entries.size >= PUBLIC_RATE_LIMIT_MAX_KEYS) {
104
+ this.prune(now);
105
+ if (this.entries.size >= PUBLIC_RATE_LIMIT_MAX_KEYS) return false;
106
+ }
107
+ return true;
108
+ }
109
+
110
+ private prune(now: number): void {
111
+ for (const [key, entry] of this.entries) {
112
+ if (entry.resetAt <= now) this.entries.delete(key);
113
+ }
114
+ }
115
+ }
116
+
117
+ class InFlightLimiter {
118
+ private readonly counts = new Map<string, number>();
119
+ private total = 0;
120
+
121
+ constructor(
122
+ private readonly perKeyLimit: number,
123
+ private readonly totalLimit: number
124
+ ) {}
125
+
126
+ reserve(key: string): (() => void) | undefined {
127
+ const current = this.counts.get(key) ?? 0;
128
+ if (current >= this.perKeyLimit || this.total >= this.totalLimit) return undefined;
129
+ this.counts.set(key, current + 1);
130
+ this.total += 1;
131
+ let active = true;
132
+ return () => {
133
+ if (!active) return;
134
+ active = false;
135
+ const count = this.counts.get(key) ?? 0;
136
+ if (count <= 1) this.counts.delete(key);
137
+ else this.counts.set(key, count - 1);
138
+ this.total -= 1;
139
+ };
140
+ }
141
+ }
142
+
143
+ interface PublicRateLimits {
144
+ authentications: InFlightLimiter;
145
+ modelCalls: InFlightLimiter;
146
+ grantReads: FixedWindowLimiter;
147
+ networkReads: FixedWindowLimiter;
148
+ networkReadFailures: FixedWindowLimiter;
149
+ grantQuestions: FixedWindowLimiter;
150
+ networkQuestions: FixedWindowLimiter;
151
+ networkQuestionFailures: FixedWindowLimiter;
152
+ }
153
+
154
+ export interface SupportPassportPublicHandlerOptions {
155
+ now?: () => number;
156
+ trustedProxyAddresses?: readonly string[];
157
+ }
158
+
159
+ function createRateLimits(now: () => number): PublicRateLimits {
160
+ return {
161
+ authentications: new InFlightLimiter(PUBLIC_AUTH_MAX_IN_FLIGHT_PER_NETWORK, PUBLIC_AUTH_MAX_IN_FLIGHT_TOTAL),
162
+ modelCalls: new InFlightLimiter(PUBLIC_MODEL_MAX_IN_FLIGHT_PER_NETWORK, PUBLIC_MODEL_MAX_IN_FLIGHT_TOTAL),
163
+ grantReads: new FixedWindowLimiter(60, 60_000, now),
164
+ networkReads: new FixedWindowLimiter(60, 60_000, now),
165
+ networkReadFailures: new FixedWindowLimiter(60, 60_000, now),
166
+ grantQuestions: new FixedWindowLimiter(20, 10 * 60_000, now),
167
+ networkQuestions: new FixedWindowLimiter(20, 10 * 60_000, now),
168
+ networkQuestionFailures: new FixedWindowLimiter(20, 10 * 60_000, now),
169
+ };
170
+ }
171
+
172
+ function rateLimited(): SupportPassportError {
173
+ return new SupportPassportError("rate_limited", "Too many helper requests.", 429);
174
+ }
175
+
176
+ async function runPublicOperation(
177
+ service: EngramAccessService,
178
+ name: "support_passport_grant_read" | "support_passport_grant_ask",
179
+ input: Record<string, unknown>,
180
+ signal?: AbortSignal
181
+ ): Promise<unknown> {
182
+ const operation = getOperation(name);
183
+ if (!operation) throw new Error(`access-boundary: operation not registered: ${name}`);
184
+ const output = (await operation.run(input, {
185
+ service,
186
+ ...(signal ? { abortSignal: signal } : {}),
187
+ })) as { result: unknown };
188
+ return output.result;
189
+ }
190
+
191
+ function reserveAuthenticatedLimits(
192
+ networkLimiter: FixedWindowLimiter,
193
+ grantLimiter: FixedWindowLimiter,
194
+ networkKey: string,
195
+ grantId: string
196
+ ): WindowReservation {
197
+ const network = networkLimiter.reserve(networkKey);
198
+ if (!network) throw rateLimited();
199
+ const grant = grantLimiter.reserve(grantId);
200
+ if (!grant) {
201
+ network.release();
202
+ throw rateLimited();
203
+ }
204
+ let active = true;
205
+ return {
206
+ commit: () => {
207
+ if (!active) return;
208
+ active = false;
209
+ network.commit();
210
+ grant.commit();
211
+ },
212
+ release: () => {
213
+ if (!active) return;
214
+ active = false;
215
+ grant.release();
216
+ network.release();
217
+ },
218
+ };
219
+ }
220
+
221
+ async function readGrantUnderAuthenticationReservation(
222
+ service: EngramAccessService,
223
+ grantId: string,
224
+ secret: string,
225
+ networkKey: string,
226
+ networkLimiter: FixedWindowLimiter,
227
+ grantLimiter: FixedWindowLimiter,
228
+ failureLimiter: FixedWindowLimiter
229
+ ) {
230
+ if (!failureLimiter.allows(networkKey)) throw rateLimited();
231
+ const limits = reserveAuthenticatedLimits(networkLimiter, grantLimiter, networkKey, grantId);
232
+ let guide: Awaited<ReturnType<EngramAccessService["supportPassportReadGrant"]>>;
233
+ try {
234
+ guide = (await runPublicOperation(service, "support_passport_grant_read", { grantId, secret })) as Awaited<
235
+ ReturnType<EngramAccessService["supportPassportReadGrant"]>
236
+ >;
237
+ } catch (error) {
238
+ if (error instanceof SupportPassportError) {
239
+ if (error.code === "grant_not_found") {
240
+ limits.release();
241
+ if (!failureLimiter.consume(networkKey)) throw rateLimited();
242
+ } else {
243
+ limits.commit();
244
+ }
245
+ } else {
246
+ limits.release();
247
+ }
248
+ throw error;
249
+ }
250
+ limits.commit();
251
+ return guide;
252
+ }
253
+
254
+ async function readGrantWithRateLimits(
255
+ service: EngramAccessService,
256
+ grantId: string,
257
+ secret: string,
258
+ networkKey: string,
259
+ networkLimiter: FixedWindowLimiter,
260
+ grantLimiter: FixedWindowLimiter,
261
+ failureLimiter: FixedWindowLimiter,
262
+ authenticationLimiter: InFlightLimiter
263
+ ) {
264
+ const releaseAuthentication = authenticationLimiter.reserve(networkKey);
265
+ if (!releaseAuthentication) throw rateLimited();
266
+ try {
267
+ return await readGrantUnderAuthenticationReservation(
268
+ service,
269
+ grantId,
270
+ secret,
271
+ networkKey,
272
+ networkLimiter,
273
+ grantLimiter,
274
+ failureLimiter
275
+ );
276
+ } finally {
277
+ releaseAuthentication();
278
+ }
279
+ }
280
+
281
+ export function normalizeSupportPassportNetworkAddress(value: string | undefined): string | undefined {
282
+ if (!value) return undefined;
283
+ const address = value.trim().toLowerCase();
284
+ const family = isIP(address);
285
+ if (family === 0) return undefined;
286
+ if (family === 4) return address;
287
+ const canonical = new URL(`http://[${address}]/`).hostname.slice(1, -1);
288
+ const mapped = /^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/.exec(canonical);
289
+ if (!mapped) return canonical;
290
+ const high = Number.parseInt(mapped[1] ?? "", 16);
291
+ const low = Number.parseInt(mapped[2] ?? "", 16);
292
+ return `${high >>> 8}.${high & 0xff}.${low >>> 8}.${low & 0xff}`;
293
+ }
294
+
295
+ function requestNetworkAddress(req: IncomingMessage, trustedProxyAddresses: ReadonlySet<string>): string {
296
+ const directAddress = normalizeSupportPassportNetworkAddress(req.socket.remoteAddress) ?? "unknown";
297
+ if (!trustedProxyAddresses.has(directAddress)) return directAddress;
298
+ const forwarded = req.headers["x-forwarded-for"];
299
+ if (typeof forwarded !== "string") return directAddress;
300
+ const rawAddresses = forwarded.split(",");
301
+ if (rawAddresses.length < 1 || rawAddresses.length > 32) return directAddress;
302
+ const addresses = rawAddresses.map((address) => normalizeSupportPassportNetworkAddress(address));
303
+ if (addresses.some((address) => address === undefined)) return directAddress;
304
+ for (let index = addresses.length - 1; index >= 0; index -= 1) {
305
+ const address = addresses[index];
306
+ if (address && !trustedProxyAddresses.has(address)) return address;
307
+ }
308
+ return addresses[0] ?? directAddress;
309
+ }
310
+
311
+ function networkDigest(req: IncomingMessage, trustedProxyAddresses: ReadonlySet<string>): string {
312
+ return createHash("sha256")
313
+ .update(requestNetworkAddress(req, trustedProxyAddresses))
314
+ .digest("hex");
315
+ }
316
+
317
+ function parseSecret(req: IncomingMessage): string | undefined {
318
+ const raw = req.headers.authorization;
319
+ if (typeof raw !== "string") return undefined;
320
+ const match = /^(\S+)[ \t]+(\S+)$/.exec(raw);
321
+ if (!match || match[1]?.toLowerCase() !== "supportpassport") return undefined;
322
+ const secret = match[2] ?? "";
323
+ if (!/^[A-Za-z0-9_-]{32,256}$/.test(secret)) return undefined;
324
+ return secret;
325
+ }
326
+
327
+ function requestDeclaresBody(req: IncomingMessage): boolean {
328
+ const contentLength = req.headers["content-length"];
329
+ const transferEncoding = req.headers["transfer-encoding"];
330
+ return transferEncoding !== undefined || (contentLength !== undefined && contentLength !== "0");
331
+ }
332
+
333
+ function respondJson(res: ServerResponse, status: number, payload: unknown): void {
334
+ const body = JSON.stringify(payload);
335
+ res.statusCode = status;
336
+ res.setHeader("cache-control", "private, no-store");
337
+ res.setHeader("vary", "Authorization");
338
+ res.setHeader("content-type", "application/json; charset=utf-8");
339
+ res.setHeader("content-length", String(Buffer.byteLength(body)));
340
+ res.end(body);
341
+ }
342
+
343
+ function respondJsonAndCloseUnreadRequest(
344
+ req: IncomingMessage,
345
+ res: ServerResponse,
346
+ status: number,
347
+ payload: unknown
348
+ ): void {
349
+ res.shouldKeepAlive = false;
350
+ res.setHeader("connection", "close");
351
+ res.once("finish", () => req.destroy());
352
+ respondJson(res, status, payload);
353
+ }
354
+
355
+ function respondBeforeReadingBody(
356
+ req: IncomingMessage,
357
+ res: ServerResponse,
358
+ status: number,
359
+ payload: unknown
360
+ ): void {
361
+ if (requestDeclaresBody(req)) {
362
+ respondJsonAndCloseUnreadRequest(req, res, status, payload);
363
+ return;
364
+ }
365
+ respondJson(res, status, payload);
366
+ }
367
+
368
+ async function readQuestionBody(req: IncomingMessage, signal: AbortSignal): Promise<string> {
369
+ const content = await new Promise<Buffer>((resolve, reject) => {
370
+ const chunks: Buffer[] = [];
371
+ let bytes = 0;
372
+ let settled = false;
373
+ const cleanup = () => {
374
+ req.off("data", onData);
375
+ req.off("end", onEnd);
376
+ req.off("error", onError);
377
+ req.off("aborted", onAborted);
378
+ signal.removeEventListener("abort", onSignalAbort);
379
+ };
380
+ const fail = (error: unknown) => {
381
+ if (settled) return;
382
+ settled = true;
383
+ cleanup();
384
+ reject(error);
385
+ };
386
+ const helperLeft = () =>
387
+ isAbortError(signal.reason) ? signal.reason : abortError("The helper left.");
388
+ const onData = (chunk: Buffer | string) => {
389
+ const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
390
+ bytes += buffer.length;
391
+ if (bytes > 4_096) {
392
+ req.pause();
393
+ fail(
394
+ new UnreadSupportPassportRequestError(
395
+ new SupportPassportError("invalid_input", "The helper question is invalid.", 400)
396
+ )
397
+ );
398
+ return;
399
+ }
400
+ chunks.push(buffer);
401
+ };
402
+ const onEnd = () => {
403
+ if (settled) return;
404
+ settled = true;
405
+ cleanup();
406
+ resolve(Buffer.concat(chunks, bytes));
407
+ };
408
+ const onError = (error: Error) => fail(signal.aborted || req.aborted ? helperLeft() : error);
409
+ const onAborted = () => fail(helperLeft());
410
+ const onSignalAbort = () => fail(helperLeft());
411
+ req.on("data", onData);
412
+ req.once("end", onEnd);
413
+ req.once("error", onError);
414
+ req.once("aborted", onAborted);
415
+ signal.addEventListener("abort", onSignalAbort, { once: true });
416
+ if (signal.aborted) onSignalAbort();
417
+ });
418
+ let parsed: unknown;
419
+ try {
420
+ parsed = JSON.parse(content.toString("utf8"));
421
+ } catch {
422
+ throw new SupportPassportError("invalid_input", "The helper question is invalid.", 400);
423
+ }
424
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
425
+ throw new SupportPassportError("invalid_input", "The helper question is invalid.", 400);
426
+ }
427
+ const body = parsed as Record<string, unknown>;
428
+ if (Object.keys(body).length !== 1 || typeof body.question !== "string") {
429
+ throw new SupportPassportError("invalid_input", "The helper question is invalid.", 400);
430
+ }
431
+ const question = body.question.trim();
432
+ if (question.length < 1 || question.length > 500) {
433
+ throw new SupportPassportError("invalid_input", "The helper question is invalid.", 400);
434
+ }
435
+ return question;
436
+ }
437
+
438
+ function requestSignal(req: IncomingMessage, res: ServerResponse): { signal: AbortSignal; cleanup(): void } {
439
+ const controller = new AbortController();
440
+ const abort = () => {
441
+ if (!res.writableFinished && !controller.signal.aborted) controller.abort(abortError("The helper left."));
442
+ };
443
+ req.once("aborted", abort);
444
+ res.once("close", abort);
445
+ return {
446
+ signal: controller.signal,
447
+ cleanup: () => {
448
+ req.off("aborted", abort);
449
+ res.off("close", abort);
450
+ },
451
+ };
452
+ }
453
+
454
+ function decodeGrantId(raw: string): string | undefined {
455
+ try {
456
+ const value = decodeURIComponent(raw);
457
+ return /^[A-Za-z0-9_-]{1,128}$/.test(value) ? value.toLowerCase() : undefined;
458
+ } catch {
459
+ return undefined;
460
+ }
461
+ }
462
+
463
+ export function buildSupportPassportPublicRequestHandler(
464
+ service: EngramAccessService,
465
+ options: SupportPassportPublicHandlerOptions = {}
466
+ ): SupportPassportExternalRequestHandler {
467
+ const rateLimits = createRateLimits(options.now ?? Date.now);
468
+ const trustedProxyAddresses = new Set(
469
+ (options.trustedProxyAddresses ?? [])
470
+ .map((address) => normalizeSupportPassportNetworkAddress(address))
471
+ .filter((address): address is string => address !== undefined)
472
+ );
473
+ return async (req, res) => {
474
+ let parsed: URL;
475
+ try {
476
+ parsed = new URL(req.url ?? "/", "http://placeholder");
477
+ } catch {
478
+ return false;
479
+ }
480
+ const readMatch = /^\/engram\/v1\/support-passport\/public\/grants\/([^/]+)$/.exec(parsed.pathname);
481
+ const askMatch = /^\/engram\/v1\/support-passport\/public\/grants\/([^/]+)\/ask$/.exec(parsed.pathname);
482
+ const ownedRead = req.method === "GET" && readMatch;
483
+ const ownedQuestion = req.method === "POST" && askMatch;
484
+ if (!ownedRead && !ownedQuestion) return false;
485
+
486
+ res.setHeader("cache-control", "private, no-store");
487
+ res.setHeader("vary", "Authorization");
488
+ const grantId = decodeGrantId((ownedRead ? readMatch?.[1] : askMatch?.[1]) ?? "");
489
+ const secret = parseSecret(req);
490
+ if (parsed.search.length > 0) {
491
+ respondBeforeReadingBody(req, res, 400, {
492
+ error: "The share link request is invalid.",
493
+ code: "invalid_input",
494
+ });
495
+ return true;
496
+ }
497
+ if (ownedRead && requestDeclaresBody(req)) {
498
+ respondJsonAndCloseUnreadRequest(req, res, 400, {
499
+ error: "The share link request is invalid.",
500
+ code: "invalid_input",
501
+ });
502
+ return true;
503
+ }
504
+ if (!grantId || !secret) {
505
+ respondBeforeReadingBody(req, res, 404, {
506
+ error: "The share link was not found.",
507
+ code: "grant_not_found",
508
+ });
509
+ return true;
510
+ }
511
+
512
+ const lifecycle = requestSignal(req, res);
513
+ try {
514
+ const digest = networkDigest(req, trustedProxyAddresses);
515
+ if (ownedRead) {
516
+ const guide = await readGrantWithRateLimits(
517
+ service,
518
+ grantId,
519
+ secret,
520
+ digest,
521
+ rateLimits.networkReads,
522
+ rateLimits.grantReads,
523
+ rateLimits.networkReadFailures,
524
+ rateLimits.authentications
525
+ );
526
+ respondJson(res, 200, guide);
527
+ } else {
528
+ let releaseAuthentication = rateLimits.authentications.reserve(digest);
529
+ if (!releaseAuthentication) throw new UnreadSupportPassportRequestError(rateLimited());
530
+ try {
531
+ let question: string;
532
+ const bodyFailure = rateLimits.networkQuestionFailures.reserve(digest);
533
+ if (!bodyFailure) throw new UnreadSupportPassportRequestError(rateLimited());
534
+ try {
535
+ question = await readQuestionBody(req, lifecycle.signal);
536
+ bodyFailure.release();
537
+ } catch (error) {
538
+ const supportError =
539
+ error instanceof UnreadSupportPassportRequestError ? error.response : error;
540
+ if (supportError instanceof SupportPassportError && supportError.code === "invalid_input") {
541
+ bodyFailure.commit();
542
+ } else {
543
+ bodyFailure.release();
544
+ }
545
+ throw error;
546
+ }
547
+ const releaseModelCall = rateLimits.modelCalls.reserve(digest);
548
+ if (!releaseModelCall) throw rateLimited();
549
+ try {
550
+ await readGrantUnderAuthenticationReservation(
551
+ service,
552
+ grantId,
553
+ secret,
554
+ digest,
555
+ rateLimits.networkQuestions,
556
+ rateLimits.grantQuestions,
557
+ rateLimits.networkQuestionFailures
558
+ );
559
+ releaseAuthentication();
560
+ releaseAuthentication = undefined;
561
+ const answer = await runPublicOperation(
562
+ service,
563
+ "support_passport_grant_ask",
564
+ { grantId, secret, question },
565
+ lifecycle.signal
566
+ );
567
+ respondJson(res, 200, answer);
568
+ } finally {
569
+ releaseModelCall();
570
+ }
571
+ } finally {
572
+ releaseAuthentication?.();
573
+ }
574
+ }
575
+ } catch (error) {
576
+ if (error instanceof UnreadSupportPassportRequestError) {
577
+ respondJsonAndCloseUnreadRequest(req, res, error.response.status, {
578
+ error: error.response.message,
579
+ code: error.response.code,
580
+ });
581
+ return true;
582
+ }
583
+ if (!(error instanceof SupportPassportError)) throw error;
584
+ respondJson(res, error.status, { error: error.message, code: error.code });
585
+ } finally {
586
+ lifecycle.cleanup();
587
+ }
588
+ return true;
589
+ };
590
+ }
591
+
592
+ export function composeSupportPassportExternalRequestHandlers(
593
+ ...handlers: Array<SupportPassportExternalRequestHandler | undefined>
594
+ ): SupportPassportExternalRequestHandler {
595
+ return async (req, res, ctx) => {
596
+ for (const handler of handlers) {
597
+ if (handler && (await handler(req, res, ctx))) return true;
598
+ }
599
+ return false;
600
+ };
601
+ }