@remnic/core 9.69.60 → 9.69.63

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 (360) hide show
  1. package/dist/access-admin-ops-surface.js +38 -38
  2. package/dist/access-authorization-probe.js +39 -39
  3. package/dist/access-boundary.js +38 -38
  4. package/dist/access-cli.js +95 -95
  5. package/dist/access-extraction-force-flush.js +38 -38
  6. package/dist/access-http-briefing.js +39 -39
  7. package/dist/access-http-query.js +40 -40
  8. package/dist/access-http.js +56 -56
  9. package/dist/access-identity-continuity-surface.js +38 -38
  10. package/dist/access-lcm-surface.js +38 -38
  11. package/dist/access-mcp.js +49 -49
  12. package/dist/access-memory-search-fanout.js +3 -3
  13. package/dist/access-namespace-preflight.js +38 -38
  14. package/dist/access-observe-write-surface.js +38 -38
  15. package/dist/access-offline-manifest.js +6 -6
  16. package/dist/access-operations-batch.js +40 -40
  17. package/dist/access-operations.js +47 -47
  18. package/dist/access-recall-concurrency.js +38 -38
  19. package/dist/access-recall-diagnostics.js +5 -5
  20. package/dist/access-recall-response.js +38 -38
  21. package/dist/access-recall-surface.js +38 -38
  22. package/dist/access-service.js +38 -38
  23. package/dist/access-surface-catalog.js +40 -40
  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-24TJ77TT.js} +2 -2
  40. package/dist/{chunk-ZLVUWROW.js → chunk-2OUSWDY6.js} +2 -2
  41. package/dist/{chunk-M5IJP3YW.js → chunk-2PKGJPQL.js} +2 -2
  42. package/dist/{chunk-FJMYMJLR.js → chunk-3JDA3XF5.js} +2 -2
  43. package/dist/{chunk-JGT7M3BA.js → chunk-3MSMBVA3.js} +6 -6
  44. package/dist/{chunk-6JYYSDHH.js → chunk-4EEDRKRT.js} +4 -4
  45. package/dist/{chunk-YUHGJBQK.js → chunk-5LWVTSF7.js} +2 -2
  46. package/dist/{chunk-WLZYGLJ4.js → chunk-5MA7ZLPD.js} +5 -7
  47. package/dist/chunk-5MA7ZLPD.js.map +1 -0
  48. package/dist/{chunk-2T2RF5ZK.js → chunk-5QZHDS4X.js} +5 -5
  49. package/dist/{chunk-64JK4TL7.js → chunk-5WXJE5TV.js} +4 -4
  50. package/dist/{chunk-DJ4CKWAD.js → chunk-5Y7VCE3A.js} +2 -2
  51. package/dist/{chunk-G2XZFGYN.js → chunk-62JTOLEX.js} +2 -2
  52. package/dist/{chunk-LVXBC6YB.js → chunk-65I2LZEK.js} +2 -2
  53. package/dist/{chunk-NZLFVLLJ.js → chunk-7CRUDH7G.js} +2 -2
  54. package/dist/{chunk-B4EGAHHS.js → chunk-7DE2NOON.js} +2 -2
  55. package/dist/{chunk-BSDBDFKZ.js → chunk-7JFQI6DQ.js} +3 -3
  56. package/dist/{chunk-BOADKFN4.js → chunk-7LNHRQKR.js} +2 -2
  57. package/dist/{chunk-IV6APZJS.js → chunk-7OC3Q5X4.js} +2 -2
  58. package/dist/{chunk-X2QPKLPL.js → chunk-ACX55QDO.js} +3 -3
  59. package/dist/{chunk-YLPCEUXP.js → chunk-AEGQ5PJ7.js} +2 -2
  60. package/dist/{chunk-GK6NOQE6.js → chunk-AERXJCOG.js} +2 -2
  61. package/dist/{chunk-HW2QYZEV.js → chunk-B5GMOOY2.js} +5 -5
  62. package/dist/{chunk-NLE6TSLG.js → chunk-BLVHDY2U.js} +5 -7
  63. package/dist/chunk-BLVHDY2U.js.map +1 -0
  64. package/dist/{chunk-JUOZ62Y7.js → chunk-BMXEBWBT.js} +2 -1
  65. package/dist/chunk-BMXEBWBT.js.map +1 -0
  66. package/dist/{chunk-YHGRA7CK.js → chunk-CDQO5DCD.js} +2 -2
  67. package/dist/{chunk-ENUI3IO7.js → chunk-D433RXFJ.js} +2 -2
  68. package/dist/{chunk-IK63WA5A.js → chunk-D4SPMHEW.js} +2 -2
  69. package/dist/{chunk-42DJ235G.js → chunk-DINRT75P.js} +2 -2
  70. package/dist/{chunk-LELJRLPY.js → chunk-DQFZOPDL.js} +2 -2
  71. package/dist/{chunk-WN4HFL4K.js → chunk-DQISIT63.js} +2 -2
  72. package/dist/{chunk-Q7KQ5YHT.js → chunk-EIU642TN.js} +2 -2
  73. package/dist/{chunk-EN2YX5SF.js → chunk-F4PEETM4.js} +3 -3
  74. package/dist/{chunk-FNQEXI3D.js → chunk-F5O6WEDO.js} +1 -1
  75. package/dist/{chunk-FNQEXI3D.js.map → chunk-F5O6WEDO.js.map} +1 -1
  76. package/dist/{chunk-Q6C5PIBW.js → chunk-F5ZCNJ3V.js} +3 -3
  77. package/dist/{chunk-KR5SZNNF.js → chunk-FEHVG4C4.js} +2 -2
  78. package/dist/{chunk-42G4FIKQ.js → chunk-FG5QU7A2.js} +4 -4
  79. package/dist/{chunk-IRGQYQQ7.js → chunk-FM5HN7LL.js} +4 -4
  80. package/dist/{chunk-FF2XYADH.js → chunk-FQGY7XB2.js} +6 -6
  81. package/dist/{chunk-FF2XYADH.js.map → chunk-FQGY7XB2.js.map} +1 -1
  82. package/dist/{chunk-IDBLAGIM.js → chunk-FTNV5476.js} +14 -14
  83. package/dist/{chunk-R4Y5PF25.js → chunk-FWVDTLRK.js} +1 -1
  84. package/dist/{chunk-C6FQJ52H.js → chunk-G2XTGEGL.js} +65 -18
  85. package/dist/chunk-G2XTGEGL.js.map +1 -0
  86. package/dist/{chunk-Q5FL3MEH.js → chunk-G4WZDQ32.js} +3 -3
  87. package/dist/{chunk-4HNY6ORZ.js → chunk-GMHWCPLP.js} +2 -2
  88. package/dist/{chunk-ZWWKKAJL.js → chunk-GYNCJSQ7.js} +4 -4
  89. package/dist/{chunk-BJI2D4SU.js → chunk-GZBNEZIU.js} +3 -3
  90. package/dist/{chunk-NYVECYCF.js → chunk-HNOKNHFO.js} +2 -2
  91. package/dist/{chunk-XLXYARWC.js → chunk-HXCJF4XU.js} +2 -2
  92. package/dist/{chunk-RMF763SX.js → chunk-IDRSTHVR.js} +5 -5
  93. package/dist/{chunk-UXREWVW4.js → chunk-IW3RMBPB.js} +2 -2
  94. package/dist/{chunk-W6YK672C.js → chunk-JTTLH646.js} +3 -3
  95. package/dist/{chunk-BQB5ZMYO.js → chunk-KKNZ7PUZ.js} +2 -2
  96. package/dist/{chunk-AAMFQHKI.js → chunk-KRPMISWO.js} +3 -3
  97. package/dist/{chunk-XX2IGMCB.js → chunk-KV44HTMJ.js} +2 -2
  98. package/dist/{chunk-FKFTPFUG.js → chunk-KXJ7XYUT.js} +2 -2
  99. package/dist/{chunk-2NZ7KWRW.js → chunk-LAEW4S43.js} +2 -2
  100. package/dist/{chunk-5SV2GFZX.js → chunk-LDP6LBDS.js} +2 -2
  101. package/dist/{chunk-F6WCOXTF.js → chunk-LMLPLIT4.js} +2 -2
  102. package/dist/{chunk-QJTFMH5Y.js → chunk-LVGVXG22.js} +2 -2
  103. package/dist/{chunk-OINFRHLR.js → chunk-NRTVZSPO.js} +2 -2
  104. package/dist/{chunk-IAZPYX6W.js → chunk-NRVGODSE.js} +3 -3
  105. package/dist/{chunk-IHOXK2I6.js → chunk-NVKO5YKP.js} +2 -2
  106. package/dist/{chunk-OQQXGYMX.js → chunk-OWYHHW67.js} +4 -4
  107. package/dist/{chunk-KPKGDQR3.js → chunk-PZEXA6CM.js} +2 -2
  108. package/dist/{chunk-DXODYQ7J.js → chunk-Q3THVX75.js} +2 -2
  109. package/dist/{chunk-TAC5WFJC.js → chunk-QEGKMZNQ.js} +4 -4
  110. package/dist/{chunk-VRF2KFI2.js → chunk-RA3C46VX.js} +2 -2
  111. package/dist/{chunk-V2HHAAPI.js → chunk-RB776UH3.js} +2 -2
  112. package/dist/{chunk-TAIIC5OM.js → chunk-SEHKTE4F.js} +3 -3
  113. package/dist/{chunk-3JLWSFTV.js → chunk-SVWYZXIL.js} +8 -5
  114. package/dist/{chunk-3JLWSFTV.js.map → chunk-SVWYZXIL.js.map} +1 -1
  115. package/dist/{chunk-G6E7XJYL.js → chunk-SZAWZPY6.js} +10 -10
  116. package/dist/{chunk-2AD5SXO4.js → chunk-T5IF2ZCE.js} +5 -2
  117. package/dist/chunk-T5IF2ZCE.js.map +1 -0
  118. package/dist/{chunk-TYZK56OA.js → chunk-TPRBJF46.js} +9 -9
  119. package/dist/{chunk-7DNMX7SA.js → chunk-TQC6ELJO.js} +2 -2
  120. package/dist/{chunk-OVJFS5P5.js → chunk-U6HXB2OG.js} +2 -2
  121. package/dist/{chunk-7WSQZJPC.js → chunk-V3JM4XEI.js} +4 -4
  122. package/dist/{chunk-36S7UHAW.js → chunk-VEBYLZQQ.js} +2 -2
  123. package/dist/{chunk-IMJPJY7V.js → chunk-VHF73MGU.js} +2 -2
  124. package/dist/{chunk-TDULASPE.js → chunk-VKDWYDFQ.js} +7 -7
  125. package/dist/{chunk-NKXHCCLB.js → chunk-VTPASHTO.js} +2 -2
  126. package/dist/{chunk-4B5S3VWD.js → chunk-VXGB766B.js} +29 -29
  127. package/dist/{chunk-ADP2VCP6.js → chunk-W5UAB6EH.js} +5 -5
  128. package/dist/{chunk-L3R24OLZ.js → chunk-W65KK3X6.js} +2 -2
  129. package/dist/{chunk-BJX6G726.js → chunk-WAR75CRY.js} +67 -64
  130. package/dist/chunk-WAR75CRY.js.map +1 -0
  131. package/dist/{chunk-MNIPH6LD.js → chunk-WBYQA3VN.js} +3 -3
  132. package/dist/{chunk-WD2JD2UB.js → chunk-WEQZ5OYK.js} +2 -2
  133. package/dist/{chunk-AJW2K7K3.js → chunk-WKNWC46C.js} +2 -2
  134. package/dist/{chunk-UD6J2LIA.js → chunk-XDH5MO6L.js} +2 -2
  135. package/dist/{chunk-MRV7VSQK.js → chunk-Y23L4YJV.js} +2 -2
  136. package/dist/{chunk-6ISP2EN2.js → chunk-YF3JERFZ.js} +2 -2
  137. package/dist/{chunk-C5CPYMLX.js → chunk-YR6A6ZK7.js} +2 -2
  138. package/dist/{chunk-EJO2NWW7.js → chunk-Z3YQOV45.js} +2 -2
  139. package/dist/{chunk-6KTXE6A3.js → chunk-Z4TXB4K7.js} +2 -2
  140. package/dist/{chunk-Y76HXF3F.js → chunk-ZDZJ2PG4.js} +393 -41
  141. package/dist/{chunk-Y76HXF3F.js.map → chunk-ZDZJ2PG4.js.map} +1 -1
  142. package/dist/{chunk-6VITOSPL.js → chunk-ZFUPRODV.js} +2 -2
  143. package/dist/cli.js +70 -70
  144. package/dist/coding/export-okf-codegraph.js +7 -7
  145. package/dist/compounding/engine.js +9 -9
  146. package/dist/config-security.d.ts +4 -0
  147. package/dist/config-security.d.ts.map +1 -1
  148. package/dist/config-security.js +2 -2
  149. package/dist/config.js +9 -9
  150. package/dist/connectors/codex-materialize-runner.js +8 -8
  151. package/dist/connectors/index.js +9 -9
  152. package/dist/contradiction/index.js +3 -3
  153. package/dist/{contradiction-scan-GVD4JJ7B.js → contradiction-scan-5EJYRKD3.js} +3 -3
  154. package/dist/convergence-refresh.js +10 -10
  155. package/dist/corpus-watermark.js +10 -10
  156. package/dist/day-summary.js +2 -2
  157. package/dist/embedding-fallback.js +2 -2
  158. package/dist/entity-retrieval.js +9 -9
  159. package/dist/explicit-capture.js +2 -2
  160. package/dist/external-wiki-access.js +39 -39
  161. package/dist/extraction-judge.js +3 -3
  162. package/dist/extraction-normalization.js +3 -3
  163. package/dist/extraction-prompt.js +2 -2
  164. package/dist/extraction.js +21 -21
  165. package/dist/{first-start-migration-L3UFX5CU.js → first-start-migration-7OATHJKB.js} +2 -2
  166. package/dist/harmonic-retrieval.js +1 -1
  167. package/dist/index.d.ts +3 -3
  168. package/dist/index.d.ts.map +1 -1
  169. package/dist/index.js +99 -95
  170. package/dist/local-llm.js +2 -2
  171. package/dist/location/index.js +10 -10
  172. package/dist/maintenance/memory-governance.js +8 -8
  173. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +8 -8
  174. package/dist/maintenance/rebuild-memory-projection.js +9 -9
  175. package/dist/memory-browse-operations.js +39 -39
  176. package/dist/model-registry.d.ts.map +1 -1
  177. package/dist/model-registry.js +1 -1
  178. package/dist/namespaces/migrate.js +9 -9
  179. package/dist/namespaces/principal.js +2 -2
  180. package/dist/namespaces/search.js +4 -4
  181. package/dist/namespaces/storage.js +8 -8
  182. package/dist/offline-sync-impression-drain.js +5 -5
  183. package/dist/operator-doctor-corpus.js +11 -11
  184. package/dist/operator-toolkit.js +21 -21
  185. package/dist/orchestration/compression-guideline-coordinator.js +2 -2
  186. package/dist/orchestration/extraction-injection-gate.d.ts +5 -4
  187. package/dist/orchestration/extraction-injection-gate.d.ts.map +1 -1
  188. package/dist/orchestration/maintenance.js +20 -20
  189. package/dist/orchestration/turn-ingestion.d.ts.map +1 -1
  190. package/dist/orchestrator.js +95 -95
  191. package/dist/profiling.d.ts.map +1 -1
  192. package/dist/profiling.js +1 -1
  193. package/dist/recall-composition-decision.js +3 -3
  194. package/dist/recall-context-composition.js +2 -2
  195. package/dist/recall-explain-renderer.js +3 -3
  196. package/dist/recall-navigate-access.js +2 -2
  197. package/dist/recall-navigate-disclosure.js +2 -2
  198. package/dist/recall-navigate.js +2 -2
  199. package/dist/recall-navigation-operations.js +39 -39
  200. package/dist/recall-navigation.js +38 -38
  201. package/dist/recall-why-service.js +5 -5
  202. package/dist/recall-why.js +3 -3
  203. package/dist/recall-xray-cli.js +4 -4
  204. package/dist/recall-xray-renderer.js +3 -3
  205. package/dist/recall-xray.js +2 -2
  206. package/dist/{resolution-CHNISQJB.js → resolution-UYJU5JUA.js} +4 -4
  207. package/dist/resume-bundles.js +10 -10
  208. package/dist/search/embed-helper.js +2 -2
  209. package/dist/search/factory.js +3 -3
  210. package/dist/search/index.js +3 -3
  211. package/dist/security/audit-memory-cli.d.ts.map +1 -1
  212. package/dist/security/audit-memory.d.ts +13 -0
  213. package/dist/security/audit-memory.d.ts.map +1 -1
  214. package/dist/security/injection-screen.d.ts +2 -2
  215. package/dist/security/injection-screen.d.ts.map +1 -1
  216. package/dist/security/origin-authority.d.ts +3 -0
  217. package/dist/security/origin-authority.d.ts.map +1 -1
  218. package/dist/security/types.d.ts +5 -0
  219. package/dist/security/types.d.ts.map +1 -1
  220. package/dist/semantic-consolidation.js +9 -9
  221. package/dist/semantic-rule-promotion.js +8 -8
  222. package/dist/semantic-rule-verifier.js +8 -8
  223. package/dist/shared-context/manager.js +2 -2
  224. package/dist/source-agent-qualifier.js +14 -14
  225. package/dist/standup/build.js +8 -8
  226. package/dist/storage.js +7 -7
  227. package/dist/summarizer.js +4 -4
  228. package/dist/support-passport/index.js +41 -41
  229. package/dist/temporal-timeline-recall.js +3 -3
  230. package/dist/{tier-stats-VK5PCO2L.js → tier-stats-VF6DS52E.js} +2 -2
  231. package/dist/transfer/export-okf.js +8 -8
  232. package/dist/types.d.ts +4 -3
  233. package/dist/types.d.ts.map +1 -1
  234. package/dist/types.js +1 -1
  235. package/dist/verified-recall.js +8 -8
  236. package/dist/who-knows-cli.js +9 -9
  237. package/dist/who-knows.js +8 -8
  238. package/package.json +12 -2
  239. package/src/buffer-turn-helpers.ts +4 -0
  240. package/src/buffer.ts +3 -0
  241. package/src/capabilities.test.ts +4 -1
  242. package/src/capabilities.ts +7 -7
  243. package/src/config-security.ts +103 -16
  244. package/src/config.test.ts +58 -1
  245. package/src/connector-provenance-lifecycle.test.ts +19 -0
  246. package/src/index.ts +3 -3
  247. package/src/model-registry.test.ts +22 -1
  248. package/src/model-registry.ts +7 -6
  249. package/src/orchestration/extraction-injection-gate.ts +11 -7
  250. package/src/orchestration/extraction-origin-context.ts +1 -1
  251. package/src/orchestration/extraction-persist.ts +8 -8
  252. package/src/orchestration/extraction-security.test.ts +12 -0
  253. package/src/orchestration/turn-ingestion.ts +2 -0
  254. package/src/profiling.test.ts +20 -1
  255. package/src/profiling.ts +7 -7
  256. package/src/security/audit-memory-cli.test.ts +90 -0
  257. package/src/security/audit-memory-cli.ts +7 -0
  258. package/src/security/audit-memory.test.ts +21 -10
  259. package/src/security/audit-memory.ts +20 -2
  260. package/src/security/injection-screen.test.ts +301 -0
  261. package/src/security/injection-screen.ts +414 -11
  262. package/src/security/origin-authority.ts +10 -0
  263. package/src/security/types.ts +11 -0
  264. package/src/types.ts +4 -3
  265. package/dist/chunk-2AD5SXO4.js.map +0 -1
  266. package/dist/chunk-6Q3ZTEF6.js.map +0 -1
  267. package/dist/chunk-BJX6G726.js.map +0 -1
  268. package/dist/chunk-C6FQJ52H.js.map +0 -1
  269. package/dist/chunk-JUOZ62Y7.js.map +0 -1
  270. package/dist/chunk-NLE6TSLG.js.map +0 -1
  271. package/dist/chunk-WLZYGLJ4.js.map +0 -1
  272. /package/dist/{auto-sync-CWSZDLLW.js.map → auto-sync-QJNIKZHV.js.map} +0 -0
  273. /package/dist/{chunk-RP7TZEI6.js.map → chunk-24TJ77TT.js.map} +0 -0
  274. /package/dist/{chunk-ZLVUWROW.js.map → chunk-2OUSWDY6.js.map} +0 -0
  275. /package/dist/{chunk-M5IJP3YW.js.map → chunk-2PKGJPQL.js.map} +0 -0
  276. /package/dist/{chunk-FJMYMJLR.js.map → chunk-3JDA3XF5.js.map} +0 -0
  277. /package/dist/{chunk-JGT7M3BA.js.map → chunk-3MSMBVA3.js.map} +0 -0
  278. /package/dist/{chunk-6JYYSDHH.js.map → chunk-4EEDRKRT.js.map} +0 -0
  279. /package/dist/{chunk-YUHGJBQK.js.map → chunk-5LWVTSF7.js.map} +0 -0
  280. /package/dist/{chunk-2T2RF5ZK.js.map → chunk-5QZHDS4X.js.map} +0 -0
  281. /package/dist/{chunk-64JK4TL7.js.map → chunk-5WXJE5TV.js.map} +0 -0
  282. /package/dist/{chunk-DJ4CKWAD.js.map → chunk-5Y7VCE3A.js.map} +0 -0
  283. /package/dist/{chunk-G2XZFGYN.js.map → chunk-62JTOLEX.js.map} +0 -0
  284. /package/dist/{chunk-LVXBC6YB.js.map → chunk-65I2LZEK.js.map} +0 -0
  285. /package/dist/{chunk-NZLFVLLJ.js.map → chunk-7CRUDH7G.js.map} +0 -0
  286. /package/dist/{chunk-B4EGAHHS.js.map → chunk-7DE2NOON.js.map} +0 -0
  287. /package/dist/{chunk-BSDBDFKZ.js.map → chunk-7JFQI6DQ.js.map} +0 -0
  288. /package/dist/{chunk-BOADKFN4.js.map → chunk-7LNHRQKR.js.map} +0 -0
  289. /package/dist/{chunk-IV6APZJS.js.map → chunk-7OC3Q5X4.js.map} +0 -0
  290. /package/dist/{chunk-X2QPKLPL.js.map → chunk-ACX55QDO.js.map} +0 -0
  291. /package/dist/{chunk-YLPCEUXP.js.map → chunk-AEGQ5PJ7.js.map} +0 -0
  292. /package/dist/{chunk-GK6NOQE6.js.map → chunk-AERXJCOG.js.map} +0 -0
  293. /package/dist/{chunk-HW2QYZEV.js.map → chunk-B5GMOOY2.js.map} +0 -0
  294. /package/dist/{chunk-YHGRA7CK.js.map → chunk-CDQO5DCD.js.map} +0 -0
  295. /package/dist/{chunk-ENUI3IO7.js.map → chunk-D433RXFJ.js.map} +0 -0
  296. /package/dist/{chunk-IK63WA5A.js.map → chunk-D4SPMHEW.js.map} +0 -0
  297. /package/dist/{chunk-42DJ235G.js.map → chunk-DINRT75P.js.map} +0 -0
  298. /package/dist/{chunk-LELJRLPY.js.map → chunk-DQFZOPDL.js.map} +0 -0
  299. /package/dist/{chunk-WN4HFL4K.js.map → chunk-DQISIT63.js.map} +0 -0
  300. /package/dist/{chunk-Q7KQ5YHT.js.map → chunk-EIU642TN.js.map} +0 -0
  301. /package/dist/{chunk-EN2YX5SF.js.map → chunk-F4PEETM4.js.map} +0 -0
  302. /package/dist/{chunk-Q6C5PIBW.js.map → chunk-F5ZCNJ3V.js.map} +0 -0
  303. /package/dist/{chunk-KR5SZNNF.js.map → chunk-FEHVG4C4.js.map} +0 -0
  304. /package/dist/{chunk-42G4FIKQ.js.map → chunk-FG5QU7A2.js.map} +0 -0
  305. /package/dist/{chunk-IRGQYQQ7.js.map → chunk-FM5HN7LL.js.map} +0 -0
  306. /package/dist/{chunk-IDBLAGIM.js.map → chunk-FTNV5476.js.map} +0 -0
  307. /package/dist/{chunk-R4Y5PF25.js.map → chunk-FWVDTLRK.js.map} +0 -0
  308. /package/dist/{chunk-Q5FL3MEH.js.map → chunk-G4WZDQ32.js.map} +0 -0
  309. /package/dist/{chunk-4HNY6ORZ.js.map → chunk-GMHWCPLP.js.map} +0 -0
  310. /package/dist/{chunk-ZWWKKAJL.js.map → chunk-GYNCJSQ7.js.map} +0 -0
  311. /package/dist/{chunk-BJI2D4SU.js.map → chunk-GZBNEZIU.js.map} +0 -0
  312. /package/dist/{chunk-NYVECYCF.js.map → chunk-HNOKNHFO.js.map} +0 -0
  313. /package/dist/{chunk-XLXYARWC.js.map → chunk-HXCJF4XU.js.map} +0 -0
  314. /package/dist/{chunk-RMF763SX.js.map → chunk-IDRSTHVR.js.map} +0 -0
  315. /package/dist/{chunk-UXREWVW4.js.map → chunk-IW3RMBPB.js.map} +0 -0
  316. /package/dist/{chunk-W6YK672C.js.map → chunk-JTTLH646.js.map} +0 -0
  317. /package/dist/{chunk-BQB5ZMYO.js.map → chunk-KKNZ7PUZ.js.map} +0 -0
  318. /package/dist/{chunk-AAMFQHKI.js.map → chunk-KRPMISWO.js.map} +0 -0
  319. /package/dist/{chunk-XX2IGMCB.js.map → chunk-KV44HTMJ.js.map} +0 -0
  320. /package/dist/{chunk-FKFTPFUG.js.map → chunk-KXJ7XYUT.js.map} +0 -0
  321. /package/dist/{chunk-2NZ7KWRW.js.map → chunk-LAEW4S43.js.map} +0 -0
  322. /package/dist/{chunk-5SV2GFZX.js.map → chunk-LDP6LBDS.js.map} +0 -0
  323. /package/dist/{chunk-F6WCOXTF.js.map → chunk-LMLPLIT4.js.map} +0 -0
  324. /package/dist/{chunk-QJTFMH5Y.js.map → chunk-LVGVXG22.js.map} +0 -0
  325. /package/dist/{chunk-OINFRHLR.js.map → chunk-NRTVZSPO.js.map} +0 -0
  326. /package/dist/{chunk-IAZPYX6W.js.map → chunk-NRVGODSE.js.map} +0 -0
  327. /package/dist/{chunk-IHOXK2I6.js.map → chunk-NVKO5YKP.js.map} +0 -0
  328. /package/dist/{chunk-OQQXGYMX.js.map → chunk-OWYHHW67.js.map} +0 -0
  329. /package/dist/{chunk-KPKGDQR3.js.map → chunk-PZEXA6CM.js.map} +0 -0
  330. /package/dist/{chunk-DXODYQ7J.js.map → chunk-Q3THVX75.js.map} +0 -0
  331. /package/dist/{chunk-TAC5WFJC.js.map → chunk-QEGKMZNQ.js.map} +0 -0
  332. /package/dist/{chunk-VRF2KFI2.js.map → chunk-RA3C46VX.js.map} +0 -0
  333. /package/dist/{chunk-V2HHAAPI.js.map → chunk-RB776UH3.js.map} +0 -0
  334. /package/dist/{chunk-TAIIC5OM.js.map → chunk-SEHKTE4F.js.map} +0 -0
  335. /package/dist/{chunk-G6E7XJYL.js.map → chunk-SZAWZPY6.js.map} +0 -0
  336. /package/dist/{chunk-TYZK56OA.js.map → chunk-TPRBJF46.js.map} +0 -0
  337. /package/dist/{chunk-7DNMX7SA.js.map → chunk-TQC6ELJO.js.map} +0 -0
  338. /package/dist/{chunk-OVJFS5P5.js.map → chunk-U6HXB2OG.js.map} +0 -0
  339. /package/dist/{chunk-7WSQZJPC.js.map → chunk-V3JM4XEI.js.map} +0 -0
  340. /package/dist/{chunk-36S7UHAW.js.map → chunk-VEBYLZQQ.js.map} +0 -0
  341. /package/dist/{chunk-IMJPJY7V.js.map → chunk-VHF73MGU.js.map} +0 -0
  342. /package/dist/{chunk-TDULASPE.js.map → chunk-VKDWYDFQ.js.map} +0 -0
  343. /package/dist/{chunk-NKXHCCLB.js.map → chunk-VTPASHTO.js.map} +0 -0
  344. /package/dist/{chunk-4B5S3VWD.js.map → chunk-VXGB766B.js.map} +0 -0
  345. /package/dist/{chunk-ADP2VCP6.js.map → chunk-W5UAB6EH.js.map} +0 -0
  346. /package/dist/{chunk-L3R24OLZ.js.map → chunk-W65KK3X6.js.map} +0 -0
  347. /package/dist/{chunk-MNIPH6LD.js.map → chunk-WBYQA3VN.js.map} +0 -0
  348. /package/dist/{chunk-WD2JD2UB.js.map → chunk-WEQZ5OYK.js.map} +0 -0
  349. /package/dist/{chunk-AJW2K7K3.js.map → chunk-WKNWC46C.js.map} +0 -0
  350. /package/dist/{chunk-UD6J2LIA.js.map → chunk-XDH5MO6L.js.map} +0 -0
  351. /package/dist/{chunk-MRV7VSQK.js.map → chunk-Y23L4YJV.js.map} +0 -0
  352. /package/dist/{chunk-6ISP2EN2.js.map → chunk-YF3JERFZ.js.map} +0 -0
  353. /package/dist/{chunk-C5CPYMLX.js.map → chunk-YR6A6ZK7.js.map} +0 -0
  354. /package/dist/{chunk-EJO2NWW7.js.map → chunk-Z3YQOV45.js.map} +0 -0
  355. /package/dist/{chunk-6KTXE6A3.js.map → chunk-Z4TXB4K7.js.map} +0 -0
  356. /package/dist/{chunk-6VITOSPL.js.map → chunk-ZFUPRODV.js.map} +0 -0
  357. /package/dist/{contradiction-scan-GVD4JJ7B.js.map → contradiction-scan-5EJYRKD3.js.map} +0 -0
  358. /package/dist/{first-start-migration-L3UFX5CU.js.map → first-start-migration-7OATHJKB.js.map} +0 -0
  359. /package/dist/{resolution-CHNISQJB.js.map → resolution-UYJU5JUA.js.map} +0 -0
  360. /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.63",
4
4
  "description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -2620,6 +2620,16 @@
2620
2620
  "remnic-source": "./src/session-integrity.ts",
2621
2621
  "import": "./dist/session-integrity.js"
2622
2622
  },
2623
+ "./recall-handles": {
2624
+ "types": "./dist/recall-handles.d.ts",
2625
+ "remnic-source": "./src/recall-handles.ts",
2626
+ "import": "./dist/recall-handles.js"
2627
+ },
2628
+ "./recall-handles.js": {
2629
+ "types": "./dist/recall-handles.d.ts",
2630
+ "remnic-source": "./src/recall-handles.ts",
2631
+ "import": "./dist/recall-handles.js"
2632
+ },
2623
2633
  "./session-namespace-bindings": {
2624
2634
  "types": "./dist/session-namespace-bindings.d.ts",
2625
2635
  "remnic-source": "./src/session-namespace-bindings.ts",
@@ -3307,7 +3317,7 @@
3307
3317
  "core"
3308
3318
  ],
3309
3319
  "peerDependencies": {
3310
- "@remnic/coding-graph": "^9.69.60"
3320
+ "@remnic/coding-graph": "^9.69.63"
3311
3321
  },
3312
3322
  "peerDependenciesMeta": {
3313
3323
  "@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,9 +387,9 @@ 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";
392
- export { auditMemoryStore, formatAuditMemoryReport, type AuditMemoryReport } from "./security/audit-memory.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
+ export { auditMemoryStore, auditScreenProfile, formatAuditMemoryReport, type AuditMemoryReport } from "./security/audit-memory.js";
393
393
  // Access layer (HTTP + MCP + schema validation)
394
394
  // ---------------------------------------------------------------------------
395
395
 
@@ -1,5 +1,5 @@
1
1
  import assert from "node:assert/strict";
2
- import { mkdtempSync, rmSync } from "node:fs";
2
+ import { existsSync, mkdtempSync, rmSync } from "node:fs";
3
3
  import { tmpdir } from "node:os";
4
4
  import { join } from "node:path";
5
5
  import test from "node:test";
@@ -36,3 +36,24 @@ test("calculateContextSizes ignores invalid or tiny override values before budge
36
36
  rmSync(dir, { recursive: true, force: true });
37
37
  }
38
38
  });
39
+
40
+ test("construction never creates the registry dir; the first save does", () => {
41
+ const dir = mkdtempSync(join(tmpdir(), "remnic-model-registry-"));
42
+ const registryDir = join(dir, ".registry");
43
+ try {
44
+ const registry = new ModelRegistry(dir);
45
+ // Constructing a registry happens on every plugin registration, including
46
+ // read-only discovery passes, so it must not touch the memory dir.
47
+ assert.equal(existsSync(registryDir), false, "no dir before anything is cached");
48
+ registry.setCapabilities("local-model", {
49
+ maxPositionEmbeddings: 32_768,
50
+ contextWindow: 32_768,
51
+ supportsExtendedContext: false,
52
+ typicalOutputTokens: 2_048,
53
+ source: "manual",
54
+ });
55
+ assert.equal(existsSync(registryDir), true, "the first cached model creates it");
56
+ } finally {
57
+ rmSync(dir, { recursive: true, force: true });
58
+ }
59
+ });
@@ -5,7 +5,7 @@
5
5
 
6
6
  import { log } from "./logger.js";
7
7
  import fs from "node:fs";
8
- import { join } from "node:path";
8
+ import { dirname, join } from "node:path";
9
9
 
10
10
  export interface ModelCapabilities {
11
11
  modelId: string;
@@ -116,11 +116,7 @@ export class ModelRegistry {
116
116
  private readonly CACHE_TTL_DAYS = 7;
117
117
 
118
118
  constructor(memoryDir: string) {
119
- const registryDir = join(memoryDir, ".registry");
120
- if (!fs.existsSync(registryDir)) {
121
- fs.mkdirSync(registryDir, { recursive: true });
122
- }
123
- this.registryPath = join(registryDir, "model-capabilities.json");
119
+ this.registryPath = join(memoryDir, ".registry", "model-capabilities.json");
124
120
  this.data = this.loadRegistry();
125
121
  }
126
122
 
@@ -140,6 +136,11 @@ export class ModelRegistry {
140
136
 
141
137
  private saveRegistry(): void {
142
138
  try {
139
+ // Created on first save, never at construction: building a registry
140
+ // happens on every plugin registration, including read-only discovery
141
+ // passes, and must not touch the operator's memory dir.
142
+ const registryDir = dirname(this.registryPath);
143
+ if (!fs.existsSync(registryDir)) fs.mkdirSync(registryDir, { recursive: true });
143
144
  fs.writeFileSync(this.registryPath, JSON.stringify(this.data, null, 2));
144
145
  } catch (err) {
145
146
  log.warn(`ModelRegistry: failed to save registry: ${err}`);