@remnic/core 9.65.2 → 9.65.4

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 (492) hide show
  1. package/dist/access-admin-ops-surface.d.ts +44 -44
  2. package/dist/access-admin-ops-surface.js +21 -19
  3. package/dist/access-authorization-probe.d.ts +38 -38
  4. package/dist/access-authorization-probe.js +22 -20
  5. package/dist/access-boundary.d.ts +40 -40
  6. package/dist/access-boundary.js +21 -19
  7. package/dist/access-cli.js +62 -60
  8. package/dist/access-cli.js.map +1 -1
  9. package/dist/access-coding-context-resolution.d.ts +3 -1
  10. package/dist/access-extraction-force-flush.d.ts +25 -25
  11. package/dist/access-extraction-force-flush.js +21 -19
  12. package/dist/access-health-types.d.ts +3 -1
  13. package/dist/access-http-lcm-compaction.d.ts +39 -39
  14. package/dist/access-http-lifecycle-flush.d.ts +39 -39
  15. package/dist/access-http-offline-stream.d.ts +25 -25
  16. package/dist/access-http-query.d.ts +4 -2
  17. package/dist/access-http-query.js +23 -21
  18. package/dist/access-http.d.ts +51 -44
  19. package/dist/access-http.js +37 -35
  20. package/dist/access-identity-continuity-surface.d.ts +12 -12
  21. package/dist/access-identity-continuity-surface.js +21 -19
  22. package/dist/access-lcm-surface.d.ts +27 -27
  23. package/dist/access-lcm-surface.js +21 -19
  24. package/dist/access-mcp-admin-tools.d.ts +9 -1
  25. package/dist/access-mcp-admin-tools.js +3 -1
  26. package/dist/access-mcp-output-schemas.js +1 -1
  27. package/dist/access-mcp.d.ts +39 -39
  28. package/dist/access-mcp.js +31 -29
  29. package/dist/access-memory-search-fanout.d.ts +4 -2
  30. package/dist/{access-namespace-preflight-Dhvcl-T0.d.ts → access-namespace-preflight-D_6mo8ms.d.ts} +1 -1
  31. package/dist/access-namespace-preflight.d.ts +5 -3
  32. package/dist/access-namespace-preflight.js +21 -19
  33. package/dist/access-observe-write-surface.d.ts +39 -39
  34. package/dist/access-observe-write-surface.js +21 -19
  35. package/dist/access-offline-manifest.d.ts +12 -12
  36. package/dist/access-offline-manifest.js +3 -3
  37. package/dist/access-operations-batch.js +25 -23
  38. package/dist/access-operations.d.ts +40 -40
  39. package/dist/access-operations.js +28 -26
  40. package/dist/access-recall-concurrency.d.ts +40 -40
  41. package/dist/access-recall-concurrency.js +21 -19
  42. package/dist/access-recall-response.d.ts +24 -24
  43. package/dist/access-recall-response.js +21 -19
  44. package/dist/access-recall-surface.d.ts +24 -24
  45. package/dist/access-recall-surface.js +21 -19
  46. package/dist/access-schema.d.ts +45 -45
  47. package/dist/{access-service-Bke1alZO.d.ts → access-service-DqPa3hy4.d.ts} +219 -75
  48. package/dist/access-service-helpers.d.ts +40 -40
  49. package/dist/access-service.d.ts +47 -47
  50. package/dist/access-service.js +21 -19
  51. package/dist/access-surface-catalog.d.ts +40 -40
  52. package/dist/access-surface-catalog.js +27 -21
  53. package/dist/access-surface-catalog.js.map +1 -1
  54. package/dist/access-wearables-meetings-surface.d.ts +5 -3
  55. package/dist/action-confidence.d.ts +3 -1
  56. package/dist/active-memory-bridge.d.ts +3 -1
  57. package/dist/active-recall.d.ts +3 -1
  58. package/dist/active-recall.js +10 -1
  59. package/dist/active-recall.js.map +1 -1
  60. package/dist/ambient-provenance.d.ts +3 -1
  61. package/dist/artifact-search.d.ts +3 -1
  62. package/dist/{auto-sync-H64ZCNIR.js → auto-sync-XVMLL2RH.js} +5 -5
  63. package/dist/behavior-learner.d.ts +3 -1
  64. package/dist/behavior-signals.d.ts +3 -1
  65. package/dist/bootstrap.d.ts +12 -12
  66. package/dist/briefing-window.d.ts +4 -2
  67. package/dist/briefing.d.ts +4 -2
  68. package/dist/briefing.js +4 -4
  69. package/dist/buffer-surprise-report.d.ts +3 -1
  70. package/dist/buffer-turn-helpers.d.ts +3 -1
  71. package/dist/buffer.d.ts +4 -2
  72. package/dist/bulk-import/index.d.ts +5 -3
  73. package/dist/calibration.d.ts +3 -1
  74. package/dist/capabilities.d.ts +3 -1
  75. package/dist/{catalog-DV6qnbr7.d.ts → catalog-DO_7zfkv.d.ts} +1 -1
  76. package/dist/causal-behavior.d.ts +1 -1
  77. package/dist/causal-consolidation.d.ts +3 -1
  78. package/dist/causal-consolidation.js +12 -9
  79. package/dist/causal-consolidation.js.map +1 -1
  80. package/dist/causal-trajectory-graph.d.ts +1 -1
  81. package/dist/chunk-236PXYG7.js +232 -0
  82. package/dist/chunk-236PXYG7.js.map +1 -0
  83. package/dist/{chunk-YB42WZCY.js → chunk-2IXQSGCU.js} +2 -2
  84. package/dist/{chunk-PE255F4T.js → chunk-2MVTAIL3.js} +2 -2
  85. package/dist/{chunk-LGO6A7GJ.js → chunk-3JZBPTLD.js} +338 -80
  86. package/dist/chunk-3JZBPTLD.js.map +1 -0
  87. package/dist/{chunk-GDFVPUJ5.js → chunk-3NH3VP3U.js} +2 -2
  88. package/dist/{chunk-TBOJ76ER.js → chunk-AB3A7EFH.js} +18 -2
  89. package/dist/{chunk-TBOJ76ER.js.map → chunk-AB3A7EFH.js.map} +1 -1
  90. package/dist/{chunk-GNCCUR6K.js → chunk-AXGFOFNY.js} +2 -2
  91. package/dist/{chunk-SB7D4BT7.js → chunk-AZLLH6YA.js} +1554 -114
  92. package/dist/chunk-AZLLH6YA.js.map +1 -0
  93. package/dist/{chunk-5YQ63T4B.js → chunk-BK5G2MHO.js} +2 -2
  94. package/dist/{chunk-LZH5FR2W.js → chunk-CQBIN77D.js} +2 -2
  95. package/dist/{chunk-35NN3ZFA.js → chunk-CTVWELNK.js} +21 -3
  96. package/dist/chunk-CTVWELNK.js.map +1 -0
  97. package/dist/{chunk-NKKD4ZAU.js → chunk-DORFF5N5.js} +2 -2
  98. package/dist/{chunk-BWLRUMOG.js → chunk-DPNXADEI.js} +441 -2
  99. package/dist/chunk-DPNXADEI.js.map +1 -0
  100. package/dist/{chunk-SQI57UCJ.js → chunk-DUEDOYZD.js} +2 -2
  101. package/dist/{chunk-5NM4OH4P.js → chunk-DUZARALI.js} +3 -3
  102. package/dist/{chunk-2E36UXVW.js → chunk-ECLJ4LA2.js} +2 -2
  103. package/dist/{chunk-TZNQUNKL.js → chunk-FC7TIRFS.js} +15 -1
  104. package/dist/chunk-FC7TIRFS.js.map +1 -0
  105. package/dist/{chunk-IID2CMUU.js → chunk-GHD2LLG4.js} +2 -2
  106. package/dist/{chunk-ZQHI2BZB.js → chunk-HF5BUTI6.js} +2 -2
  107. package/dist/{chunk-3DVBKTSO.js → chunk-HSZMX3ZJ.js} +4 -4
  108. package/dist/{chunk-S2DPMJXH.js → chunk-I23ZHYSL.js} +2 -2
  109. package/dist/{chunk-ODZG724P.js → chunk-I2HTKOOP.js} +2 -2
  110. package/dist/chunk-I32NKXE2.js +879 -0
  111. package/dist/chunk-I32NKXE2.js.map +1 -0
  112. package/dist/{chunk-NTWN6HB2.js → chunk-IURMJBGP.js} +2 -2
  113. package/dist/{chunk-OCZIYAE5.js → chunk-IWKGOCL6.js} +3 -3
  114. package/dist/{chunk-UXO5IMBK.js → chunk-J3ATBB7M.js} +2 -2
  115. package/dist/{chunk-Y7DK7HHJ.js → chunk-JPAKBNTM.js} +2 -2
  116. package/dist/{chunk-SPUJNJJC.js → chunk-KFIOPZ25.js} +2 -2
  117. package/dist/{chunk-JYYBA7TF.js → chunk-KOO37E4Y.js} +2 -2
  118. package/dist/{chunk-OTHZWLUD.js → chunk-KPB2QHJZ.js} +2 -2
  119. package/dist/{chunk-SBDCZ2AX.js → chunk-LBFFNDFM.js} +1 -1
  120. package/dist/chunk-LBFFNDFM.js.map +1 -0
  121. package/dist/{chunk-CT56C22C.js → chunk-LYBIHM4N.js} +4 -4
  122. package/dist/{chunk-3I7ASZN3.js → chunk-MFOSZUIT.js} +2 -2
  123. package/dist/{chunk-DZUJ46DO.js → chunk-NLEH4RTB.js} +2 -2
  124. package/dist/{chunk-ZO6AXLEH.js → chunk-OCCHUEZB.js} +2 -2
  125. package/dist/{chunk-EILZG5VC.js → chunk-OU34IQXV.js} +2 -2
  126. package/dist/{chunk-2XDWWPTN.js → chunk-OZDFB22S.js} +2 -2
  127. package/dist/{chunk-UIN2BWDD.js → chunk-PTZQYCJ4.js} +2 -2
  128. package/dist/{chunk-7BY7V4YX.js → chunk-Q4WONDMJ.js} +4 -3
  129. package/dist/{chunk-7BY7V4YX.js.map → chunk-Q4WONDMJ.js.map} +1 -1
  130. package/dist/{chunk-Z7PBQPJ4.js → chunk-QJW4MZSW.js} +2 -2
  131. package/dist/{chunk-R7JAM2XF.js → chunk-R2MZCYA6.js} +3 -3
  132. package/dist/{chunk-TF77C7SV.js → chunk-SR5LNI6Q.js} +7 -5
  133. package/dist/chunk-SR5LNI6Q.js.map +1 -0
  134. package/dist/{chunk-LBWQ65SX.js → chunk-T42L3S6A.js} +4 -4
  135. package/dist/{chunk-J275IYMG.js → chunk-THVI4Y7X.js} +34 -7
  136. package/dist/chunk-THVI4Y7X.js.map +1 -0
  137. package/dist/{chunk-QOS5LBZN.js → chunk-TJFI3K2O.js} +15 -3
  138. package/dist/chunk-TJFI3K2O.js.map +1 -0
  139. package/dist/{chunk-2YI72KM3.js → chunk-UCKG36HO.js} +2 -2
  140. package/dist/{chunk-SIHSCCUQ.js → chunk-UFR6HX7A.js} +1 -1
  141. package/dist/{chunk-CDUUDBWJ.js → chunk-VFYRYFLL.js} +2 -2
  142. package/dist/{chunk-XRYZRW54.js → chunk-WDXD6ITO.js} +2 -2
  143. package/dist/{chunk-4KYOLI6M.js → chunk-XGM3VQWG.js} +120 -14
  144. package/dist/chunk-XGM3VQWG.js.map +1 -0
  145. package/dist/{chunk-MN4KB2A4.js → chunk-YDKF4MSJ.js} +3 -3
  146. package/dist/{chunk-YLDXWCZP.js → chunk-YHGCT462.js} +14 -9
  147. package/dist/chunk-YHGCT462.js.map +1 -0
  148. package/dist/{chunk-7YQ4IYS2.js → chunk-YOXVZJFM.js} +2 -2
  149. package/dist/{chunk-ZWXJBFZU.js → chunk-YZJM6CLF.js} +8 -8
  150. package/dist/chunk-ZCUTSMR2.js +61 -0
  151. package/dist/chunk-ZCUTSMR2.js.map +1 -0
  152. package/dist/{chunk-LUNJ3WFO.js → chunk-ZK4BFABK.js} +4 -4
  153. package/dist/{chunk-V3MXUL3D.js → chunk-ZPOHEB5Z.js} +329 -653
  154. package/dist/chunk-ZPOHEB5Z.js.map +1 -0
  155. package/dist/{chunk-RDFF2NAU.js → chunk-ZXBTTMGZ.js} +184 -88
  156. package/dist/chunk-ZXBTTMGZ.js.map +1 -0
  157. package/dist/{cli-cShQ13XG.d.ts → cli-DO3i14pM.d.ts} +5 -5
  158. package/dist/cli.d.ts +25 -25
  159. package/dist/cli.js +51 -48
  160. package/dist/coding/pre-action-gate.d.ts +2 -60
  161. package/dist/compounding/engine.d.ts +4 -2
  162. package/dist/compounding/engine.js +4 -4
  163. package/dist/compounding/preference-consolidator.d.ts +3 -1
  164. package/dist/compression-optimizer.d.ts +3 -1
  165. package/dist/config.d.ts +3 -1
  166. package/dist/config.js +10 -1
  167. package/dist/connectors/codex-materialize-runner.d.ts +3 -1
  168. package/dist/connectors/codex-materialize-runner.js +8 -5
  169. package/dist/connectors/codex-materialize.d.ts +16 -1
  170. package/dist/connectors/codex-materialize.js +10 -1
  171. package/dist/connectors/index.d.ts +3 -1
  172. package/dist/connectors/index.js +8 -5
  173. package/dist/consolidation-provenance-check.d.ts +4 -2
  174. package/dist/consolidation-undo.d.ts +4 -2
  175. package/dist/contradiction/index.d.ts +10 -270
  176. package/dist/contradiction/index.js +12 -7
  177. package/dist/{contradiction-review-QKJH5DKD.js → contradiction-review-WRVLRWHS.js} +6 -2
  178. package/dist/{contradiction-scan-VOTQRRSX.js → contradiction-scan-AKUWPX5N.js} +5 -3
  179. package/dist/converge-config.d.ts +3 -1
  180. package/dist/convergence-refresh.d.ts +4 -2
  181. package/dist/convergence-refresh.js +6 -6
  182. package/dist/conversation-index/backend.d.ts +3 -1
  183. package/dist/conversation-index/chunker.d.ts +3 -1
  184. package/dist/conversation-index/faiss-adapter.d.ts +3 -1
  185. package/dist/conversation-index/indexer.d.ts +3 -1
  186. package/dist/conversation-index/search.d.ts +3 -1
  187. package/dist/corpus-watermark.d.ts +3 -1
  188. package/dist/corpus-watermark.js +6 -6
  189. package/dist/cross-lingual-recall.d.ts +3 -1
  190. package/dist/day-summary.d.ts +3 -1
  191. package/dist/delinearize.d.ts +3 -1
  192. package/dist/dependency-propagation-config.d.ts +3 -1
  193. package/dist/{dependency-propagation-delivery-CsGg-VwS.d.ts → dependency-propagation-delivery-D23_x-s5.d.ts} +1 -1
  194. package/dist/direct-answer-wiring.d.ts +3 -1
  195. package/dist/direct-answer.d.ts +3 -1
  196. package/dist/embedding-fallback.d.ts +3 -1
  197. package/dist/enrichment/index.d.ts +3 -1
  198. package/dist/entity-origin-fields.d.ts +3 -1
  199. package/dist/entity-retrieval.d.ts +4 -2
  200. package/dist/entity-retrieval.js +4 -4
  201. package/dist/entity-schema.d.ts +3 -1
  202. package/dist/episodic-context.d.ts +3 -1
  203. package/dist/explicit-capture.d.ts +12 -12
  204. package/dist/explicit-capture.js +1 -1
  205. package/dist/external-wiki-access.d.ts +40 -40
  206. package/dist/external-wiki-access.js +22 -20
  207. package/dist/external-wiki-collection-registration.d.ts +3 -1
  208. package/dist/external-wiki-collection.d.ts +3 -1
  209. package/dist/external-wiki-mcp-tools.d.ts +40 -40
  210. package/dist/extraction-error-classification.d.ts +3 -1
  211. package/dist/extraction-faithfulness.d.ts +3 -1
  212. package/dist/extraction-judge-telemetry.d.ts +3 -1
  213. package/dist/extraction-judge-training.d.ts +3 -1
  214. package/dist/extraction-judge.d.ts +3 -1
  215. package/dist/extraction-judge.js +2 -2
  216. package/dist/extraction-liveness.d.ts +3 -1
  217. package/dist/extraction-normalization.d.ts +3 -1
  218. package/dist/extraction-prompt.d.ts +3 -1
  219. package/dist/extraction-source-grounding-rules.d.ts +3 -1
  220. package/dist/extraction-source-grounding.d.ts +3 -1
  221. package/dist/extraction.d.ts +3 -1
  222. package/dist/extraction.js +9 -7
  223. package/dist/fallback-llm.d.ts +3 -1
  224. package/dist/graph-dashboard-diff.d.ts +3 -1
  225. package/dist/graph-dashboard-key.d.ts +3 -1
  226. package/dist/graph-dashboard-parser.d.ts +3 -1
  227. package/dist/graph-edge-reinforcement.d.ts +3 -1
  228. package/dist/graph-path-reconstruction.d.ts +3 -1
  229. package/dist/graph-path-scoring.d.ts +3 -1
  230. package/dist/graph-snapshot.d.ts +3 -1
  231. package/dist/graph.d.ts +3 -1
  232. package/dist/harmonic-retrieval.js +1 -1
  233. package/dist/importance.d.ts +3 -1
  234. package/dist/importers/index.d.ts +3 -1
  235. package/dist/in-flight-reads.d.ts +3 -1
  236. package/dist/index--QhGIXF2.d.ts +284 -0
  237. package/dist/index.d.ts +314 -45
  238. package/dist/index.js +163 -88
  239. package/dist/intent.d.ts +3 -1
  240. package/dist/lcm/engine.d.ts +3 -1
  241. package/dist/lcm/index.d.ts +3 -1
  242. package/dist/lcm/tools.d.ts +3 -1
  243. package/dist/lifecycle.d.ts +3 -1
  244. package/dist/live-connectors-runner.d.ts +3 -1
  245. package/dist/local-llm.d.ts +3 -1
  246. package/dist/local-model-endpoint.d.ts +3 -1
  247. package/dist/maintenance/memory-governance.d.ts +3 -1
  248. package/dist/maintenance/memory-governance.js +4 -4
  249. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +4 -2
  250. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +4 -4
  251. package/dist/maintenance/rebuild-memory-projection.d.ts +4 -2
  252. package/dist/maintenance/rebuild-memory-projection.js +5 -5
  253. package/dist/{maintenance-jhMpeGne.d.ts → maintenance-PFvY1Pw_.d.ts} +3 -3
  254. package/dist/mcp-memory-inspector-app.d.ts +37 -37
  255. package/dist/memory-action-policy.d.ts +3 -1
  256. package/dist/memory-cache.d.ts +3 -1
  257. package/dist/memory-lifecycle-ledger-utils.d.ts +3 -1
  258. package/dist/memory-projection-store.d.ts +3 -1
  259. package/dist/memory-provenance.d.ts +3 -1
  260. package/dist/memory-snapshot.d.ts +3 -1
  261. package/dist/memory-subject-cli.d.ts +40 -40
  262. package/dist/memory-subject.d.ts +42 -42
  263. package/dist/memory-worth-outcomes.d.ts +4 -2
  264. package/dist/models-json.d.ts +3 -1
  265. package/dist/namespaces/migrate.d.ts +5 -3
  266. package/dist/namespaces/migrate.js +5 -5
  267. package/dist/namespaces/principal.d.ts +3 -1
  268. package/dist/namespaces/search.d.ts +3 -1
  269. package/dist/namespaces/storage.d.ts +5 -3
  270. package/dist/namespaces/storage.js +4 -4
  271. package/dist/native-knowledge.d.ts +3 -1
  272. package/dist/offline-sync-impression-drain.d.ts +3 -1
  273. package/dist/operator-doctor-corpus.d.ts +3 -1
  274. package/dist/operator-doctor-corpus.js +7 -7
  275. package/dist/operator-doctor-replica.d.ts +3 -1
  276. package/dist/operator-toolkit.d.ts +5 -3
  277. package/dist/operator-toolkit.js +19 -13
  278. package/dist/orchestration/compression-guideline-coordinator.d.ts +4 -2
  279. package/dist/orchestration/maintenance.d.ts +6 -4
  280. package/dist/orchestration/maintenance.js +10 -10
  281. package/dist/{orchestrator-DyGUC7re.d.ts → orchestrator-4wzJrPVm.d.ts} +23 -9
  282. package/dist/orchestrator.d.ts +12 -12
  283. package/dist/orchestrator.js +62 -60
  284. package/dist/patterns-cli.d.ts +3 -1
  285. package/dist/{pipeline-C25Oxtp1.d.ts → pipeline-CgXgdIrF.d.ts} +1 -1
  286. package/dist/policy-runtime.d.ts +3 -1
  287. package/dist/proactive-contention.d.ts +3 -1
  288. package/dist/provenance.d.ts +3 -1
  289. package/dist/{public-http-CMe7NQzj.d.ts → public-http-DhIXYBYI.d.ts} +1 -1
  290. package/dist/{qmd-DkDVCbgF.d.ts → qmd-BppGGxsi.d.ts} +1 -1
  291. package/dist/qmd-preflight.d.ts +4 -2
  292. package/dist/qmd-recall-cache.d.ts +3 -1
  293. package/dist/qmd.d.ts +4 -2
  294. package/dist/recall-concurrency-config.d.ts +3 -1
  295. package/dist/recall-disclosure-escalation.d.ts +3 -1
  296. package/dist/recall-explain-renderer.d.ts +3 -1
  297. package/dist/recall-explain-renderer.js +3 -3
  298. package/dist/recall-memory-map.d.ts +3 -1
  299. package/dist/recall-planner-llm.d.ts +3 -1
  300. package/dist/recall-state.d.ts +3 -1
  301. package/dist/recall-tag-filter.d.ts +3 -1
  302. package/dist/recall-timings.d.ts +3 -1
  303. package/dist/recall-xray-cli.d.ts +3 -1
  304. package/dist/recall-xray-cli.js +4 -4
  305. package/dist/recall-xray-renderer.d.ts +3 -1
  306. package/dist/recall-xray-renderer.js +3 -3
  307. package/dist/recall-xray.d.ts +3 -1
  308. package/dist/recall-xray.js +2 -2
  309. package/dist/reconcile/cursor.d.ts +3 -1
  310. package/dist/reconcile/manifest.d.ts +3 -1
  311. package/dist/reconcile/manifest.js +2 -2
  312. package/dist/reconcile/plan.d.ts +3 -1
  313. package/dist/replay/normalizers/chatgpt.d.ts +3 -1
  314. package/dist/replay/normalizers/claude.d.ts +3 -1
  315. package/dist/replay/normalizers/openclaw.d.ts +3 -1
  316. package/dist/replay/normalizers/shared.d.ts +3 -1
  317. package/dist/replay/runner.d.ts +3 -1
  318. package/dist/replay/types.d.ts +3 -1
  319. package/dist/replica-divergence.d.ts +3 -1
  320. package/dist/replica-peers-config.d.ts +3 -1
  321. package/dist/{resolution-MFY72STR.js → resolution-4552BNRV.js} +14 -4
  322. package/dist/resolve-auth-token.d.ts +3 -1
  323. package/dist/resume-bundles.js +8 -2
  324. package/dist/retrieval-agents.d.ts +4 -2
  325. package/dist/retrieval-tiers.d.ts +3 -1
  326. package/dist/routing/engine.d.ts +3 -1
  327. package/dist/routing/store.d.ts +3 -1
  328. package/dist/salvage-envelope.d.ts +3 -1
  329. package/dist/salvage-envelope.js +1 -1
  330. package/dist/schemas.d.ts +44 -44
  331. package/dist/{scope-profiles-B9xMoFO-.d.ts → scope-profiles-ChZUtxDU.d.ts} +1 -1
  332. package/dist/search/embed-helper.d.ts +3 -1
  333. package/dist/search/factory.d.ts +3 -1
  334. package/dist/search/index.d.ts +3 -1
  335. package/dist/search/lancedb-backend.d.ts +3 -1
  336. package/dist/search/meilisearch-backend.d.ts +3 -1
  337. package/dist/search/noop-backend.d.ts +3 -1
  338. package/dist/search/orama-backend.d.ts +3 -1
  339. package/dist/search/port.d.ts +3 -1
  340. package/dist/search/remote-backend.d.ts +3 -1
  341. package/dist/{semantic-TddhF0y7.d.ts → semantic-BalR6EXU.d.ts} +1 -1
  342. package/dist/{semantic-consolidation-C4uykW84.d.ts → semantic-consolidation-mSPwQSmF.d.ts} +1 -1
  343. package/dist/semantic-consolidation.d.ts +4 -2
  344. package/dist/semantic-consolidation.js +9 -6
  345. package/dist/semantic-rule-promotion.js +4 -4
  346. package/dist/semantic-rule-verifier.d.ts +3 -1
  347. package/dist/semantic-rule-verifier.js +4 -4
  348. package/dist/{service-DCZDZNcV.d.ts → service-BICWLwSP.d.ts} +2 -2
  349. package/dist/session-observer-bands.d.ts +3 -1
  350. package/dist/session-observer-state.d.ts +3 -1
  351. package/dist/shared-context/manager.d.ts +3 -1
  352. package/dist/signal.d.ts +3 -1
  353. package/dist/skills-registry.js +4 -56
  354. package/dist/skills-registry.js.map +1 -1
  355. package/dist/source-agent-qualifier.d.ts +3 -1
  356. package/dist/source-agent-qualifier.js +8 -5
  357. package/dist/{storage-CcKmEjL8.d.ts → storage-B7urx1K3.d.ts} +1 -1
  358. package/dist/storage.d.ts +4 -2
  359. package/dist/storage.js +6 -6
  360. package/dist/subject-config.d.ts +3 -1
  361. package/dist/summarizer.d.ts +3 -1
  362. package/dist/summary-snapshot.d.ts +3 -1
  363. package/dist/support-passport/index.d.ts +43 -43
  364. package/dist/support-passport/index.js +24 -22
  365. package/dist/temporal-supersession.d.ts +4 -2
  366. package/dist/temporal-timeline-recall.d.ts +3 -1
  367. package/dist/temporal-validity.d.ts +3 -1
  368. package/dist/threading.d.ts +3 -1
  369. package/dist/tier-migration.d.ts +4 -2
  370. package/dist/tier-routing.d.ts +3 -1
  371. package/dist/topics.d.ts +3 -1
  372. package/dist/transcript.d.ts +3 -1
  373. package/dist/transfer/types.d.ts +20 -20
  374. package/dist/trust-score-stage.d.ts +3 -1
  375. package/dist/trust-score.d.ts +3 -1
  376. package/dist/{types-Pi0lfaEt.d.ts → types-ETU5N6nB.d.ts} +433 -7
  377. package/dist/types.d.ts +3 -1
  378. package/dist/types.js +1 -1
  379. package/dist/utility-runtime.d.ts +3 -1
  380. package/dist/verified-recall.js +4 -4
  381. package/dist/who-knows-cli.d.ts +40 -40
  382. package/dist/who-knows-cli.js +5 -5
  383. package/dist/who-knows.d.ts +42 -42
  384. package/dist/who-knows.js +4 -4
  385. package/dist/write-envelope.d.ts +3 -1
  386. package/dist/write-envelope.js +1 -1
  387. package/package.json +2 -2
  388. package/src/access-boundary.ts +4 -0
  389. package/src/access-http.ts +6 -5
  390. package/src/access-mcp-admin-tools.ts +24 -0
  391. package/src/access-mcp-output-schemas.ts +14 -0
  392. package/src/access-mcp.ts +2 -2
  393. package/src/access-operations-batch.ts +5 -0
  394. package/src/access-service.ts +27 -0
  395. package/src/access-surface-catalog.test.ts +24 -0
  396. package/src/access-surface-catalog.ts +4 -0
  397. package/src/cli/skills-commands.ts +150 -0
  398. package/src/cli.ts +4 -2
  399. package/src/coding/action-gate.test.ts +341 -0
  400. package/src/coding/action-gate.ts +556 -0
  401. package/src/config.ts +9 -2
  402. package/src/connectors/codex-materialize-runner.ts +16 -0
  403. package/src/connectors/codex-materialize-skills.test.ts +141 -0
  404. package/src/connectors/codex-materialize.ts +58 -40
  405. package/src/connectors/materialize-paths.ts +50 -0
  406. package/src/connectors/materialize-skills.ts +127 -0
  407. package/src/contradiction/contradiction-review.ts +50 -4
  408. package/src/contradiction/contradiction-scan.ts +14 -3
  409. package/src/contradiction/resolution.ts +50 -2
  410. package/src/index.ts +9 -13
  411. package/src/orchestration/recall-rerank-coordinator.ts +123 -4
  412. package/src/orchestration/recall-result-formatter.ts +6 -2
  413. package/src/orchestration/recall-search-pipeline.ts +14 -1
  414. package/src/preferences/drift-config.ts +118 -0
  415. package/src/preferences/drift-recall.ts +133 -0
  416. package/src/preferences/drift-types.ts +87 -0
  417. package/src/preferences/index.ts +12 -0
  418. package/src/preferences/preference-drift.test.ts +690 -0
  419. package/src/preferences/preference-drift.ts +724 -0
  420. package/src/procedural/skill-io.test.ts +190 -0
  421. package/src/procedural/skill-io.ts +220 -0
  422. package/src/procedural/skill-projection.test.ts +214 -0
  423. package/src/procedural/skill-projection.ts +356 -0
  424. package/src/review/review-deck-access.test.ts +325 -0
  425. package/src/review/review-deck-http-base.ts +133 -0
  426. package/src/review/review-deck-mutation.test.ts +417 -0
  427. package/src/review/review-deck-mutation.ts +677 -0
  428. package/src/review/review-deck-snapshot.ts +196 -0
  429. package/src/review/review-deck-surface.ts +117 -0
  430. package/src/review/review-deck.test.ts +347 -0
  431. package/src/review/review-deck.ts +311 -0
  432. package/src/storage.ts +4 -6
  433. package/src/types.ts +9 -6
  434. package/dist/chunk-35NN3ZFA.js.map +0 -1
  435. package/dist/chunk-4KYOLI6M.js.map +0 -1
  436. package/dist/chunk-BWLRUMOG.js.map +0 -1
  437. package/dist/chunk-J275IYMG.js.map +0 -1
  438. package/dist/chunk-LGO6A7GJ.js.map +0 -1
  439. package/dist/chunk-QOS5LBZN.js.map +0 -1
  440. package/dist/chunk-RDFF2NAU.js.map +0 -1
  441. package/dist/chunk-SB7D4BT7.js.map +0 -1
  442. package/dist/chunk-SBDCZ2AX.js.map +0 -1
  443. package/dist/chunk-TF77C7SV.js.map +0 -1
  444. package/dist/chunk-TZNQUNKL.js.map +0 -1
  445. package/dist/chunk-V3MXUL3D.js.map +0 -1
  446. package/dist/chunk-XCTXS7VY.js +0 -402
  447. package/dist/chunk-XCTXS7VY.js.map +0 -1
  448. package/dist/chunk-YLDXWCZP.js.map +0 -1
  449. /package/dist/{auto-sync-H64ZCNIR.js.map → auto-sync-XVMLL2RH.js.map} +0 -0
  450. /package/dist/{chunk-YB42WZCY.js.map → chunk-2IXQSGCU.js.map} +0 -0
  451. /package/dist/{chunk-PE255F4T.js.map → chunk-2MVTAIL3.js.map} +0 -0
  452. /package/dist/{chunk-GDFVPUJ5.js.map → chunk-3NH3VP3U.js.map} +0 -0
  453. /package/dist/{chunk-GNCCUR6K.js.map → chunk-AXGFOFNY.js.map} +0 -0
  454. /package/dist/{chunk-5YQ63T4B.js.map → chunk-BK5G2MHO.js.map} +0 -0
  455. /package/dist/{chunk-LZH5FR2W.js.map → chunk-CQBIN77D.js.map} +0 -0
  456. /package/dist/{chunk-NKKD4ZAU.js.map → chunk-DORFF5N5.js.map} +0 -0
  457. /package/dist/{chunk-SQI57UCJ.js.map → chunk-DUEDOYZD.js.map} +0 -0
  458. /package/dist/{chunk-5NM4OH4P.js.map → chunk-DUZARALI.js.map} +0 -0
  459. /package/dist/{chunk-2E36UXVW.js.map → chunk-ECLJ4LA2.js.map} +0 -0
  460. /package/dist/{chunk-IID2CMUU.js.map → chunk-GHD2LLG4.js.map} +0 -0
  461. /package/dist/{chunk-ZQHI2BZB.js.map → chunk-HF5BUTI6.js.map} +0 -0
  462. /package/dist/{chunk-3DVBKTSO.js.map → chunk-HSZMX3ZJ.js.map} +0 -0
  463. /package/dist/{chunk-S2DPMJXH.js.map → chunk-I23ZHYSL.js.map} +0 -0
  464. /package/dist/{chunk-ODZG724P.js.map → chunk-I2HTKOOP.js.map} +0 -0
  465. /package/dist/{chunk-NTWN6HB2.js.map → chunk-IURMJBGP.js.map} +0 -0
  466. /package/dist/{chunk-OCZIYAE5.js.map → chunk-IWKGOCL6.js.map} +0 -0
  467. /package/dist/{chunk-UXO5IMBK.js.map → chunk-J3ATBB7M.js.map} +0 -0
  468. /package/dist/{chunk-Y7DK7HHJ.js.map → chunk-JPAKBNTM.js.map} +0 -0
  469. /package/dist/{chunk-SPUJNJJC.js.map → chunk-KFIOPZ25.js.map} +0 -0
  470. /package/dist/{chunk-JYYBA7TF.js.map → chunk-KOO37E4Y.js.map} +0 -0
  471. /package/dist/{chunk-OTHZWLUD.js.map → chunk-KPB2QHJZ.js.map} +0 -0
  472. /package/dist/{chunk-CT56C22C.js.map → chunk-LYBIHM4N.js.map} +0 -0
  473. /package/dist/{chunk-3I7ASZN3.js.map → chunk-MFOSZUIT.js.map} +0 -0
  474. /package/dist/{chunk-DZUJ46DO.js.map → chunk-NLEH4RTB.js.map} +0 -0
  475. /package/dist/{chunk-ZO6AXLEH.js.map → chunk-OCCHUEZB.js.map} +0 -0
  476. /package/dist/{chunk-EILZG5VC.js.map → chunk-OU34IQXV.js.map} +0 -0
  477. /package/dist/{chunk-2XDWWPTN.js.map → chunk-OZDFB22S.js.map} +0 -0
  478. /package/dist/{chunk-UIN2BWDD.js.map → chunk-PTZQYCJ4.js.map} +0 -0
  479. /package/dist/{chunk-Z7PBQPJ4.js.map → chunk-QJW4MZSW.js.map} +0 -0
  480. /package/dist/{chunk-R7JAM2XF.js.map → chunk-R2MZCYA6.js.map} +0 -0
  481. /package/dist/{chunk-LBWQ65SX.js.map → chunk-T42L3S6A.js.map} +0 -0
  482. /package/dist/{chunk-2YI72KM3.js.map → chunk-UCKG36HO.js.map} +0 -0
  483. /package/dist/{chunk-SIHSCCUQ.js.map → chunk-UFR6HX7A.js.map} +0 -0
  484. /package/dist/{chunk-CDUUDBWJ.js.map → chunk-VFYRYFLL.js.map} +0 -0
  485. /package/dist/{chunk-XRYZRW54.js.map → chunk-WDXD6ITO.js.map} +0 -0
  486. /package/dist/{chunk-MN4KB2A4.js.map → chunk-YDKF4MSJ.js.map} +0 -0
  487. /package/dist/{chunk-7YQ4IYS2.js.map → chunk-YOXVZJFM.js.map} +0 -0
  488. /package/dist/{chunk-ZWXJBFZU.js.map → chunk-YZJM6CLF.js.map} +0 -0
  489. /package/dist/{chunk-LUNJ3WFO.js.map → chunk-ZK4BFABK.js.map} +0 -0
  490. /package/dist/{contradiction-review-QKJH5DKD.js.map → contradiction-review-WRVLRWHS.js.map} +0 -0
  491. /package/dist/{contradiction-scan-VOTQRRSX.js.map → contradiction-scan-AKUWPX5N.js.map} +0 -0
  492. /package/dist/{resolution-MFY72STR.js.map → resolution-4552BNRV.js.map} +0 -0
@@ -0,0 +1,556 @@
1
+ /**
2
+ * Action-site failure gate (issue #2382, slice 1 — core contract).
3
+ *
4
+ * The H6 study (#1963) measured that a failure memory delivered in the prompt
5
+ * preamble barely changes behaviour, while the same memory delivered at the
6
+ * moment the agent proposes the matched action removes the repeated failure.
7
+ * This module productionises that delivery point: `ActionGateService` wraps the
8
+ * experimental `PreActionFailureGate` primitive, adds failure-class memory
9
+ * candidates, a per-turn budget, cross-channel suppression, and telemetry.
10
+ *
11
+ * Scope, per the study's honest limit: the gate removes a known failure mode.
12
+ * It does not improve task completion. It is advisory only — it never blocks an
13
+ * action, never outruns its deadline, and fails open on every error path.
14
+ */
15
+ import type { ActionIntent, ActionStrategyId } from "../causal-trajectory.js";
16
+ import { coerceBool, coerceNumber } from "../connectors/coerce.js";
17
+ import type { CodingContext, MemoryFile } from "../types.js";
18
+ import {
19
+ PRE_ACTION_GATE_DEFAULT_TIMEOUT_MS,
20
+ type PreActionFailureGate,
21
+ normalizeActionIntent,
22
+ sanitizePayloadString,
23
+ } from "./pre-action-gate.js";
24
+
25
+ export const ACTION_GATE_DEFAULT_MAX_ADVISORIES_PER_TURN = 3;
26
+ /** Bound on a single advisory payload, above the primitive's citation bound. */
27
+ const MAX_ADVISORY_CHARS = 400;
28
+ /** Bounded lexical matching: terms considered from one proposed action. */
29
+ const MAX_ACTION_TERMS = 24;
30
+ const MIN_TERM_CHARS = 3;
31
+ /** Fraction of action terms a failure memory must mention to be a candidate. */
32
+ const MIN_TERM_OVERLAP_RATIO = 0.6;
33
+ /** Sessions tracked for suppression before the oldest is evicted. */
34
+ const MAX_TRACKED_SESSIONS = 200;
35
+ /** Memory ids remembered per session for cross-channel suppression. */
36
+ const MAX_TRACKED_IDS_PER_SESSION = 200;
37
+
38
+ export interface ActionGateConfig {
39
+ /**
40
+ * Master gate. Default `false`: when disabled no lookup, no matching, and no
41
+ * suppression bookkeeping runs on any path.
42
+ */
43
+ enabled: boolean;
44
+ /** Hard latency cap for a whole gate evaluation. Overrun fails open. */
45
+ timeoutMs: number;
46
+ /** Advisories injected per turn. `0` disables injection and all lookups. */
47
+ maxAdvisoriesPerTurn: number;
48
+ }
49
+
50
+ export const ACTION_GATE_DEFAULTS: ActionGateConfig = {
51
+ enabled: false,
52
+ timeoutMs: PRE_ACTION_GATE_DEFAULT_TIMEOUT_MS,
53
+ maxAdvisoriesPerTurn: ACTION_GATE_DEFAULT_MAX_ADVISORIES_PER_TURN,
54
+ };
55
+
56
+ export function parseActionGateConfig(raw: unknown): ActionGateConfig {
57
+ if (raw !== undefined && (raw === null || typeof raw !== "object" || Array.isArray(raw))) {
58
+ throw new Error(
59
+ `actionGate must be an object (got ${JSON.stringify(raw)}). Use actionGate: { enabled: true } to opt in.`
60
+ );
61
+ }
62
+ const block = (raw ?? {}) as Record<string, unknown>;
63
+ const rawEnabled = block.enabled;
64
+ let enabled = ACTION_GATE_DEFAULTS.enabled;
65
+ if (rawEnabled !== undefined) {
66
+ const coerced = coerceBool(rawEnabled);
67
+ if (coerced === undefined) {
68
+ throw new Error(
69
+ `actionGate.enabled must be a boolean or one of "true"/"false"/"1"/"0"/"yes"/"no"/"on"/"off" (got ${JSON.stringify(rawEnabled)}).`
70
+ );
71
+ }
72
+ enabled = coerced;
73
+ }
74
+ const rawTimeout = coerceNumber(block.timeoutMs);
75
+ const timeoutMs =
76
+ rawTimeout !== undefined && Number.isFinite(rawTimeout)
77
+ ? Math.min(5000, Math.max(1, Math.floor(rawTimeout)))
78
+ : ACTION_GATE_DEFAULTS.timeoutMs;
79
+ const rawMax = coerceNumber(block.maxAdvisoriesPerTurn);
80
+ // Zero-limit semantics are a compatibility contract: `0` stays `0`.
81
+ const maxAdvisoriesPerTurn =
82
+ rawMax !== undefined && Number.isFinite(rawMax)
83
+ ? Math.min(20, Math.max(0, Math.floor(rawMax)))
84
+ : ACTION_GATE_DEFAULTS.maxAdvisoriesPerTurn;
85
+ return { enabled, timeoutMs, maxAdvisoriesPerTurn };
86
+ }
87
+
88
+ export type ActionGateStatus = "DISABLED" | "NO_MATCH" | "MATCH_WARN" | "ERROR_FAIL_OPEN";
89
+
90
+ export interface ActionGateRequest {
91
+ sessionKey: string;
92
+ /** Turn identity: the per-turn budget and dedupe reset when this changes. */
93
+ turnId: string;
94
+ strategyId: ActionStrategyId;
95
+ intent: ActionIntent;
96
+ codingContext: CodingContext;
97
+ /** Memory directory ALREADY resolved for the caller's readable namespace. */
98
+ memoryDir: string;
99
+ /** Resolved readable namespace, passed verbatim to candidate sources. */
100
+ namespace?: string;
101
+ causalTrajectoryStoreDir?: string;
102
+ signal?: AbortSignal;
103
+ }
104
+
105
+ export interface ActionGateAdvisory {
106
+ /** Trajectory id or memory id — the unit of dedupe and suppression. */
107
+ memoryId: string;
108
+ sourceId: string;
109
+ text: string;
110
+ }
111
+
112
+ export interface ActionGateDecision {
113
+ status: ActionGateStatus;
114
+ advisories: ActionGateAdvisory[];
115
+ /** Candidates withheld: already delivered this turn/session, or over budget. */
116
+ suppressedIds: string[];
117
+ /** Source failures, kept distinct from "no candidates" (rule 22). */
118
+ degradations: string[];
119
+ fingerprint?: string;
120
+ reason?: string;
121
+ latencyMs: number;
122
+ }
123
+
124
+ export interface ActionGateCandidate {
125
+ memoryId: string;
126
+ advisoryText: string;
127
+ /** Deterministic ranking key; higher wins, ties break on `memoryId`. */
128
+ score?: number;
129
+ }
130
+
131
+ export interface ActionGateCandidateQuery {
132
+ sessionKey: string;
133
+ fingerprint: string;
134
+ /** Normalized, deduplicated lexical terms describing the proposed action. */
135
+ actionTerms: string[];
136
+ strategyId: ActionStrategyId;
137
+ intent: ActionIntent;
138
+ codingContext: CodingContext;
139
+ memoryDir: string;
140
+ namespace?: string;
141
+ causalTrajectoryStoreDir?: string;
142
+ signal?: AbortSignal;
143
+ }
144
+
145
+ export type ActionGateSourceResult = { ok: true; candidates: ActionGateCandidate[] } | { ok: false; reason: string };
146
+
147
+ export interface ActionGateCandidateSource {
148
+ readonly id: string;
149
+ find(query: ActionGateCandidateQuery): Promise<ActionGateSourceResult>;
150
+ }
151
+
152
+ export interface ActionGateAuditRecord {
153
+ ts: string;
154
+ sessionKey: string;
155
+ turnId: string;
156
+ status: ActionGateStatus;
157
+ latencyMs: number;
158
+ fingerprint?: string;
159
+ deliveredIds: string[];
160
+ suppressedIds: string[];
161
+ degradations: string[];
162
+ reason?: string;
163
+ }
164
+
165
+ export type ActionGateAuditSink = (record: ActionGateAuditRecord) => void | Promise<void>;
166
+
167
+ export interface ActionGateServiceDependencies {
168
+ sources?: ActionGateCandidateSource[];
169
+ audit?: ActionGateAuditSink;
170
+ clock?: () => number;
171
+ now?: () => Date;
172
+ }
173
+
174
+ /**
175
+ * Deterministic, local term extraction from a proposed action. No LLM and no
176
+ * I/O: this runs in the hot path ahead of the tool call.
177
+ */
178
+ export function actionTermsFor(intent: ActionIntent): string[] {
179
+ const raw =
180
+ intent.kind === "command"
181
+ ? [intent.command, ...(intent.args ?? [])]
182
+ : [intent.filePath, intent.editKind, intent.symbol ?? "", intent.range ?? ""];
183
+ const terms: string[] = [];
184
+ const seen = new Set<string>();
185
+ for (const piece of raw) {
186
+ for (const token of sanitizePayloadString(piece ?? "")
187
+ .toLowerCase()
188
+ .split(/[^a-z0-9._-]+/)) {
189
+ const term = token.replace(/^[._-]+|[._-]+$/g, "");
190
+ if (term.length < MIN_TERM_CHARS || seen.has(term)) continue;
191
+ seen.add(term);
192
+ terms.push(term);
193
+ if (terms.length >= MAX_ACTION_TERMS) return terms;
194
+ }
195
+ }
196
+ return terms;
197
+ }
198
+
199
+ /**
200
+ * Failure-class markers on stored memories, read from frontmatter only so the
201
+ * decision stays deterministic: explicit corrections, procedures flagged for
202
+ * repair by library maintenance, and memories whose recorded outcomes are
203
+ * failure-dominant.
204
+ */
205
+ export function isFailureClassMemory(memory: MemoryFile): boolean {
206
+ const fm = memory.frontmatter;
207
+ if (fm.status !== undefined && fm.status !== "active") return false;
208
+ if (fm.category === "correction") return true;
209
+ if (fm.structuredAttributes?.needsRepair === "true") return true;
210
+ const failures = typeof fm.mw_fail === "number" ? fm.mw_fail : 0;
211
+ const successes = typeof fm.mw_success === "number" ? fm.mw_success : 0;
212
+ return failures > 0 && failures > successes;
213
+ }
214
+
215
+ export interface FailureMemorySourceDependencies {
216
+ /**
217
+ * Namespace-scoped listing of candidate memories. Callers wire this to a
218
+ * storage read for the SAME namespace the gate request resolved, so a
219
+ * principal can never receive another principal's advisories.
220
+ */
221
+ listMemories: (options: {
222
+ namespace?: string;
223
+ memoryDir: string;
224
+ signal?: AbortSignal;
225
+ }) => Promise<MemoryFile[]>;
226
+ }
227
+
228
+ /**
229
+ * Failure-class memory candidates, matched by bounded lexical overlap against
230
+ * the proposed action's terms. Deterministic and local by construction.
231
+ */
232
+ export function createFailureMemoryCandidateSource(deps: FailureMemorySourceDependencies): ActionGateCandidateSource {
233
+ return {
234
+ id: "failure-memory",
235
+ async find(query) {
236
+ if (query.actionTerms.length === 0) return { ok: true, candidates: [] };
237
+ let memories: MemoryFile[];
238
+ try {
239
+ memories = await deps.listMemories({
240
+ namespace: query.namespace,
241
+ memoryDir: query.memoryDir,
242
+ signal: query.signal,
243
+ });
244
+ } catch (error) {
245
+ return { ok: false, reason: error instanceof Error ? error.message : String(error) };
246
+ }
247
+ const required = Math.max(1, Math.ceil(query.actionTerms.length * MIN_TERM_OVERLAP_RATIO));
248
+ const candidates: ActionGateCandidate[] = [];
249
+ for (const memory of memories) {
250
+ if (!isFailureClassMemory(memory)) continue;
251
+ const haystack = `${memory.content} ${(memory.frontmatter.tags ?? []).join(" ")}`.toLowerCase();
252
+ let hits = 0;
253
+ for (const term of query.actionTerms) if (haystack.includes(term)) hits += 1;
254
+ if (hits < required) continue;
255
+ candidates.push({
256
+ memoryId: memory.frontmatter.id,
257
+ score: hits,
258
+ advisoryText: `[ActionGate] A stored failure memory matches this action: "${memory.content}".`,
259
+ });
260
+ }
261
+ candidates.sort((left, right) => {
262
+ const byScore = (right.score ?? 0) - (left.score ?? 0);
263
+ return byScore !== 0 ? byScore : left.memoryId.localeCompare(right.memoryId);
264
+ });
265
+ return { ok: true, candidates };
266
+ },
267
+ };
268
+ }
269
+
270
+ /**
271
+ * Candidate source over recorded causal-trajectory failures, delegating the
272
+ * fingerprint match to the existing `PreActionFailureGate` primitive.
273
+ */
274
+ export function createTrajectoryCandidateSource(gate: PreActionFailureGate): ActionGateCandidateSource {
275
+ return {
276
+ id: "causal-trajectory",
277
+ async find(query) {
278
+ const result = await gate.evaluate({
279
+ sessionKey: query.sessionKey,
280
+ strategyId: query.strategyId,
281
+ intent: query.intent,
282
+ codingContext: query.codingContext,
283
+ memoryDir: query.memoryDir,
284
+ causalTrajectoryStoreDir: query.causalTrajectoryStoreDir,
285
+ signal: query.signal,
286
+ });
287
+ if (result.status === "ERROR_FAIL_OPEN") {
288
+ return { ok: false, reason: result.reason ?? "pre-action gate failed open" };
289
+ }
290
+ if (result.status !== "MATCH_WARN" || !result.matchedTrajectoryId || !result.advisoryText) {
291
+ return { ok: true, candidates: [] };
292
+ }
293
+ return {
294
+ ok: true,
295
+ candidates: [
296
+ {
297
+ memoryId: result.matchedTrajectoryId,
298
+ // Trajectory matches are exact fingerprint hits: rank above lexical ones.
299
+ score: Number.MAX_SAFE_INTEGER,
300
+ advisoryText: result.advisoryText,
301
+ },
302
+ ],
303
+ };
304
+ },
305
+ };
306
+ }
307
+
308
+ interface SessionSuppression {
309
+ turnId: string;
310
+ /** Ids the gate delivered during `turnId`. */
311
+ deliveredThisTurn: Set<string>;
312
+ /** Ids the gate delivered anywhere in the session; turn-start must skip them. */
313
+ deliveredByGate: Set<string>;
314
+ /** Ids turn-start injection already delivered; the gate must skip them. */
315
+ deliveredByTurnStart: Set<string>;
316
+ }
317
+
318
+ /**
319
+ * Advisory gate evaluated immediately before an agent action.
320
+ *
321
+ * Delivery is bounded three ways: a hard deadline, `maxAdvisoriesPerTurn`, and
322
+ * dedupe per memory per turn. Cross-channel suppression keeps one memory from
323
+ * arriving twice in a session — once here and once from turn-start recall.
324
+ */
325
+ export class ActionGateService {
326
+ private readonly config: ActionGateConfig;
327
+ private readonly sources: ActionGateCandidateSource[];
328
+ private readonly audit?: ActionGateAuditSink;
329
+ private readonly clock: () => number;
330
+ private readonly now: () => Date;
331
+ private readonly sessions = new Map<string, SessionSuppression>();
332
+
333
+ constructor(config: ActionGateConfig, deps: ActionGateServiceDependencies = {}) {
334
+ this.config = config;
335
+ this.sources = deps.sources ?? [];
336
+ this.audit = deps.audit;
337
+ this.clock = deps.clock ?? Date.now;
338
+ this.now = deps.now ?? (() => new Date());
339
+ }
340
+
341
+ /**
342
+ * Memory ids the gate already delivered in this session. Turn-start recall
343
+ * filters these out before its own cap, honouring the filter-then-cap order.
344
+ */
345
+ public suppressedForTurnStart(sessionKey: string): string[] {
346
+ if (!this.config.enabled) return [];
347
+ return [...(this.sessions.get(sessionKey)?.deliveredByGate ?? [])];
348
+ }
349
+
350
+ /** Record ids turn-start recall injected, so the gate will not repeat them. */
351
+ public noteTurnStartDelivery(sessionKey: string, memoryIds: readonly string[]): void {
352
+ if (!this.config.enabled || memoryIds.length === 0) return;
353
+ const state = this.sessionState(sessionKey, undefined);
354
+ for (const id of memoryIds) this.addTracked(state.deliveredByTurnStart, id);
355
+ }
356
+
357
+ public resetSession(sessionKey: string): void {
358
+ this.sessions.delete(sessionKey);
359
+ }
360
+
361
+ async evaluate(request: ActionGateRequest): Promise<ActionGateDecision> {
362
+ const startedAt = this.clock();
363
+ if (!this.config.enabled) {
364
+ return {
365
+ status: "DISABLED",
366
+ advisories: [],
367
+ suppressedIds: [],
368
+ degradations: [],
369
+ reason: "actionGate.enabled is false",
370
+ latencyMs: 0,
371
+ };
372
+ }
373
+ if (this.config.maxAdvisoriesPerTurn === 0) {
374
+ return this.finish(request, startedAt, {
375
+ status: "DISABLED",
376
+ advisories: [],
377
+ suppressedIds: [],
378
+ degradations: [],
379
+ reason: "actionGate.maxAdvisoriesPerTurn is 0",
380
+ });
381
+ }
382
+
383
+ let fingerprint: string;
384
+ try {
385
+ fingerprint = normalizeActionIntent(request.intent, request.strategyId, request.codingContext).fingerprint;
386
+ } catch (error) {
387
+ return this.finish(request, startedAt, {
388
+ status: "ERROR_FAIL_OPEN",
389
+ advisories: [],
390
+ suppressedIds: [],
391
+ degradations: [],
392
+ reason: error instanceof Error ? error.message : String(error),
393
+ });
394
+ }
395
+
396
+ const deadline = startedAt + this.config.timeoutMs;
397
+ const collected = await this.collect(request, fingerprint, deadline);
398
+ const state = this.sessionState(request.sessionKey, request.turnId);
399
+ const advisories: ActionGateAdvisory[] = [];
400
+ const suppressedIds: string[] = [];
401
+ for (const { sourceId, candidate } of collected.candidates) {
402
+ if (state.deliveredThisTurn.has(candidate.memoryId) || state.deliveredByTurnStart.has(candidate.memoryId)) {
403
+ suppressedIds.push(candidate.memoryId);
404
+ continue;
405
+ }
406
+ if (advisories.length >= this.config.maxAdvisoriesPerTurn) {
407
+ suppressedIds.push(candidate.memoryId);
408
+ continue;
409
+ }
410
+ advisories.push({
411
+ memoryId: candidate.memoryId,
412
+ sourceId,
413
+ text: sanitizePayloadString(candidate.advisoryText).replace(/\s+/g, " ").slice(0, MAX_ADVISORY_CHARS),
414
+ });
415
+ this.addTracked(state.deliveredThisTurn, candidate.memoryId);
416
+ this.addTracked(state.deliveredByGate, candidate.memoryId);
417
+ }
418
+
419
+ const status: ActionGateStatus =
420
+ advisories.length > 0 ? "MATCH_WARN" : collected.degradations.length > 0 ? "ERROR_FAIL_OPEN" : "NO_MATCH";
421
+ return this.finish(request, startedAt, {
422
+ status,
423
+ advisories,
424
+ suppressedIds,
425
+ degradations: collected.degradations,
426
+ fingerprint,
427
+ reason: status === "ERROR_FAIL_OPEN" ? collected.degradations[0] : undefined,
428
+ });
429
+ }
430
+
431
+ private async collect(
432
+ request: ActionGateRequest,
433
+ fingerprint: string,
434
+ deadline: number
435
+ ): Promise<{
436
+ candidates: Array<{ sourceId: string; candidate: ActionGateCandidate }>;
437
+ degradations: string[];
438
+ }> {
439
+ if (this.sources.length === 0) return { candidates: [], degradations: [] };
440
+ const timeoutAbort = new AbortController();
441
+ const signal = request.signal
442
+ ? AbortSignal.any([request.signal, timeoutAbort.signal])
443
+ : timeoutAbort.signal;
444
+ const query: ActionGateCandidateQuery = {
445
+ sessionKey: request.sessionKey,
446
+ fingerprint,
447
+ actionTerms: actionTermsFor(request.intent),
448
+ strategyId: request.strategyId,
449
+ intent: request.intent,
450
+ codingContext: request.codingContext,
451
+ memoryDir: request.memoryDir,
452
+ namespace: request.namespace,
453
+ causalTrajectoryStoreDir: request.causalTrajectoryStoreDir,
454
+ signal,
455
+ };
456
+ const remaining = Math.max(1, deadline - this.clock());
457
+ let onTimeout!: (value: ActionGateSourceResult) => void;
458
+ const timeoutResult = new Promise<ActionGateSourceResult>((resolve) => {
459
+ onTimeout = resolve;
460
+ });
461
+ const timer = setTimeout(() => {
462
+ timeoutAbort.abort();
463
+ onTimeout({ ok: false, reason: `action gate timed out after ${this.config.timeoutMs}ms` });
464
+ }, remaining);
465
+ try {
466
+ const settled = await Promise.all(
467
+ this.sources.map(async (source) => {
468
+ let result: ActionGateSourceResult;
469
+ try {
470
+ result = await Promise.race([source.find(query), timeoutResult]);
471
+ } catch (error) {
472
+ result = { ok: false, reason: error instanceof Error ? error.message : String(error) };
473
+ }
474
+ return { source, result };
475
+ })
476
+ );
477
+ const candidates: Array<{ sourceId: string; candidate: ActionGateCandidate }> = [];
478
+ const degradations: string[] = [];
479
+ for (const { source, result } of settled) {
480
+ if (!result.ok) {
481
+ degradations.push(`${source.id}: ${result.reason}`);
482
+ continue;
483
+ }
484
+ for (const candidate of result.candidates) candidates.push({ sourceId: source.id, candidate });
485
+ }
486
+ candidates.sort((left, right) => {
487
+ const byScore = (right.candidate.score ?? 0) - (left.candidate.score ?? 0);
488
+ if (byScore !== 0) return byScore;
489
+ const bySource = left.sourceId.localeCompare(right.sourceId);
490
+ return bySource !== 0 ? bySource : left.candidate.memoryId.localeCompare(right.candidate.memoryId);
491
+ });
492
+ return { candidates, degradations };
493
+ } finally {
494
+ clearTimeout(timer);
495
+ }
496
+ }
497
+
498
+ private finish(
499
+ request: ActionGateRequest,
500
+ startedAt: number,
501
+ decision: Omit<ActionGateDecision, "latencyMs">
502
+ ): ActionGateDecision {
503
+ const latencyMs = Math.max(0, this.clock() - startedAt);
504
+ const result: ActionGateDecision = { ...decision, latencyMs };
505
+ if (this.audit) {
506
+ const record: ActionGateAuditRecord = {
507
+ ts: this.now().toISOString(),
508
+ sessionKey: request.sessionKey,
509
+ turnId: request.turnId,
510
+ status: result.status,
511
+ latencyMs,
512
+ fingerprint: result.fingerprint,
513
+ deliveredIds: result.advisories.map((advisory) => advisory.memoryId),
514
+ suppressedIds: result.suppressedIds,
515
+ degradations: result.degradations,
516
+ reason: result.reason,
517
+ };
518
+ // Telemetry must never break the action it observes.
519
+ void Promise.resolve()
520
+ .then(() => this.audit?.(record))
521
+ .catch(() => undefined);
522
+ }
523
+ return result;
524
+ }
525
+
526
+ private sessionState(sessionKey: string, turnId: string | undefined): SessionSuppression {
527
+ let state = this.sessions.get(sessionKey);
528
+ if (!state) {
529
+ if (this.sessions.size >= MAX_TRACKED_SESSIONS) {
530
+ const oldest = this.sessions.keys().next().value;
531
+ if (oldest !== undefined) this.sessions.delete(oldest);
532
+ }
533
+ state = {
534
+ turnId: turnId ?? "",
535
+ deliveredThisTurn: new Set(),
536
+ deliveredByGate: new Set(),
537
+ deliveredByTurnStart: new Set(),
538
+ };
539
+ this.sessions.set(sessionKey, state);
540
+ }
541
+ if (turnId !== undefined && state.turnId !== turnId) {
542
+ state.turnId = turnId;
543
+ state.deliveredThisTurn.clear();
544
+ }
545
+ return state;
546
+ }
547
+
548
+ private addTracked(set: Set<string>, value: string): void {
549
+ if (set.has(value)) return;
550
+ if (set.size >= MAX_TRACKED_IDS_PER_SESSION) {
551
+ const oldest = set.values().next().value;
552
+ if (oldest !== undefined) set.delete(oldest);
553
+ }
554
+ set.add(value);
555
+ }
556
+ }
package/src/config.ts CHANGED
@@ -43,6 +43,8 @@ import { parseExtractionLivenessConfig } from "./extraction-liveness.js";
43
43
  import { parseReplicaPeersConfig } from "./replica-peers-config.js";
44
44
  import { parseDependencyPropagationConfig } from "./dependency-propagation-config.js";
45
45
  import { parseProceduralMaintenanceConfig } from "./procedural/maintenance-config.js";
46
+ import { parseSkillProjectionConfig } from "./procedural/skill-projection.js";
47
+ import { parseDriftDetectionConfig } from "./preferences/drift-config.js";
46
48
  import {
47
49
  parseContradictionLocalizationConfig,
48
50
  parseContradictionScanConfig,
@@ -68,6 +70,7 @@ import { parseLocationConfig } from "./location/config.js";
68
70
  import { parseOkfConfig } from "./okf/config.js";
69
71
  import { parseBoundedJsonlStateConfig } from "./bounded-jsonl-state.js";
70
72
  import { parseCodingKnowledgeConfig } from "./coding/coding-knowledge-config.js";
73
+ import { parseActionGateConfig } from "./coding/action-gate.js";
71
74
  import { parseChatConfig } from "./chat/chat-config.js";
72
75
  import { parseSupportPassportConfig } from "./support-passport/config.js";
73
76
  import { parseCorrectionIntentConfig, parseFaithfulnessGateConfig } from "./faithfulness-config.js";
@@ -1126,8 +1129,8 @@ export function parseConfig(
1126
1129
  ? Math.min(10, Math.max(1, Math.floor(recallMaxCoerced)))
1127
1130
  : 2;
1128
1131
  const maintenance = parseProceduralMaintenanceConfig(rawProcedural.maintenance);
1129
- // Default-on procedural memory (issue #567 PR 4/5). Explicit false-ish
1130
- // values stay off. Unknown values throw.
1132
+ const skillProjection = parseSkillProjectionConfig(rawProcedural.skillProjection);
1133
+ // Default-on procedural memory (issue #567 PR 4/5). Explicit false-ish values stay off. Unknown values throw.
1131
1134
  const rawEnabledValue = rawProcedural.enabled;
1132
1135
  let proceduralEnabled: boolean;
1133
1136
  if (rawEnabledValue === undefined) {
@@ -1152,6 +1155,7 @@ export function parseConfig(
1152
1155
  lookbackDays,
1153
1156
  proceduralMiningCronAutoRegister: coerceBool(rawProcedural.proceduralMiningCronAutoRegister) === true,
1154
1157
  recallMaxProcedures,
1158
+ skillProjection,
1155
1159
  };
1156
1160
  const wearables = parseWearablesConfig(cfg.wearables);
1157
1161
  const { activity, meetings, provenance } = parseCaptureCompanionConfigs(cfg);
@@ -1789,6 +1793,8 @@ export function parseConfig(
1789
1793
  contradictionAutoResolve: cfg.contradictionAutoResolve !== false,
1790
1794
  // Contradiction Scan cron (issue #520)
1791
1795
  contradictionScan: parseContradictionScanConfig(cfg.contradictionScan),
1796
+ // Preference drift detection (issue #2371)
1797
+ driftDetection: parseDriftDetectionConfig(cfg.driftDetection),
1792
1798
  dependencyPropagation: parseDependencyPropagationConfig(cfg),
1793
1799
  // Temporal Supersession (issue #375)
1794
1800
  temporalSupersessionEnabled: cfg.temporalSupersessionEnabled !== false, // On by default
@@ -2329,6 +2335,7 @@ export function parseConfig(
2329
2335
  bridgeMode: cfg.bridgeMode === undefined ? "embedded" : String(cfg.bridgeMode),
2330
2336
  codexCompat,
2331
2337
  codingKnowledge: parseCodingKnowledgeConfig(cfg.codingKnowledge),
2338
+ actionGate: parseActionGateConfig(cfg.actionGate),
2332
2339
  chat: parseChatConfig(cfg.chat),
2333
2340
  supportPassport: parseSupportPassportConfig(cfg.supportPassport),
2334
2341
  hourlySummariesEnabled: cfg.hourlySummariesEnabled !== false, // default: true
@@ -14,6 +14,8 @@ import { existsSync } from "node:fs";
14
14
  import { log } from "../logger.js";
15
15
  import { resolveNamespaceChildRoot } from "../namespaces/path.js";
16
16
  import { isSafeRouteNamespace } from "../routing/engine.js";
17
+ import { projectProceduresToSkills } from "../procedural/skill-projection.js";
18
+ import { BUILTIN_SKILLS } from "../skills-registry.js";
17
19
  import { StorageManager } from "../storage.js";
18
20
  import { excludeSupportPassportPrivateMemories } from "../support-passport/card-projection.js";
19
21
  import type { PluginConfig, MemoryFile } from "../types.js";
@@ -109,6 +111,19 @@ export async function runCodexMaterialize(
109
111
  }
110
112
  memories = excludeSupportPassportPrivateMemories(memories);
111
113
 
114
+ // Skill projection (issue #2369). Gated on `procedural.enabled` AND
115
+ // `procedural.skillProjection.enabled`; `maxSkills: 0` disables it too.
116
+ // Passing `undefined` leaves `skills/` untouched, so a disabled gate never
117
+ // deletes a folder the user curated.
118
+ const skillProjection = cfg.procedural?.skillProjection;
119
+ const skills =
120
+ cfg.procedural?.enabled === true && skillProjection?.enabled === true
121
+ ? projectProceduresToSkills(memories, {
122
+ maxSkills: skillProjection.maxSkills,
123
+ reservedSlugs: BUILTIN_SKILLS.map((skill) => skill.slug),
124
+ })
125
+ : undefined;
126
+
112
127
  // Intentionally NOT catching here: per the JSDoc contract above,
113
128
  // schema-validation and I/O errors from `materializeForNamespace` must
114
129
  // surface to callers so they can exit non-zero (CLI) or log + recover
@@ -122,6 +137,7 @@ export async function runCodexMaterialize(
122
137
  maxSummaryTokens: cfg.codexMaterializeMaxSummaryTokens,
123
138
  rolloutRetentionDays: cfg.codexMaterializeRolloutRetentionDays,
124
139
  rolloutSummaries: options.rolloutSummaries,
140
+ skills,
125
141
  now: options.now,
126
142
  });
127
143
  if (options.reason) {