@remnic/core 9.69.60 → 9.69.61

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 (343) hide show
  1. package/dist/access-admin-ops-surface.js +36 -36
  2. package/dist/access-authorization-probe.js +37 -37
  3. package/dist/access-boundary.js +36 -36
  4. package/dist/access-cli.js +93 -93
  5. package/dist/access-extraction-force-flush.js +36 -36
  6. package/dist/access-http-briefing.js +37 -37
  7. package/dist/access-http-query.js +38 -38
  8. package/dist/access-http.js +54 -54
  9. package/dist/access-identity-continuity-surface.js +36 -36
  10. package/dist/access-lcm-surface.js +36 -36
  11. package/dist/access-mcp.js +47 -47
  12. package/dist/access-memory-search-fanout.js +3 -3
  13. package/dist/access-namespace-preflight.js +36 -36
  14. package/dist/access-observe-write-surface.js +36 -36
  15. package/dist/access-offline-manifest.js +6 -6
  16. package/dist/access-operations-batch.js +38 -38
  17. package/dist/access-operations.js +45 -45
  18. package/dist/access-recall-concurrency.js +36 -36
  19. package/dist/access-recall-diagnostics.js +5 -5
  20. package/dist/access-recall-response.js +36 -36
  21. package/dist/access-recall-surface.js +36 -36
  22. package/dist/access-service.js +36 -36
  23. package/dist/access-surface-catalog.js +38 -38
  24. package/dist/active-memory-bridge.js +3 -3
  25. package/dist/active-recall.js +9 -9
  26. package/dist/{auto-sync-CWSZDLLW.js → auto-sync-QJNIKZHV.js} +5 -5
  27. package/dist/briefing.js +8 -8
  28. package/dist/buffer-turn-helpers.d.ts.map +1 -1
  29. package/dist/buffer-turn-helpers.js +1 -1
  30. package/dist/buffer.d.ts.map +1 -1
  31. package/dist/buffer.js +7 -7
  32. package/dist/calibration.js +2 -2
  33. package/dist/capabilities.d.ts +6 -7
  34. package/dist/capabilities.d.ts.map +1 -1
  35. package/dist/capabilities.js +1 -1
  36. package/dist/causal-consolidation.js +9 -9
  37. package/dist/{chunk-6Q3ZTEF6.js → chunk-23G5P7TA.js} +9 -1
  38. package/dist/chunk-23G5P7TA.js.map +1 -0
  39. package/dist/{chunk-RP7TZEI6.js → chunk-2C5Z7CWB.js} +2 -2
  40. package/dist/{chunk-6JYYSDHH.js → chunk-2L5DIVDU.js} +4 -4
  41. package/dist/{chunk-ZLVUWROW.js → chunk-2OUSWDY6.js} +2 -2
  42. package/dist/{chunk-M5IJP3YW.js → chunk-2PKGJPQL.js} +2 -2
  43. package/dist/{chunk-FJMYMJLR.js → chunk-3JDA3XF5.js} +2 -2
  44. package/dist/{chunk-KR5SZNNF.js → chunk-4IFSMCRS.js} +2 -2
  45. package/dist/{chunk-KPKGDQR3.js → chunk-4P3ZBL5E.js} +2 -2
  46. package/dist/{chunk-YUHGJBQK.js → chunk-5LWVTSF7.js} +2 -2
  47. package/dist/{chunk-2T2RF5ZK.js → chunk-5QZHDS4X.js} +5 -5
  48. package/dist/{chunk-DJ4CKWAD.js → chunk-5Y7VCE3A.js} +2 -2
  49. package/dist/{chunk-G2XZFGYN.js → chunk-62JTOLEX.js} +2 -2
  50. package/dist/{chunk-LVXBC6YB.js → chunk-65I2LZEK.js} +2 -2
  51. package/dist/{chunk-NZLFVLLJ.js → chunk-7CRUDH7G.js} +2 -2
  52. package/dist/{chunk-B4EGAHHS.js → chunk-7DE2NOON.js} +2 -2
  53. package/dist/{chunk-BSDBDFKZ.js → chunk-7JFQI6DQ.js} +3 -3
  54. package/dist/{chunk-BOADKFN4.js → chunk-7LNHRQKR.js} +2 -2
  55. package/dist/{chunk-IV6APZJS.js → chunk-7OC3Q5X4.js} +2 -2
  56. package/dist/{chunk-X2QPKLPL.js → chunk-ACX55QDO.js} +3 -3
  57. package/dist/{chunk-YLPCEUXP.js → chunk-AEGQ5PJ7.js} +2 -2
  58. package/dist/{chunk-GK6NOQE6.js → chunk-AERXJCOG.js} +2 -2
  59. package/dist/{chunk-HW2QYZEV.js → chunk-B5GMOOY2.js} +5 -5
  60. package/dist/{chunk-JUOZ62Y7.js → chunk-BMXEBWBT.js} +2 -1
  61. package/dist/chunk-BMXEBWBT.js.map +1 -0
  62. package/dist/{chunk-YHGRA7CK.js → chunk-CDQO5DCD.js} +2 -2
  63. package/dist/{chunk-ENUI3IO7.js → chunk-D433RXFJ.js} +2 -2
  64. package/dist/{chunk-IK63WA5A.js → chunk-D4SPMHEW.js} +2 -2
  65. package/dist/{chunk-IDBLAGIM.js → chunk-DC5CTLCZ.js} +14 -14
  66. package/dist/{chunk-42DJ235G.js → chunk-DINRT75P.js} +2 -2
  67. package/dist/{chunk-LELJRLPY.js → chunk-DQFZOPDL.js} +2 -2
  68. package/dist/{chunk-WN4HFL4K.js → chunk-DQISIT63.js} +2 -2
  69. package/dist/{chunk-Q7KQ5YHT.js → chunk-EIU642TN.js} +2 -2
  70. package/dist/{chunk-EN2YX5SF.js → chunk-F4PEETM4.js} +3 -3
  71. package/dist/{chunk-FNQEXI3D.js → chunk-F5O6WEDO.js} +1 -1
  72. package/dist/{chunk-FNQEXI3D.js.map → chunk-F5O6WEDO.js.map} +1 -1
  73. package/dist/{chunk-Q6C5PIBW.js → chunk-F5ZCNJ3V.js} +3 -3
  74. package/dist/{chunk-42G4FIKQ.js → chunk-FG5QU7A2.js} +4 -4
  75. package/dist/{chunk-IRGQYQQ7.js → chunk-FM5HN7LL.js} +4 -4
  76. package/dist/{chunk-FF2XYADH.js → chunk-FQGY7XB2.js} +6 -6
  77. package/dist/{chunk-FF2XYADH.js.map → chunk-FQGY7XB2.js.map} +1 -1
  78. package/dist/{chunk-R4Y5PF25.js → chunk-FWVDTLRK.js} +1 -1
  79. package/dist/{chunk-C6FQJ52H.js → chunk-G2XTGEGL.js} +65 -18
  80. package/dist/chunk-G2XTGEGL.js.map +1 -0
  81. package/dist/{chunk-Q5FL3MEH.js → chunk-G4WZDQ32.js} +3 -3
  82. package/dist/{chunk-4HNY6ORZ.js → chunk-GMHWCPLP.js} +2 -2
  83. package/dist/{chunk-ZWWKKAJL.js → chunk-GYNCJSQ7.js} +4 -4
  84. package/dist/{chunk-BJI2D4SU.js → chunk-GZBNEZIU.js} +3 -3
  85. package/dist/{chunk-NYVECYCF.js → chunk-HNOKNHFO.js} +2 -2
  86. package/dist/{chunk-XLXYARWC.js → chunk-HXCJF4XU.js} +2 -2
  87. package/dist/{chunk-RMF763SX.js → chunk-IDRSTHVR.js} +5 -5
  88. package/dist/{chunk-UXREWVW4.js → chunk-IW3RMBPB.js} +2 -2
  89. package/dist/{chunk-W6YK672C.js → chunk-JTTLH646.js} +3 -3
  90. package/dist/{chunk-Y76HXF3F.js → chunk-K7S2IMGJ.js} +93 -38
  91. package/dist/{chunk-Y76HXF3F.js.map → chunk-K7S2IMGJ.js.map} +1 -1
  92. package/dist/{chunk-AJW2K7K3.js → chunk-KIOXEHWF.js} +2 -2
  93. package/dist/{chunk-BQB5ZMYO.js → chunk-KKNZ7PUZ.js} +2 -2
  94. package/dist/{chunk-AAMFQHKI.js → chunk-KRPMISWO.js} +3 -3
  95. package/dist/{chunk-XX2IGMCB.js → chunk-KV44HTMJ.js} +2 -2
  96. package/dist/{chunk-FKFTPFUG.js → chunk-KXJ7XYUT.js} +2 -2
  97. package/dist/{chunk-5SV2GFZX.js → chunk-LDP6LBDS.js} +2 -2
  98. package/dist/{chunk-F6WCOXTF.js → chunk-LMLPLIT4.js} +2 -2
  99. package/dist/{chunk-JGT7M3BA.js → chunk-LY3SDHMI.js} +6 -6
  100. package/dist/{chunk-2NZ7KWRW.js → chunk-M4PHCEPU.js} +2 -2
  101. package/dist/{chunk-VRF2KFI2.js → chunk-NORFVW2H.js} +2 -2
  102. package/dist/{chunk-OINFRHLR.js → chunk-NRTVZSPO.js} +2 -2
  103. package/dist/{chunk-IAZPYX6W.js → chunk-NRVGODSE.js} +3 -3
  104. package/dist/{chunk-IHOXK2I6.js → chunk-NVKO5YKP.js} +2 -2
  105. package/dist/{chunk-OQQXGYMX.js → chunk-OWYHHW67.js} +4 -4
  106. package/dist/{chunk-DXODYQ7J.js → chunk-Q3THVX75.js} +2 -2
  107. package/dist/{chunk-TAC5WFJC.js → chunk-QEGKMZNQ.js} +4 -4
  108. package/dist/{chunk-V2HHAAPI.js → chunk-RB776UH3.js} +2 -2
  109. package/dist/{chunk-TAIIC5OM.js → chunk-SEHKTE4F.js} +3 -3
  110. package/dist/{chunk-3JLWSFTV.js → chunk-SVWYZXIL.js} +8 -5
  111. package/dist/{chunk-3JLWSFTV.js.map → chunk-SVWYZXIL.js.map} +1 -1
  112. package/dist/{chunk-G6E7XJYL.js → chunk-SZAWZPY6.js} +10 -10
  113. package/dist/{chunk-2AD5SXO4.js → chunk-T5IF2ZCE.js} +5 -2
  114. package/dist/chunk-T5IF2ZCE.js.map +1 -0
  115. package/dist/{chunk-OVJFS5P5.js → chunk-TM7S5UHD.js} +2 -2
  116. package/dist/{chunk-7DNMX7SA.js → chunk-TQAXUYUE.js} +2 -2
  117. package/dist/{chunk-7WSQZJPC.js → chunk-V3JM4XEI.js} +4 -4
  118. package/dist/{chunk-36S7UHAW.js → chunk-VEBYLZQQ.js} +2 -2
  119. package/dist/{chunk-IMJPJY7V.js → chunk-VHF73MGU.js} +2 -2
  120. package/dist/{chunk-TDULASPE.js → chunk-VKDWYDFQ.js} +7 -7
  121. package/dist/{chunk-NKXHCCLB.js → chunk-VTPASHTO.js} +2 -2
  122. package/dist/{chunk-L3R24OLZ.js → chunk-W65KK3X6.js} +2 -2
  123. package/dist/{chunk-MNIPH6LD.js → chunk-WBYQA3VN.js} +3 -3
  124. package/dist/{chunk-4B5S3VWD.js → chunk-WD32KTVI.js} +28 -28
  125. package/dist/{chunk-WD2JD2UB.js → chunk-WEQZ5OYK.js} +2 -2
  126. package/dist/{chunk-UD6J2LIA.js → chunk-XDH5MO6L.js} +2 -2
  127. package/dist/{chunk-QJTFMH5Y.js → chunk-XN4CPSCN.js} +2 -2
  128. package/dist/{chunk-64JK4TL7.js → chunk-XOLVM3AT.js} +3 -3
  129. package/dist/{chunk-MRV7VSQK.js → chunk-Y23L4YJV.js} +2 -2
  130. package/dist/{chunk-6ISP2EN2.js → chunk-YF3JERFZ.js} +2 -2
  131. package/dist/{chunk-TYZK56OA.js → chunk-YL2W6NUG.js} +7 -7
  132. package/dist/{chunk-C5CPYMLX.js → chunk-YR6A6ZK7.js} +2 -2
  133. package/dist/{chunk-EJO2NWW7.js → chunk-Z3YQOV45.js} +2 -2
  134. package/dist/{chunk-6KTXE6A3.js → chunk-Z4TXB4K7.js} +2 -2
  135. package/dist/{chunk-6VITOSPL.js → chunk-ZFUPRODV.js} +2 -2
  136. package/dist/{chunk-BJX6G726.js → chunk-ZJ6MEVTX.js} +65 -62
  137. package/dist/chunk-ZJ6MEVTX.js.map +1 -0
  138. package/dist/{chunk-ADP2VCP6.js → chunk-ZNFHWNDM.js} +5 -5
  139. package/dist/cli.js +68 -68
  140. package/dist/coding/export-okf-codegraph.js +7 -7
  141. package/dist/compounding/engine.js +9 -9
  142. package/dist/config-security.d.ts +4 -0
  143. package/dist/config-security.d.ts.map +1 -1
  144. package/dist/config-security.js +2 -2
  145. package/dist/config.js +9 -9
  146. package/dist/connectors/codex-materialize-runner.js +8 -8
  147. package/dist/connectors/index.js +9 -9
  148. package/dist/contradiction/index.js +3 -3
  149. package/dist/{contradiction-scan-GVD4JJ7B.js → contradiction-scan-5EJYRKD3.js} +3 -3
  150. package/dist/convergence-refresh.js +10 -10
  151. package/dist/corpus-watermark.js +10 -10
  152. package/dist/day-summary.js +2 -2
  153. package/dist/embedding-fallback.js +2 -2
  154. package/dist/entity-retrieval.js +9 -9
  155. package/dist/explicit-capture.js +2 -2
  156. package/dist/external-wiki-access.js +37 -37
  157. package/dist/extraction-judge.js +3 -3
  158. package/dist/extraction-normalization.js +3 -3
  159. package/dist/extraction-prompt.js +2 -2
  160. package/dist/extraction.js +19 -19
  161. package/dist/{first-start-migration-L3UFX5CU.js → first-start-migration-7OATHJKB.js} +2 -2
  162. package/dist/harmonic-retrieval.js +1 -1
  163. package/dist/index.d.ts +2 -2
  164. package/dist/index.d.ts.map +1 -1
  165. package/dist/index.js +95 -93
  166. package/dist/local-llm.js +2 -2
  167. package/dist/location/index.js +10 -10
  168. package/dist/maintenance/memory-governance.js +8 -8
  169. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +8 -8
  170. package/dist/maintenance/rebuild-memory-projection.js +9 -9
  171. package/dist/memory-browse-operations.js +37 -37
  172. package/dist/namespaces/migrate.js +9 -9
  173. package/dist/namespaces/principal.js +2 -2
  174. package/dist/namespaces/search.js +4 -4
  175. package/dist/namespaces/storage.js +8 -8
  176. package/dist/offline-sync-impression-drain.js +5 -5
  177. package/dist/operator-doctor-corpus.js +11 -11
  178. package/dist/operator-toolkit.js +21 -21
  179. package/dist/orchestration/compression-guideline-coordinator.js +2 -2
  180. package/dist/orchestration/extraction-injection-gate.d.ts +5 -4
  181. package/dist/orchestration/extraction-injection-gate.d.ts.map +1 -1
  182. package/dist/orchestration/maintenance.js +20 -20
  183. package/dist/orchestration/turn-ingestion.d.ts.map +1 -1
  184. package/dist/orchestrator.js +93 -93
  185. package/dist/recall-composition-decision.js +3 -3
  186. package/dist/recall-context-composition.js +2 -2
  187. package/dist/recall-explain-renderer.js +3 -3
  188. package/dist/recall-navigate-access.js +2 -2
  189. package/dist/recall-navigate-disclosure.js +2 -2
  190. package/dist/recall-navigate.js +2 -2
  191. package/dist/recall-navigation-operations.js +37 -37
  192. package/dist/recall-navigation.js +36 -36
  193. package/dist/recall-why-service.js +5 -5
  194. package/dist/recall-why.js +3 -3
  195. package/dist/recall-xray-cli.js +4 -4
  196. package/dist/recall-xray-renderer.js +3 -3
  197. package/dist/recall-xray.js +2 -2
  198. package/dist/{resolution-CHNISQJB.js → resolution-UYJU5JUA.js} +4 -4
  199. package/dist/resume-bundles.js +10 -10
  200. package/dist/search/embed-helper.js +2 -2
  201. package/dist/search/factory.js +3 -3
  202. package/dist/search/index.js +3 -3
  203. package/dist/security/audit-memory.d.ts +3 -0
  204. package/dist/security/audit-memory.d.ts.map +1 -1
  205. package/dist/security/injection-screen.d.ts +2 -1
  206. package/dist/security/injection-screen.d.ts.map +1 -1
  207. package/dist/security/origin-authority.d.ts +3 -0
  208. package/dist/security/origin-authority.d.ts.map +1 -1
  209. package/dist/security/types.d.ts +5 -0
  210. package/dist/security/types.d.ts.map +1 -1
  211. package/dist/semantic-consolidation.js +9 -9
  212. package/dist/semantic-rule-promotion.js +8 -8
  213. package/dist/semantic-rule-verifier.js +8 -8
  214. package/dist/shared-context/manager.js +2 -2
  215. package/dist/source-agent-qualifier.js +14 -14
  216. package/dist/standup/build.js +8 -8
  217. package/dist/storage.js +7 -7
  218. package/dist/summarizer.js +3 -3
  219. package/dist/support-passport/index.js +39 -39
  220. package/dist/temporal-timeline-recall.js +3 -3
  221. package/dist/{tier-stats-VK5PCO2L.js → tier-stats-VF6DS52E.js} +2 -2
  222. package/dist/transfer/export-okf.js +8 -8
  223. package/dist/types.d.ts +4 -3
  224. package/dist/types.d.ts.map +1 -1
  225. package/dist/types.js +1 -1
  226. package/dist/verified-recall.js +8 -8
  227. package/dist/who-knows-cli.js +9 -9
  228. package/dist/who-knows.js +8 -8
  229. package/package.json +2 -2
  230. package/src/buffer-turn-helpers.ts +4 -0
  231. package/src/buffer.ts +3 -0
  232. package/src/capabilities.test.ts +4 -1
  233. package/src/capabilities.ts +7 -7
  234. package/src/config-security.ts +103 -16
  235. package/src/config.test.ts +58 -1
  236. package/src/connector-provenance-lifecycle.test.ts +19 -0
  237. package/src/index.ts +2 -2
  238. package/src/orchestration/extraction-injection-gate.ts +11 -7
  239. package/src/orchestration/extraction-origin-context.ts +1 -1
  240. package/src/orchestration/extraction-persist.ts +8 -8
  241. package/src/orchestration/extraction-security.test.ts +12 -0
  242. package/src/orchestration/turn-ingestion.ts +2 -0
  243. package/src/security/audit-memory.test.ts +21 -10
  244. package/src/security/audit-memory.ts +6 -2
  245. package/src/security/injection-screen.test.ts +56 -0
  246. package/src/security/injection-screen.ts +81 -8
  247. package/src/security/origin-authority.ts +10 -0
  248. package/src/security/types.ts +11 -0
  249. package/src/types.ts +4 -3
  250. package/dist/chunk-2AD5SXO4.js.map +0 -1
  251. package/dist/chunk-6Q3ZTEF6.js.map +0 -1
  252. package/dist/chunk-BJX6G726.js.map +0 -1
  253. package/dist/chunk-C6FQJ52H.js.map +0 -1
  254. package/dist/chunk-JUOZ62Y7.js.map +0 -1
  255. /package/dist/{auto-sync-CWSZDLLW.js.map → auto-sync-QJNIKZHV.js.map} +0 -0
  256. /package/dist/{chunk-RP7TZEI6.js.map → chunk-2C5Z7CWB.js.map} +0 -0
  257. /package/dist/{chunk-6JYYSDHH.js.map → chunk-2L5DIVDU.js.map} +0 -0
  258. /package/dist/{chunk-ZLVUWROW.js.map → chunk-2OUSWDY6.js.map} +0 -0
  259. /package/dist/{chunk-M5IJP3YW.js.map → chunk-2PKGJPQL.js.map} +0 -0
  260. /package/dist/{chunk-FJMYMJLR.js.map → chunk-3JDA3XF5.js.map} +0 -0
  261. /package/dist/{chunk-KR5SZNNF.js.map → chunk-4IFSMCRS.js.map} +0 -0
  262. /package/dist/{chunk-KPKGDQR3.js.map → chunk-4P3ZBL5E.js.map} +0 -0
  263. /package/dist/{chunk-YUHGJBQK.js.map → chunk-5LWVTSF7.js.map} +0 -0
  264. /package/dist/{chunk-2T2RF5ZK.js.map → chunk-5QZHDS4X.js.map} +0 -0
  265. /package/dist/{chunk-DJ4CKWAD.js.map → chunk-5Y7VCE3A.js.map} +0 -0
  266. /package/dist/{chunk-G2XZFGYN.js.map → chunk-62JTOLEX.js.map} +0 -0
  267. /package/dist/{chunk-LVXBC6YB.js.map → chunk-65I2LZEK.js.map} +0 -0
  268. /package/dist/{chunk-NZLFVLLJ.js.map → chunk-7CRUDH7G.js.map} +0 -0
  269. /package/dist/{chunk-B4EGAHHS.js.map → chunk-7DE2NOON.js.map} +0 -0
  270. /package/dist/{chunk-BSDBDFKZ.js.map → chunk-7JFQI6DQ.js.map} +0 -0
  271. /package/dist/{chunk-BOADKFN4.js.map → chunk-7LNHRQKR.js.map} +0 -0
  272. /package/dist/{chunk-IV6APZJS.js.map → chunk-7OC3Q5X4.js.map} +0 -0
  273. /package/dist/{chunk-X2QPKLPL.js.map → chunk-ACX55QDO.js.map} +0 -0
  274. /package/dist/{chunk-YLPCEUXP.js.map → chunk-AEGQ5PJ7.js.map} +0 -0
  275. /package/dist/{chunk-GK6NOQE6.js.map → chunk-AERXJCOG.js.map} +0 -0
  276. /package/dist/{chunk-HW2QYZEV.js.map → chunk-B5GMOOY2.js.map} +0 -0
  277. /package/dist/{chunk-YHGRA7CK.js.map → chunk-CDQO5DCD.js.map} +0 -0
  278. /package/dist/{chunk-ENUI3IO7.js.map → chunk-D433RXFJ.js.map} +0 -0
  279. /package/dist/{chunk-IK63WA5A.js.map → chunk-D4SPMHEW.js.map} +0 -0
  280. /package/dist/{chunk-IDBLAGIM.js.map → chunk-DC5CTLCZ.js.map} +0 -0
  281. /package/dist/{chunk-42DJ235G.js.map → chunk-DINRT75P.js.map} +0 -0
  282. /package/dist/{chunk-LELJRLPY.js.map → chunk-DQFZOPDL.js.map} +0 -0
  283. /package/dist/{chunk-WN4HFL4K.js.map → chunk-DQISIT63.js.map} +0 -0
  284. /package/dist/{chunk-Q7KQ5YHT.js.map → chunk-EIU642TN.js.map} +0 -0
  285. /package/dist/{chunk-EN2YX5SF.js.map → chunk-F4PEETM4.js.map} +0 -0
  286. /package/dist/{chunk-Q6C5PIBW.js.map → chunk-F5ZCNJ3V.js.map} +0 -0
  287. /package/dist/{chunk-42G4FIKQ.js.map → chunk-FG5QU7A2.js.map} +0 -0
  288. /package/dist/{chunk-IRGQYQQ7.js.map → chunk-FM5HN7LL.js.map} +0 -0
  289. /package/dist/{chunk-R4Y5PF25.js.map → chunk-FWVDTLRK.js.map} +0 -0
  290. /package/dist/{chunk-Q5FL3MEH.js.map → chunk-G4WZDQ32.js.map} +0 -0
  291. /package/dist/{chunk-4HNY6ORZ.js.map → chunk-GMHWCPLP.js.map} +0 -0
  292. /package/dist/{chunk-ZWWKKAJL.js.map → chunk-GYNCJSQ7.js.map} +0 -0
  293. /package/dist/{chunk-BJI2D4SU.js.map → chunk-GZBNEZIU.js.map} +0 -0
  294. /package/dist/{chunk-NYVECYCF.js.map → chunk-HNOKNHFO.js.map} +0 -0
  295. /package/dist/{chunk-XLXYARWC.js.map → chunk-HXCJF4XU.js.map} +0 -0
  296. /package/dist/{chunk-RMF763SX.js.map → chunk-IDRSTHVR.js.map} +0 -0
  297. /package/dist/{chunk-UXREWVW4.js.map → chunk-IW3RMBPB.js.map} +0 -0
  298. /package/dist/{chunk-W6YK672C.js.map → chunk-JTTLH646.js.map} +0 -0
  299. /package/dist/{chunk-AJW2K7K3.js.map → chunk-KIOXEHWF.js.map} +0 -0
  300. /package/dist/{chunk-BQB5ZMYO.js.map → chunk-KKNZ7PUZ.js.map} +0 -0
  301. /package/dist/{chunk-AAMFQHKI.js.map → chunk-KRPMISWO.js.map} +0 -0
  302. /package/dist/{chunk-XX2IGMCB.js.map → chunk-KV44HTMJ.js.map} +0 -0
  303. /package/dist/{chunk-FKFTPFUG.js.map → chunk-KXJ7XYUT.js.map} +0 -0
  304. /package/dist/{chunk-5SV2GFZX.js.map → chunk-LDP6LBDS.js.map} +0 -0
  305. /package/dist/{chunk-F6WCOXTF.js.map → chunk-LMLPLIT4.js.map} +0 -0
  306. /package/dist/{chunk-JGT7M3BA.js.map → chunk-LY3SDHMI.js.map} +0 -0
  307. /package/dist/{chunk-2NZ7KWRW.js.map → chunk-M4PHCEPU.js.map} +0 -0
  308. /package/dist/{chunk-VRF2KFI2.js.map → chunk-NORFVW2H.js.map} +0 -0
  309. /package/dist/{chunk-OINFRHLR.js.map → chunk-NRTVZSPO.js.map} +0 -0
  310. /package/dist/{chunk-IAZPYX6W.js.map → chunk-NRVGODSE.js.map} +0 -0
  311. /package/dist/{chunk-IHOXK2I6.js.map → chunk-NVKO5YKP.js.map} +0 -0
  312. /package/dist/{chunk-OQQXGYMX.js.map → chunk-OWYHHW67.js.map} +0 -0
  313. /package/dist/{chunk-DXODYQ7J.js.map → chunk-Q3THVX75.js.map} +0 -0
  314. /package/dist/{chunk-TAC5WFJC.js.map → chunk-QEGKMZNQ.js.map} +0 -0
  315. /package/dist/{chunk-V2HHAAPI.js.map → chunk-RB776UH3.js.map} +0 -0
  316. /package/dist/{chunk-TAIIC5OM.js.map → chunk-SEHKTE4F.js.map} +0 -0
  317. /package/dist/{chunk-G6E7XJYL.js.map → chunk-SZAWZPY6.js.map} +0 -0
  318. /package/dist/{chunk-OVJFS5P5.js.map → chunk-TM7S5UHD.js.map} +0 -0
  319. /package/dist/{chunk-7DNMX7SA.js.map → chunk-TQAXUYUE.js.map} +0 -0
  320. /package/dist/{chunk-7WSQZJPC.js.map → chunk-V3JM4XEI.js.map} +0 -0
  321. /package/dist/{chunk-36S7UHAW.js.map → chunk-VEBYLZQQ.js.map} +0 -0
  322. /package/dist/{chunk-IMJPJY7V.js.map → chunk-VHF73MGU.js.map} +0 -0
  323. /package/dist/{chunk-TDULASPE.js.map → chunk-VKDWYDFQ.js.map} +0 -0
  324. /package/dist/{chunk-NKXHCCLB.js.map → chunk-VTPASHTO.js.map} +0 -0
  325. /package/dist/{chunk-L3R24OLZ.js.map → chunk-W65KK3X6.js.map} +0 -0
  326. /package/dist/{chunk-MNIPH6LD.js.map → chunk-WBYQA3VN.js.map} +0 -0
  327. /package/dist/{chunk-4B5S3VWD.js.map → chunk-WD32KTVI.js.map} +0 -0
  328. /package/dist/{chunk-WD2JD2UB.js.map → chunk-WEQZ5OYK.js.map} +0 -0
  329. /package/dist/{chunk-UD6J2LIA.js.map → chunk-XDH5MO6L.js.map} +0 -0
  330. /package/dist/{chunk-QJTFMH5Y.js.map → chunk-XN4CPSCN.js.map} +0 -0
  331. /package/dist/{chunk-64JK4TL7.js.map → chunk-XOLVM3AT.js.map} +0 -0
  332. /package/dist/{chunk-MRV7VSQK.js.map → chunk-Y23L4YJV.js.map} +0 -0
  333. /package/dist/{chunk-6ISP2EN2.js.map → chunk-YF3JERFZ.js.map} +0 -0
  334. /package/dist/{chunk-TYZK56OA.js.map → chunk-YL2W6NUG.js.map} +0 -0
  335. /package/dist/{chunk-C5CPYMLX.js.map → chunk-YR6A6ZK7.js.map} +0 -0
  336. /package/dist/{chunk-EJO2NWW7.js.map → chunk-Z3YQOV45.js.map} +0 -0
  337. /package/dist/{chunk-6KTXE6A3.js.map → chunk-Z4TXB4K7.js.map} +0 -0
  338. /package/dist/{chunk-6VITOSPL.js.map → chunk-ZFUPRODV.js.map} +0 -0
  339. /package/dist/{chunk-ADP2VCP6.js.map → chunk-ZNFHWNDM.js.map} +0 -0
  340. /package/dist/{contradiction-scan-GVD4JJ7B.js.map → contradiction-scan-5EJYRKD3.js.map} +0 -0
  341. /package/dist/{first-start-migration-L3UFX5CU.js.map → first-start-migration-7OATHJKB.js.map} +0 -0
  342. /package/dist/{resolution-CHNISQJB.js.map → resolution-UYJU5JUA.js.map} +0 -0
  343. /package/dist/{tier-stats-VK5PCO2L.js.map → tier-stats-VF6DS52E.js.map} +0 -0
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  compareVerifiedEpisodeResults,
3
3
  searchVerifiedEpisodes
4
- } from "./chunk-OINFRHLR.js";
4
+ } from "./chunk-NRTVZSPO.js";
5
5
  import "./chunk-B7RWBZXW.js";
6
- import "./chunk-2T2RF5ZK.js";
6
+ import "./chunk-5QZHDS4X.js";
7
7
  import "./chunk-46WM6JX2.js";
8
8
  import "./chunk-UHVXE24Y.js";
9
9
  import "./chunk-D5F7TKMH.js";
10
- import "./chunk-W6YK672C.js";
11
- import "./chunk-IAZPYX6W.js";
10
+ import "./chunk-JTTLH646.js";
11
+ import "./chunk-NRVGODSE.js";
12
12
  import "./chunk-WPGR3RW4.js";
13
- import "./chunk-6KTXE6A3.js";
13
+ import "./chunk-Z4TXB4K7.js";
14
14
  import "./chunk-D7MAYFQP.js";
15
15
  import "./chunk-KVO2BTA4.js";
16
16
  import "./chunk-CYEPCZN5.js";
@@ -50,7 +50,7 @@ import "./chunk-ZLQ37WJX.js";
50
50
  import "./chunk-IUM3VSHI.js";
51
51
  import "./chunk-C64XATK7.js";
52
52
  import "./chunk-42JKGUFJ.js";
53
- import "./chunk-6Q3ZTEF6.js";
53
+ import "./chunk-23G5P7TA.js";
54
54
  import "./chunk-ZTHGFTMW.js";
55
55
  import "./chunk-I55KAVET.js";
56
56
  import "./chunk-L2EXJQJP.js";
@@ -79,7 +79,7 @@ import "./chunk-C7HJ3NEI.js";
79
79
  import "./chunk-NB3LRY4T.js";
80
80
  import "./chunk-5FVVY2EB.js";
81
81
  import "./chunk-FFAZ2XFU.js";
82
- import "./chunk-FNQEXI3D.js";
82
+ import "./chunk-F5O6WEDO.js";
83
83
  import "./chunk-RGMVMVMF.js";
84
84
  import "./chunk-PWPIERBM.js";
85
85
  import "./chunk-JDSVLVCG.js";
@@ -87,7 +87,7 @@ import "./chunk-5GKPFL3S.js";
87
87
  import "./chunk-JAKIDQB2.js";
88
88
  import "./chunk-P7FMDTKL.js";
89
89
  import "./chunk-VUFL7X3H.js";
90
- import "./chunk-JUOZ62Y7.js";
90
+ import "./chunk-BMXEBWBT.js";
91
91
  import "./chunk-ZEFVK7XC.js";
92
92
  import "./chunk-6KH5NLQS.js";
93
93
  import "./chunk-P2QRMMVQ.js";
@@ -4,16 +4,16 @@ import {
4
4
  renderWhoKnows,
5
5
  renderWhoKnowsJson,
6
6
  renderWhoKnowsText
7
- } from "./chunk-XX2IGMCB.js";
8
- import "./chunk-NYVECYCF.js";
9
- import "./chunk-2T2RF5ZK.js";
7
+ } from "./chunk-KV44HTMJ.js";
8
+ import "./chunk-HNOKNHFO.js";
9
+ import "./chunk-5QZHDS4X.js";
10
10
  import "./chunk-46WM6JX2.js";
11
11
  import "./chunk-UHVXE24Y.js";
12
12
  import "./chunk-D5F7TKMH.js";
13
- import "./chunk-W6YK672C.js";
14
- import "./chunk-IAZPYX6W.js";
13
+ import "./chunk-JTTLH646.js";
14
+ import "./chunk-NRVGODSE.js";
15
15
  import "./chunk-WPGR3RW4.js";
16
- import "./chunk-6KTXE6A3.js";
16
+ import "./chunk-Z4TXB4K7.js";
17
17
  import "./chunk-D7MAYFQP.js";
18
18
  import "./chunk-KVO2BTA4.js";
19
19
  import "./chunk-CYEPCZN5.js";
@@ -53,7 +53,7 @@ import "./chunk-ZLQ37WJX.js";
53
53
  import "./chunk-IUM3VSHI.js";
54
54
  import "./chunk-C64XATK7.js";
55
55
  import "./chunk-42JKGUFJ.js";
56
- import "./chunk-6Q3ZTEF6.js";
56
+ import "./chunk-23G5P7TA.js";
57
57
  import "./chunk-ZTHGFTMW.js";
58
58
  import "./chunk-I55KAVET.js";
59
59
  import "./chunk-L2EXJQJP.js";
@@ -82,7 +82,7 @@ import "./chunk-C7HJ3NEI.js";
82
82
  import "./chunk-NB3LRY4T.js";
83
83
  import "./chunk-5FVVY2EB.js";
84
84
  import "./chunk-FFAZ2XFU.js";
85
- import "./chunk-FNQEXI3D.js";
85
+ import "./chunk-F5O6WEDO.js";
86
86
  import "./chunk-RGMVMVMF.js";
87
87
  import "./chunk-PWPIERBM.js";
88
88
  import "./chunk-JDSVLVCG.js";
@@ -90,7 +90,7 @@ import "./chunk-5GKPFL3S.js";
90
90
  import "./chunk-JAKIDQB2.js";
91
91
  import "./chunk-P7FMDTKL.js";
92
92
  import "./chunk-VUFL7X3H.js";
93
- import "./chunk-JUOZ62Y7.js";
93
+ import "./chunk-BMXEBWBT.js";
94
94
  import "./chunk-ZEFVK7XC.js";
95
95
  import "./chunk-6KH5NLQS.js";
96
96
  import "./chunk-P2QRMMVQ.js";
package/dist/who-knows.js CHANGED
@@ -9,15 +9,15 @@ import {
9
9
  loadWhoKnowsEntities,
10
10
  tokenizeTopic,
11
11
  validateWhoKnowsInput
12
- } from "./chunk-NYVECYCF.js";
13
- import "./chunk-2T2RF5ZK.js";
12
+ } from "./chunk-HNOKNHFO.js";
13
+ import "./chunk-5QZHDS4X.js";
14
14
  import "./chunk-46WM6JX2.js";
15
15
  import "./chunk-UHVXE24Y.js";
16
16
  import "./chunk-D5F7TKMH.js";
17
- import "./chunk-W6YK672C.js";
18
- import "./chunk-IAZPYX6W.js";
17
+ import "./chunk-JTTLH646.js";
18
+ import "./chunk-NRVGODSE.js";
19
19
  import "./chunk-WPGR3RW4.js";
20
- import "./chunk-6KTXE6A3.js";
20
+ import "./chunk-Z4TXB4K7.js";
21
21
  import "./chunk-D7MAYFQP.js";
22
22
  import "./chunk-KVO2BTA4.js";
23
23
  import "./chunk-CYEPCZN5.js";
@@ -57,7 +57,7 @@ import "./chunk-ZLQ37WJX.js";
57
57
  import "./chunk-IUM3VSHI.js";
58
58
  import "./chunk-C64XATK7.js";
59
59
  import "./chunk-42JKGUFJ.js";
60
- import "./chunk-6Q3ZTEF6.js";
60
+ import "./chunk-23G5P7TA.js";
61
61
  import "./chunk-ZTHGFTMW.js";
62
62
  import "./chunk-I55KAVET.js";
63
63
  import "./chunk-L2EXJQJP.js";
@@ -86,7 +86,7 @@ import "./chunk-C7HJ3NEI.js";
86
86
  import "./chunk-NB3LRY4T.js";
87
87
  import "./chunk-5FVVY2EB.js";
88
88
  import "./chunk-FFAZ2XFU.js";
89
- import "./chunk-FNQEXI3D.js";
89
+ import "./chunk-F5O6WEDO.js";
90
90
  import "./chunk-RGMVMVMF.js";
91
91
  import "./chunk-PWPIERBM.js";
92
92
  import "./chunk-JDSVLVCG.js";
@@ -94,7 +94,7 @@ import "./chunk-5GKPFL3S.js";
94
94
  import "./chunk-JAKIDQB2.js";
95
95
  import "./chunk-P7FMDTKL.js";
96
96
  import "./chunk-VUFL7X3H.js";
97
- import "./chunk-JUOZ62Y7.js";
97
+ import "./chunk-BMXEBWBT.js";
98
98
  import "./chunk-ZEFVK7XC.js";
99
99
  import "./chunk-6KH5NLQS.js";
100
100
  import "./chunk-P2QRMMVQ.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnic/core",
3
- "version": "9.69.60",
3
+ "version": "9.69.61",
4
4
  "description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -3307,7 +3307,7 @@
3307
3307
  "core"
3308
3308
  ],
3309
3309
  "peerDependencies": {
3310
- "@remnic/coding-graph": "^9.69.60"
3310
+ "@remnic/coding-graph": "^9.69.61"
3311
3311
  },
3312
3312
  "peerDependenciesMeta": {
3313
3313
  "@remnic/coding-graph": {
@@ -58,6 +58,9 @@ export function copyBufferTurn(turn: BufferTurn): BufferTurn {
58
58
  if (typeof turn.sourceConnector === "string") {
59
59
  copy.sourceConnector = turn.sourceConnector;
60
60
  }
61
+ if (turn.originRole === "user" || turn.originRole === "assistant" || turn.originRole === "tool") {
62
+ copy.originRole = turn.originRole;
63
+ }
61
64
  if (typeof turn.ambientCapture === "boolean") {
62
65
  copy.ambientCapture = turn.ambientCapture;
63
66
  }
@@ -77,6 +80,7 @@ export function bufferTurnsEqual(left: BufferTurn | undefined, right: BufferTurn
77
80
  left.turnFingerprint === right.turnFingerprint &&
78
81
  left.persistProcessedFingerprint === right.persistProcessedFingerprint &&
79
82
  left.sourceConnector === right.sourceConnector &&
83
+ left.originRole === right.originRole &&
80
84
  left.ambientCapture === right.ambientCapture
81
85
  );
82
86
  }
package/src/buffer.ts CHANGED
@@ -918,6 +918,9 @@ export class SmartBuffer {
918
918
  copy.persistProcessedFingerprint = t.persistProcessedFingerprint;
919
919
  }
920
920
  if (typeof t.sourceConnector === "string") copy.sourceConnector = t.sourceConnector;
921
+ if (t.originRole === "user" || t.originRole === "assistant" || t.originRole === "tool") {
922
+ copy.originRole = t.originRole;
923
+ }
921
924
  return copy;
922
925
  });
923
926
  }
@@ -853,7 +853,10 @@ test("resolveLocalLlmCapabilities: result is frozen", () => {
853
853
  // SecurityCapabilitySet — gate-parity tests (issue #1523 batch 7).
854
854
  // ---------------------------------------------------------------------------
855
855
 
856
- const SECURITY_FIELD_TO_FLAG: Record<keyof SecurityCapabilitySet, string> = {
856
+ // Boolean-flag parity only: `injectionScreenProfile` is an enum projection
857
+ // (#1962), not a gate — its custom->default / named-mode->hardened mapping is
858
+ // pinned in config.test.ts.
859
+ const SECURITY_FIELD_TO_FLAG: Record<Exclude<keyof SecurityCapabilitySet, "injectionScreenProfile">, string> = {
857
860
  trustZones: "trustZonesEnabled",
858
861
  quarantinePromotion: "quarantinePromotionEnabled",
859
862
  memoryPoisoningDefense: "memoryPoisoningDefenseEnabled",
@@ -20,15 +20,12 @@
20
20
  * the CapabilitySet itself (rule 30 governs behavior changes; resolving and
21
21
  * threading a capability projection must stay behavior-preserving).
22
22
  *
23
- * Flag-retirement audit (#1780, 2026-07-08): all projected fields across 18
24
- * capability sets were verified for live consumers. Two dead projections found
25
- * and removed: recallGraph (RecallEnhancementCapabilitySet — production reads
26
- * recallGraphEnabled directly via graph-recall.ts) and behaviorLoopAutoTune
27
- * (ConversationContextCapabilitySet — production reads behaviorLoopAutoTuneEnabled
28
- * directly via cli.ts). The flags themselves remain alive.
23
+ * Flag-retirement audit (#1780, 2026-07-08): all projected fields verified for
24
+ * live consumers; dead projections removed.
29
25
  */
30
26
 
31
27
  import type { PluginConfig } from "./types.js";
28
+ import type { InjectionScreenProfile } from "./security/injection-screen.js";
32
29
 
33
30
  /**
34
31
  * Frozen projection of recall-operation feature gates.
@@ -638,6 +635,8 @@ export interface SecurityCapabilitySet {
638
635
  readonly originAuthority: boolean;
639
636
  /** `injectionScreenEnabled` — quarantine deterministic injection findings. */
640
637
  readonly injectionScreen: boolean;
638
+ /** Injection-screen profile weighting (#1962). */
639
+ readonly injectionScreenProfile: InjectionScreenProfile;
641
640
  /** `trustZoneRecallEnabled` — restrict recall to trusted zones. */
642
641
  readonly trustZoneRecall: boolean;
643
642
  }
@@ -645,7 +644,7 @@ export interface SecurityCapabilitySet {
645
644
  /** Config projection consumed by {@link resolveSecurityCapabilities}. */
646
645
  export type SecurityConfigProjection = Pick<PluginConfig,
647
646
  | "trustZonesEnabled" | "quarantinePromotionEnabled" | "memoryPoisoningDefenseEnabled"
648
- | "originAuthorityEnabled" | "injectionScreenEnabled" | "trustZoneRecallEnabled">;
647
+ | "originAuthorityEnabled" | "injectionScreenEnabled" | "injectionScreenProfile" | "trustZoneRecallEnabled">;
649
648
 
650
649
  /** Resolve the {@link SecurityCapabilitySet} from parsed config. */
651
650
  export function resolveSecurityCapabilities(config: SecurityConfigProjection): SecurityCapabilitySet {
@@ -655,6 +654,7 @@ export function resolveSecurityCapabilities(config: SecurityConfigProjection): S
655
654
  memoryPoisoningDefense: config.memoryPoisoningDefenseEnabled,
656
655
  originAuthority: config.originAuthorityEnabled,
657
656
  injectionScreen: config.injectionScreenEnabled,
657
+ injectionScreenProfile: config.injectionScreenProfile,
658
658
  trustZoneRecall: config.trustZoneRecallEnabled,
659
659
  });
660
660
  }
@@ -1,6 +1,11 @@
1
1
  import { coerceBool } from "./connectors/coerce.js";
2
2
  import { readEnvVar } from "./runtime/env.js";
3
- import { DEFAULT_UNTRUSTED_ORIGINS } from "./security/origin-authority.js";
3
+ import {
4
+ DEFAULT_UNTRUSTED_ORIGINS,
5
+ HARDENED_UNTRUSTED_ORIGINS,
6
+ } from "./security/origin-authority.js";
7
+ import type { MemoryInjectionDefenseMode } from "./security/types.js";
8
+ import type { InjectionScreenProfile } from "./security/injection-screen.js";
4
9
 
5
10
  // Memory-poisoning hardening (#1955): preserve explicit config, but let env
6
11
  // values replace schema-materialized defaults from the host config loader.
@@ -103,29 +108,111 @@ function resolveUntrustedOrigins(
103
108
  return normalized.length > 0 ? normalized : [...DEFAULT_UNTRUSTED_ORIGINS];
104
109
  }
105
110
 
111
+ function validateDefenseMode(value: unknown): MemoryInjectionDefenseMode {
112
+ if (
113
+ value === "custom"
114
+ || value === "off"
115
+ || value === "fencing"
116
+ || value === "quarantine"
117
+ || value === "layered"
118
+ ) {
119
+ return value;
120
+ }
121
+ throw new Error(
122
+ `memoryInjectionDefenseMode must be custom|off|fencing|quarantine|layered; got ${JSON.stringify(value)}`,
123
+ );
124
+ }
125
+
126
+ function isOperatorAuthored(
127
+ rawOperatorConfig: Record<string, unknown> | null | undefined,
128
+ key: string,
129
+ ): boolean {
130
+ return rawOperatorConfig !== undefined
131
+ && rawOperatorConfig !== null
132
+ && Object.prototype.hasOwnProperty.call(rawOperatorConfig, key)
133
+ && (rawOperatorConfig as Record<string, unknown>)[key] !== undefined
134
+ && (rawOperatorConfig as Record<string, unknown>)[key] !== null;
135
+ }
136
+
137
+ function resolveMemoryInjectionDefenseMode(
138
+ value: unknown,
139
+ rawOperatorConfig: Record<string, unknown> | null | undefined,
140
+ ): MemoryInjectionDefenseMode {
141
+ // Precedence: operator-authored config, then the environment, then a
142
+ // host-materialized schema default. A host that fills in the manifest
143
+ // default must not shadow an operator's environment override.
144
+ if (isOperatorAuthored(rawOperatorConfig, "memoryInjectionDefenseMode")) {
145
+ return validateDefenseMode(
146
+ (rawOperatorConfig as Record<string, unknown>).memoryInjectionDefenseMode,
147
+ );
148
+ }
149
+ const envValue = readEnvVar("REMNIC_MEMORY_INJECTION_DEFENSE_MODE");
150
+ if (envValue !== undefined && rawOperatorConfig !== undefined) return validateDefenseMode(envValue);
151
+ if (value !== undefined && value !== null) return validateDefenseMode(value);
152
+ if (envValue !== undefined) return validateDefenseMode(envValue);
153
+ return "custom";
154
+ }
155
+
156
+ function hasExplicitUntrustedOrigins(
157
+ cfg: Record<string, unknown>,
158
+ rawOperatorConfig: Record<string, unknown> | null | undefined,
159
+ ): boolean {
160
+ const configAuthored = rawOperatorConfig === undefined
161
+ ? Object.prototype.hasOwnProperty.call(cfg, "untrustedOrigins")
162
+ : rawOperatorConfig !== null
163
+ && Object.prototype.hasOwnProperty.call(rawOperatorConfig, "untrustedOrigins");
164
+ return configAuthored || readEnvVar("REMNIC_UNTRUSTED_ORIGINS") !== undefined;
165
+ }
166
+
106
167
  export function parseSecurityConfig(
107
168
  cfg: Record<string, unknown>,
108
169
  rawOperatorConfig: Record<string, unknown> | null | undefined,
109
170
  ): {
171
+ memoryInjectionDefenseMode: MemoryInjectionDefenseMode;
110
172
  originAuthorityEnabled: boolean;
111
173
  injectionScreenEnabled: boolean;
174
+ injectionScreenProfile: InjectionScreenProfile;
112
175
  untrustedOrigins: string[];
113
176
  } {
177
+ const memoryInjectionDefenseMode = resolveMemoryInjectionDefenseMode(
178
+ cfg.memoryInjectionDefenseMode,
179
+ rawOperatorConfig,
180
+ );
181
+ const customOriginAuthority = resolveSecurityBooleanConfig(
182
+ cfg.originAuthorityEnabled,
183
+ rawOperatorConfig,
184
+ "originAuthorityEnabled",
185
+ "REMNIC_ORIGIN_AUTHORITY_ENABLED",
186
+ false,
187
+ );
188
+ const customInjectionScreen = resolveSecurityBooleanConfig(
189
+ cfg.injectionScreenEnabled,
190
+ rawOperatorConfig,
191
+ "injectionScreenEnabled",
192
+ "REMNIC_INJECTION_SCREEN_ENABLED",
193
+ true,
194
+ );
195
+ const flags = {
196
+ custom: [customOriginAuthority, customInjectionScreen],
197
+ off: [false, false],
198
+ fencing: [true, false],
199
+ quarantine: [false, true],
200
+ layered: [true, true],
201
+ } satisfies Record<MemoryInjectionDefenseMode, readonly [boolean, boolean]>;
202
+ const [originAuthorityEnabled, injectionScreenEnabled] = flags[memoryInjectionDefenseMode];
203
+ const injectionScreenProfile: InjectionScreenProfile =
204
+ memoryInjectionDefenseMode === "custom" ? "default" : "hardened";
205
+ const configuredOrigins = resolveUntrustedOrigins(cfg.untrustedOrigins, rawOperatorConfig);
206
+ const untrustedOrigins =
207
+ memoryInjectionDefenseMode !== "custom"
208
+ && !hasExplicitUntrustedOrigins(cfg, rawOperatorConfig)
209
+ ? [...HARDENED_UNTRUSTED_ORIGINS]
210
+ : configuredOrigins;
114
211
  return {
115
- originAuthorityEnabled: resolveSecurityBooleanConfig(
116
- cfg.originAuthorityEnabled,
117
- rawOperatorConfig,
118
- "originAuthorityEnabled",
119
- "REMNIC_ORIGIN_AUTHORITY_ENABLED",
120
- false,
121
- ),
122
- injectionScreenEnabled: resolveSecurityBooleanConfig(
123
- cfg.injectionScreenEnabled,
124
- rawOperatorConfig,
125
- "injectionScreenEnabled",
126
- "REMNIC_INJECTION_SCREEN_ENABLED",
127
- true,
128
- ),
129
- untrustedOrigins: resolveUntrustedOrigins(cfg.untrustedOrigins, rawOperatorConfig),
212
+ memoryInjectionDefenseMode,
213
+ originAuthorityEnabled,
214
+ injectionScreenEnabled,
215
+ injectionScreenProfile,
216
+ untrustedOrigins,
130
217
  };
131
218
  }
@@ -35,14 +35,39 @@ test("parseConfig memory-poisoning hardening defaults and validation (#1955)", (
35
35
  const previousOrigin = process.env.REMNIC_ORIGIN_AUTHORITY_ENABLED;
36
36
  const previousInjection = process.env.REMNIC_INJECTION_SCREEN_ENABLED;
37
37
  const previousOrigins = process.env.REMNIC_UNTRUSTED_ORIGINS;
38
+ const previousMode = process.env.REMNIC_MEMORY_INJECTION_DEFENSE_MODE;
38
39
  delete process.env.REMNIC_ORIGIN_AUTHORITY_ENABLED;
39
40
  delete process.env.REMNIC_INJECTION_SCREEN_ENABLED;
40
41
  delete process.env.REMNIC_UNTRUSTED_ORIGINS;
42
+ delete process.env.REMNIC_MEMORY_INJECTION_DEFENSE_MODE;
41
43
  try {
42
44
  const defaults = parseConfig({});
45
+ assert.equal(defaults.memoryInjectionDefenseMode, "custom");
43
46
  assert.equal(defaults.originAuthorityEnabled, false);
44
47
  assert.equal(defaults.injectionScreenEnabled, true);
45
- assert.deepEqual(defaults.untrustedOrigins, ["tool_output", "import:*", "unknown"]);
48
+ assert.equal(defaults.injectionScreenProfile, "default");
49
+
50
+ for (const [mode, originAuthorityEnabled, injectionScreenEnabled] of [
51
+ ["off", false, false],
52
+ ["fencing", true, false],
53
+ ["quarantine", false, true],
54
+ ["layered", true, true],
55
+ ] as const) {
56
+ const resolved = parseConfig({ memoryInjectionDefenseMode: mode });
57
+ assert.equal(resolved.memoryInjectionDefenseMode, mode);
58
+ assert.equal(resolved.originAuthorityEnabled, originAuthorityEnabled);
59
+ assert.equal(resolved.injectionScreenEnabled, injectionScreenEnabled);
60
+ assert.equal(resolved.injectionScreenProfile, "hardened");
61
+ assert.deepEqual(
62
+ resolved.untrustedOrigins,
63
+ ["user", "tool_output", "connector:*", "import:*", "unknown"],
64
+ );
65
+ }
66
+ const customizedMode = parseConfig({
67
+ memoryInjectionDefenseMode: "fencing",
68
+ untrustedOrigins: ["tool_output"],
69
+ });
70
+ assert.deepEqual(customizedMode.untrustedOrigins, ["tool_output"]);
46
71
 
47
72
  const configured = parseConfig({
48
73
  originAuthorityEnabled: "true",
@@ -83,6 +108,10 @@ test("parseConfig memory-poisoning hardening defaults and validation (#1955)", (
83
108
  () => parseConfig({ untrustedOrigins: "unknown" }),
84
109
  /untrustedOrigins must be an array of strings/,
85
110
  );
111
+ assert.throws(
112
+ () => parseConfig({ memoryInjectionDefenseMode: "automatic" }),
113
+ /memoryInjectionDefenseMode must be/,
114
+ );
86
115
  } finally {
87
116
  if (previousOrigin === undefined) delete process.env.REMNIC_ORIGIN_AUTHORITY_ENABLED;
88
117
  else process.env.REMNIC_ORIGIN_AUTHORITY_ENABLED = previousOrigin;
@@ -90,6 +119,34 @@ test("parseConfig memory-poisoning hardening defaults and validation (#1955)", (
90
119
  else process.env.REMNIC_INJECTION_SCREEN_ENABLED = previousInjection;
91
120
  if (previousOrigins === undefined) delete process.env.REMNIC_UNTRUSTED_ORIGINS;
92
121
  else process.env.REMNIC_UNTRUSTED_ORIGINS = previousOrigins;
122
+ if (previousMode === undefined) delete process.env.REMNIC_MEMORY_INJECTION_DEFENSE_MODE;
123
+ else process.env.REMNIC_MEMORY_INJECTION_DEFENSE_MODE = previousMode;
124
+ }
125
+ });
126
+
127
+ test("parseConfig honors REMNIC_MEMORY_INJECTION_DEFENSE_MODE when the operator omits the field", () => {
128
+ const previousMode = process.env.REMNIC_MEMORY_INJECTION_DEFENSE_MODE;
129
+ delete process.env.REMNIC_MEMORY_INJECTION_DEFENSE_MODE;
130
+ try {
131
+ process.env.REMNIC_MEMORY_INJECTION_DEFENSE_MODE = "layered";
132
+ const resolved = parseConfig({});
133
+ assert.equal(resolved.memoryInjectionDefenseMode, "layered");
134
+ assert.equal(resolved.originAuthorityEnabled, true);
135
+ assert.equal(resolved.injectionScreenEnabled, true);
136
+ assert.equal(resolved.injectionScreenProfile, "hardened");
137
+ // A host that materializes the manifest default into cfg while the
138
+ // operator's raw config omits the key must not shadow the env override.
139
+ const materialized = parseConfig({ memoryInjectionDefenseMode: "custom" }, {});
140
+ assert.equal(materialized.memoryInjectionDefenseMode, "layered");
141
+ // An operator-authored value still outranks the environment.
142
+ const authored = parseConfig(
143
+ { memoryInjectionDefenseMode: "fencing" },
144
+ { memoryInjectionDefenseMode: "fencing" },
145
+ );
146
+ assert.equal(authored.memoryInjectionDefenseMode, "fencing");
147
+ } finally {
148
+ if (previousMode === undefined) delete process.env.REMNIC_MEMORY_INJECTION_DEFENSE_MODE;
149
+ else process.env.REMNIC_MEMORY_INJECTION_DEFENSE_MODE = previousMode;
93
150
  }
94
151
  });
95
152
 
@@ -13,6 +13,7 @@ import path from "node:path";
13
13
  import test from "node:test";
14
14
 
15
15
  import { SmartBuffer } from "./buffer.js";
16
+ import { bufferTurnsEqual, copyBufferTurn } from "./buffer-turn-helpers.js";
16
17
  import {
17
18
  ExtractionRunCoordinator,
18
19
  type ExtractionRunCoordinatorDeps,
@@ -238,6 +239,7 @@ test("ingestReplayBatch: sourceConnector preserved through replay ingestion", as
238
239
  content: "hello from chatgpt",
239
240
  timestamp: "2026-07-12T00:00:00Z",
240
241
  sourceConnector: "chatgpt",
242
+ originRole: "tool",
241
243
  },
242
244
  ]);
243
245
 
@@ -247,6 +249,11 @@ test("ingestReplayBatch: sourceConnector preserved through replay ingestion", as
247
249
  "chatgpt",
248
250
  "ingestReplayBatch must preserve sourceConnector on rebuilt BufferTurn"
249
251
  );
252
+ assert.equal(
253
+ capturedTurns[0].originRole,
254
+ "tool",
255
+ "ingestReplayBatch must preserve the authenticated originRole so origin authority fences tool content"
256
+ );
250
257
  } finally {
251
258
  StorageManager.clearAllStaticCaches();
252
259
  await rm(baseDir, { recursive: true, force: true });
@@ -699,3 +706,15 @@ test("runExtraction: the Source agent header connector equals the persisted sour
699
706
  await rm(baseDir, { recursive: true, force: true });
700
707
  }
701
708
  });
709
+
710
+ test("copyBufferTurn and bufferTurnsEqual carry originRole", () => {
711
+ const turn = makeTurn({ content: "tool output", originRole: "tool" });
712
+ const copy = copyBufferTurn(turn);
713
+ assert.equal(copy.originRole, "tool", "extraction snapshots must keep the authenticated origin role");
714
+ assert.equal(bufferTurnsEqual(copy, turn), true);
715
+ assert.equal(
716
+ bufferTurnsEqual(copy, makeTurn({ content: "tool output", originRole: "user" })),
717
+ false,
718
+ "a turn re-attributed to another origin is not the same turn",
719
+ );
720
+ });
package/src/index.ts CHANGED
@@ -387,8 +387,8 @@ export {
387
387
  type TrustZoneRecordKind,
388
388
  type TrustZoneSourceClass,
389
389
  } from "./trust-zones.js";
390
- export { DEFAULT_UNTRUSTED_ORIGINS, classifyOrigin, isUntrustedOrigin, parseOriginClass, renderAuthorityFence, type OriginClass } from "./security/origin-authority.js";
391
- export { INJECTION_SCREEN_THRESHOLD, screenCandidateFact, type InjectionScreenFinding, type InjectionScreenResult } from "./security/injection-screen.js";
390
+ export { DEFAULT_UNTRUSTED_ORIGINS, HARDENED_UNTRUSTED_ORIGINS, classifyOrigin, isUntrustedOrigin, parseOriginClass, renderAuthorityFence, type MemoryInjectionDefenseMode, type OriginClass } from "./security/origin-authority.js";
391
+ export { INJECTION_SCREEN_THRESHOLD, screenCandidateFact, type InjectionScreenFinding, type InjectionScreenProfile, type InjectionScreenResult } from "./security/injection-screen.js";
392
392
  export { auditMemoryStore, formatAuditMemoryReport, type AuditMemoryReport } from "./security/audit-memory.js";
393
393
  // Access layer (HTTP + MCP + schema validation)
394
394
  // ---------------------------------------------------------------------------
@@ -2,6 +2,7 @@ import { parseOriginClass } from "../security/origin-authority.js";
2
2
  import { normalizeAttributePairs } from "../structured-attributes.js";
3
3
  import { buildProcedurePersistBody } from "../procedural/procedure-types.js";
4
4
  import { screenCandidateFact } from "../security/injection-screen.js";
5
+ import type { InjectionScreenProfile } from "../security/injection-screen.js";
5
6
  import type { EntityStructuredSection } from "../types.js";
6
7
 
7
8
  export interface InjectionScreenCandidate {
@@ -41,11 +42,12 @@ export function serializeInjectionScreenCandidate(candidate: InjectionScreenCand
41
42
  export function evaluateInjectionScreen(
42
43
  candidate: InjectionScreenCandidate | string,
43
44
  enabled: boolean,
45
+ profile: InjectionScreenProfile = "default",
44
46
  ): InjectionScreenGateResult {
45
47
  if (!enabled) return { tags: [] };
46
48
  const content =
47
49
  typeof candidate === "string" ? candidate : serializeInjectionScreenCandidate(candidate);
48
- const result = screenCandidateFact(content);
50
+ const result = screenCandidateFact(content, profile);
49
51
  return {
50
52
  status: result.quarantine === true ? "pending_review" : undefined,
51
53
  tags: result.quarantine === true
@@ -63,6 +65,7 @@ export function evaluateInjectionScreen(
63
65
  export function withholdScreenedStrings(
64
66
  values: readonly unknown[],
65
67
  enabled: boolean,
68
+ profile: InjectionScreenProfile = "default",
66
69
  ): { kept: string[]; withheldRules: string[] } {
67
70
  const kept: string[] = [];
68
71
  const withheldRules: string[] = [];
@@ -72,7 +75,7 @@ export function withholdScreenedStrings(
72
75
  kept.push(value);
73
76
  continue;
74
77
  }
75
- const screened = screenCandidateFact(value);
78
+ const screened = screenCandidateFact(value, profile);
76
79
  if (screened.quarantine) {
77
80
  withheldRules.push(...screened.findings.map((finding) => `injection-screen:${finding.rule}`));
78
81
  } else {
@@ -99,20 +102,20 @@ export interface ScreenedEntityWrite {
99
102
  * `withheldRules` (entities carry no review status; routing is #2397).
100
103
  * Returns null for entities without a usable name/type.
101
104
  */
102
- export function screenEntityForIndex(entity: unknown, enabled: boolean): ScreenedEntityWrite | null {
105
+ export function screenEntityForIndex(entity: unknown, enabled: boolean, profile: InjectionScreenProfile = "default"): ScreenedEntityWrite | null {
103
106
  const record = entity as { name?: unknown; type?: unknown; source?: unknown; facts?: unknown; structuredSections?: unknown } | null;
104
107
  const name = record?.name;
105
108
  const type = record?.type;
106
109
  if (typeof name !== "string" || !name.trim() || typeof type !== "string" || !type.trim()) return null;
107
110
  // #1955 review: the raw name is emitted as the entity target outside the
108
111
  // snippet fence — a flagged name withholds the whole entity from the index.
109
- const nameScreen = withholdScreenedStrings([name], enabled);
110
- const factScreen = withholdScreenedStrings(Array.isArray(record?.facts) ? record.facts : [], enabled);
112
+ const nameScreen = withholdScreenedStrings([name], enabled, profile);
113
+ const factScreen = withholdScreenedStrings(Array.isArray(record?.facts) ? record.facts : [], enabled, profile);
111
114
  const rawSections: EntityStructuredSection[] | undefined = Array.isArray(record?.structuredSections)
112
115
  ? (record.structuredSections as EntityStructuredSection[])
113
116
  : undefined;
114
117
  const sectionScreens = enabled && rawSections
115
- ? rawSections.map((section) => ({ section, screen: withholdScreenedStrings(section?.facts ?? [], true) }))
118
+ ? rawSections.map((section) => ({ section, screen: withholdScreenedStrings(section?.facts ?? [], true, profile) }))
116
119
  : undefined;
117
120
  return {
118
121
  name,
@@ -155,8 +158,9 @@ export function screenEntityForIndex(entity: unknown, enabled: boolean): Screene
155
158
  export function screenPersistStrings(
156
159
  values: readonly string[],
157
160
  enabled: boolean,
161
+ profile: InjectionScreenProfile = "default",
158
162
  ): { kept: string[]; warning?: string } {
159
- const screen = withholdScreenedStrings(values, enabled);
163
+ const screen = withholdScreenedStrings(values, enabled, profile);
160
164
  return {
161
165
  kept: screen.kept,
162
166
  ...(screen.withheldRules.length > 0
@@ -20,7 +20,7 @@ export function deriveExtractionOriginContext(
20
20
  targetTurns: readonly BufferTurn[],
21
21
  fallbackConnector?: string,
22
22
  ): Pick<ExtractionSourceContext, "turnRole" | "importAdapter" | "sourceConnector" | "originConflict"> {
23
- const originRoles = new Set(targetTurns.map((turn) => turn.role));
23
+ const originRoles = new Set(targetTurns.map((turn) => turn.originRole ?? turn.role));
24
24
  const turnRole = originRoles.size === 1 ? [...originRoles][0] : undefined;
25
25
  const originConnectors = new Set(
26
26
  targetTurns