@remnic/core 9.65.1 → 9.65.3

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 (576) hide show
  1. package/dist/access-admin-ops-surface.d.ts +44 -44
  2. package/dist/access-admin-ops-surface.js +36 -35
  3. package/dist/access-authorization-probe.d.ts +39 -40
  4. package/dist/access-authorization-probe.js +37 -36
  5. package/dist/access-boundary.d.ts +41 -185
  6. package/dist/access-boundary.js +36 -35
  7. package/dist/access-cli.js +110 -107
  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 +36 -35
  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 +40 -41
  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 +38 -37
  18. package/dist/access-http.d.ts +51 -44
  19. package/dist/access-http.js +57 -56
  20. package/dist/access-identity-continuity-surface.d.ts +12 -12
  21. package/dist/access-identity-continuity-surface.js +36 -35
  22. package/dist/access-lcm-surface.d.ts +27 -27
  23. package/dist/access-lcm-surface.js +36 -35
  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 +50 -47
  29. package/dist/access-memory-search-fanout.d.ts +4 -2
  30. package/dist/{access-namespace-preflight-BKUnKsBv.d.ts → access-namespace-preflight-B7Usyz-K.d.ts} +1 -1
  31. package/dist/access-namespace-preflight.d.ts +5 -3
  32. package/dist/access-namespace-preflight.js +36 -35
  33. package/dist/access-observe-write-surface.d.ts +39 -39
  34. package/dist/access-observe-write-surface.js +36 -35
  35. package/dist/access-offline-manifest.d.ts +12 -12
  36. package/dist/access-offline-manifest.js +5 -5
  37. package/dist/access-operations-batch.js +41 -40
  38. package/dist/access-operations.d.ts +46 -47
  39. package/dist/access-operations.js +44 -43
  40. package/dist/access-recall-concurrency.d.ts +40 -40
  41. package/dist/access-recall-concurrency.js +36 -35
  42. package/dist/access-recall-response.d.ts +24 -24
  43. package/dist/access-recall-response.js +36 -35
  44. package/dist/access-recall-surface.d.ts +24 -24
  45. package/dist/access-recall-surface.js +36 -35
  46. package/dist/access-schema.d.ts +139 -139
  47. package/dist/access-schema.js +3 -3
  48. package/dist/{access-service-B1Lbb-nQ.d.ts → access-service-DkaIG3n8.d.ts} +688 -140
  49. package/dist/access-service-helpers.d.ts +40 -40
  50. package/dist/access-service.d.ts +47 -47
  51. package/dist/access-service.js +36 -35
  52. package/dist/access-surface-catalog.d.ts +41 -42
  53. package/dist/access-surface-catalog.js +44 -37
  54. package/dist/access-surface-catalog.js.map +1 -1
  55. package/dist/access-wearables-meetings-surface.d.ts +5 -3
  56. package/dist/action-confidence.d.ts +3 -1
  57. package/dist/active-memory-bridge.d.ts +3 -1
  58. package/dist/active-recall.d.ts +3 -1
  59. package/dist/active-recall.js +11 -1
  60. package/dist/active-recall.js.map +1 -1
  61. package/dist/adapters/index.js +4 -4
  62. package/dist/adapters/registry.js +2 -2
  63. package/dist/ambient-provenance.d.ts +3 -1
  64. package/dist/artifact-search.d.ts +3 -1
  65. package/dist/{auto-sync-5L7EUZ27.js → auto-sync-H64ZCNIR.js} +13 -5
  66. package/dist/{auto-sync-5L7EUZ27.js.map → auto-sync-H64ZCNIR.js.map} +1 -1
  67. package/dist/behavior-learner.d.ts +3 -1
  68. package/dist/behavior-signals.d.ts +3 -1
  69. package/dist/bootstrap.d.ts +12 -12
  70. package/dist/briefing-window.d.ts +4 -2
  71. package/dist/briefing.d.ts +4 -2
  72. package/dist/briefing.js +16 -15
  73. package/dist/buffer-surprise-report.d.ts +3 -1
  74. package/dist/buffer-turn-helpers.d.ts +3 -1
  75. package/dist/buffer.d.ts +4 -2
  76. package/dist/buffer.js +4 -4
  77. package/dist/bulk-import/index.d.ts +5 -3
  78. package/dist/calibration.d.ts +3 -1
  79. package/dist/calibration.js +1 -1
  80. package/dist/capabilities.d.ts +3 -1
  81. package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-YO5QJ6L3.js} +2 -2
  82. package/dist/{catalog-DjVhJoRM.d.ts → catalog-CX2BZEJh.d.ts} +1 -1
  83. package/dist/causal-behavior.d.ts +1 -1
  84. package/dist/causal-consolidation.d.ts +3 -1
  85. package/dist/causal-consolidation.js +20 -19
  86. package/dist/causal-consolidation.js.map +1 -1
  87. package/dist/causal-trajectory-graph.d.ts +1 -1
  88. package/dist/{chunk-MIBKEW7A.js → chunk-2VXWFYJE.js} +3 -3
  89. package/dist/{chunk-3YTTAGPB.js → chunk-3DVBKTSO.js} +2 -2
  90. package/dist/{chunk-EIR5VLIH.js → chunk-4K7IW3F7.js} +2 -2
  91. package/dist/chunk-4K7IW3F7.js.map +1 -0
  92. package/dist/{chunk-JTSVMJHV.js → chunk-4XDGYCZI.js} +3 -3
  93. package/dist/chunk-573TEZCD.js +88 -0
  94. package/dist/chunk-573TEZCD.js.map +1 -0
  95. package/dist/{chunk-HQSBYI5X.js → chunk-57HVIG5U.js} +2 -2
  96. package/dist/{chunk-PMVPCZJZ.js → chunk-6433HV72.js} +2 -2
  97. package/dist/{chunk-N6TRHP72.js → chunk-6TAX66IA.js} +2 -2
  98. package/dist/{chunk-AGKIG3YA.js → chunk-6VALIZKG.js} +2 -2
  99. package/dist/{chunk-YQ3CBLL4.js → chunk-76PL4XLG.js} +512 -8
  100. package/dist/chunk-76PL4XLG.js.map +1 -0
  101. package/dist/{chunk-4NZHHGVL.js → chunk-7BDZTALN.js} +4 -1
  102. package/dist/chunk-7BDZTALN.js.map +1 -0
  103. package/dist/{chunk-NS5ETDYD.js → chunk-7BEPVIH3.js} +3 -3
  104. package/dist/{chunk-JG22O53B.js → chunk-7CBKAQIG.js} +2 -1
  105. package/dist/chunk-7CBKAQIG.js.map +1 -0
  106. package/dist/{chunk-LYIZXQYY.js → chunk-7KFIMGMP.js} +2 -2
  107. package/dist/{chunk-LWVO2QZV.js → chunk-7QOO4LGC.js} +56 -56
  108. package/dist/chunk-AAXJNINV.js +55 -0
  109. package/dist/chunk-AAXJNINV.js.map +1 -0
  110. package/dist/{chunk-56BSXSHC.js → chunk-AB3A7EFH.js} +31 -2
  111. package/dist/{chunk-56BSXSHC.js.map → chunk-AB3A7EFH.js.map} +1 -1
  112. package/dist/{chunk-CCTVAVTT.js → chunk-AUO2LJ3K.js} +2 -2
  113. package/dist/{chunk-ALCJRQ72.js → chunk-AYDDB3XI.js} +2 -2
  114. package/dist/{chunk-3TMYV3LP.js → chunk-AYYGRVRP.js} +5 -5
  115. package/dist/{chunk-W6TSGWYS.js → chunk-AZAA5DNP.js} +2 -2
  116. package/dist/{chunk-WTOE7CW4.js → chunk-BKYPJUQL.js} +122 -16
  117. package/dist/chunk-BKYPJUQL.js.map +1 -0
  118. package/dist/{chunk-6JJT5AKI.js → chunk-BQUEAVNW.js} +2 -2
  119. package/dist/{chunk-2NLLXCJG.js → chunk-BXLOS5AJ.js} +2 -2
  120. package/dist/{chunk-CEH2AFXG.js → chunk-C24UZSFW.js} +6 -6
  121. package/dist/{chunk-ZPN7W3OP.js → chunk-CDUUDBWJ.js} +3 -3
  122. package/dist/{chunk-35NN3ZFA.js → chunk-CTVWELNK.js} +21 -3
  123. package/dist/chunk-CTVWELNK.js.map +1 -0
  124. package/dist/{chunk-Y23B2QXP.js → chunk-D27J626P.js} +2 -2
  125. package/dist/{chunk-2572MRP2.js → chunk-DHTQP334.js} +2 -2
  126. package/dist/{chunk-HJQZQUPC.js → chunk-DJZWNKFO.js} +5 -5
  127. package/dist/{chunk-X7Y7WX73.js → chunk-DQEMWVMT.js} +1 -1
  128. package/dist/{chunk-VJ6ECBIP.js → chunk-E4MVQQVX.js} +2 -2
  129. package/dist/{chunk-SYJ6EKKE.js → chunk-EIVIB73I.js} +2 -2
  130. package/dist/{chunk-HUNSEO5U.js → chunk-EV3YFLCB.js} +2 -2
  131. package/dist/{chunk-GEULB2VI.js → chunk-FC7TIRFS.js} +21 -1
  132. package/dist/chunk-FC7TIRFS.js.map +1 -0
  133. package/dist/{chunk-VPGRXEAB.js → chunk-G57LQRP6.js} +2 -2
  134. package/dist/{chunk-BC4QD3FM.js → chunk-GN55KU2P.js} +2 -2
  135. package/dist/{chunk-4W6INNXO.js → chunk-GUXS322H.js} +2 -2
  136. package/dist/{chunk-DBXZZIDU.js → chunk-H5FW4S5Q.js} +434 -693
  137. package/dist/chunk-H5FW4S5Q.js.map +1 -0
  138. package/dist/chunk-I32NKXE2.js +879 -0
  139. package/dist/chunk-I32NKXE2.js.map +1 -0
  140. package/dist/{chunk-3MADV4YC.js → chunk-IQSC3V2E.js} +2 -2
  141. package/dist/{chunk-UYCIS6V5.js → chunk-JCWY73FK.js} +2 -2
  142. package/dist/{chunk-T42L3S6A.js → chunk-LBWQ65SX.js} +4 -4
  143. package/dist/{chunk-MSTNSVXI.js → chunk-LDBFXD4F.js} +2 -1
  144. package/dist/chunk-LDBFXD4F.js.map +1 -0
  145. package/dist/{chunk-CEQF6L5K.js → chunk-LUNJ3WFO.js} +9 -7
  146. package/dist/chunk-LUNJ3WFO.js.map +1 -0
  147. package/dist/{chunk-256FBCVX.js → chunk-M4AHBM72.js} +7 -7
  148. package/dist/{chunk-YEQEGSJA.js → chunk-MBDJJTAT.js} +3 -3
  149. package/dist/{chunk-IAY7YBXS.js → chunk-MRTUN665.js} +2 -2
  150. package/dist/{chunk-JFJ3MHGV.js → chunk-NXKJHSDN.js} +1 -1
  151. package/dist/chunk-NXKJHSDN.js.map +1 -0
  152. package/dist/{chunk-R3AAOKR2.js → chunk-NZWEEALH.js} +2 -2
  153. package/dist/{chunk-I2HTKOOP.js → chunk-ODZG724P.js} +2 -2
  154. package/dist/{chunk-7QFBLYFP.js → chunk-OJD4WS2E.js} +3 -3
  155. package/dist/{chunk-CUS6S7PN.js → chunk-OLWTCWQ2.js} +9 -9
  156. package/dist/chunk-OLWTCWQ2.js.map +1 -0
  157. package/dist/{chunk-53ENM6F6.js → chunk-P4DHENRE.js} +2 -2
  158. package/dist/{chunk-DEFI2QBT.js → chunk-PAYGC3BD.js} +52 -22
  159. package/dist/chunk-PAYGC3BD.js.map +1 -0
  160. package/dist/{chunk-KPBLJCCV.js → chunk-PDVQ5JU3.js} +2 -2
  161. package/dist/{chunk-7BY7V4YX.js → chunk-Q4WONDMJ.js} +4 -3
  162. package/dist/{chunk-7BY7V4YX.js.map → chunk-Q4WONDMJ.js.map} +1 -1
  163. package/dist/{chunk-ESCQ6LY7.js → chunk-QFMO32TO.js} +3 -3
  164. package/dist/{chunk-HQSPXTQO.js → chunk-QXIQPCCN.js} +1 -1
  165. package/dist/{chunk-CFRBTATE.js → chunk-R47WINCY.js} +3 -3
  166. package/dist/{chunk-G72IPMR7.js → chunk-R4OCGPSH.js} +2 -2
  167. package/dist/{chunk-LCU5R6TQ.js → chunk-RAIUTAZZ.js} +22 -3
  168. package/dist/chunk-RAIUTAZZ.js.map +1 -0
  169. package/dist/chunk-RIAM7DND.js +167 -0
  170. package/dist/chunk-RIAM7DND.js.map +1 -0
  171. package/dist/{chunk-VZVP2W4O.js → chunk-RK4WXUI2.js} +2 -2
  172. package/dist/{chunk-JBPKEARU.js → chunk-RKNJBZ55.js} +4 -4
  173. package/dist/{chunk-6L27N6YI.js → chunk-S7Q5CM7E.js} +2 -2
  174. package/dist/{chunk-CTQRPANJ.js → chunk-SVSRPG6M.js} +2 -2
  175. package/dist/{chunk-GXWDWOWP.js → chunk-TDKSCV62.js} +2 -2
  176. package/dist/{chunk-S2VBSTTA.js → chunk-THG4GYIE.js} +2 -2
  177. package/dist/{chunk-IXRC7EQG.js → chunk-TR7DGXGI.js} +2 -2
  178. package/dist/{chunk-63FHSH7E.js → chunk-TYUS5TLG.js} +4 -4
  179. package/dist/{chunk-7PWWGYGO.js → chunk-URHCUXKI.js} +2 -2
  180. package/dist/{chunk-Z54TXZ2F.js → chunk-VA5KMSAE.js} +16 -7
  181. package/dist/chunk-VA5KMSAE.js.map +1 -0
  182. package/dist/{chunk-KQAFEZQX.js → chunk-VDX2J7OX.js} +2 -2
  183. package/dist/{chunk-MUJ4QFUQ.js → chunk-W4BMEGQA.js} +4 -4
  184. package/dist/{chunk-5HK3CJAR.js → chunk-W675UJCZ.js} +2 -2
  185. package/dist/{chunk-3PXVYJMC.js → chunk-WN5FSGLE.js} +2077 -215
  186. package/dist/chunk-WN5FSGLE.js.map +1 -0
  187. package/dist/{chunk-3RHFGGI5.js → chunk-YF6UHWOV.js} +30 -10
  188. package/dist/chunk-YF6UHWOV.js.map +1 -0
  189. package/dist/{chunk-X5SDZMO7.js → chunk-YHCBJULX.js} +2 -2
  190. package/dist/{chunk-5UYSCYR7.js → chunk-Z4RPXHJH.js} +4 -4
  191. package/dist/{cli-Pulnz-qm.d.ts → cli-ChKeYMZv.d.ts} +5 -5
  192. package/dist/cli.d.ts +25 -25
  193. package/dist/cli.js +81 -78
  194. package/dist/coding/pre-action-gate.d.ts +2 -60
  195. package/dist/compounding/engine.d.ts +4 -2
  196. package/dist/compounding/engine.js +17 -16
  197. package/dist/compounding/preference-consolidator.d.ts +3 -1
  198. package/dist/compression-optimizer.d.ts +3 -1
  199. package/dist/config.d.ts +3 -1
  200. package/dist/config.js +11 -1
  201. package/dist/connectors/codex-materialize-runner.d.ts +3 -1
  202. package/dist/connectors/codex-materialize-runner.js +16 -15
  203. package/dist/connectors/codex-materialize.d.ts +3 -1
  204. package/dist/connectors/index.d.ts +3 -1
  205. package/dist/connectors/index.js +16 -15
  206. package/dist/consolidation-provenance-check.d.ts +4 -2
  207. package/dist/consolidation-undo.d.ts +4 -2
  208. package/dist/contradiction/index.d.ts +10 -270
  209. package/dist/contradiction/index.js +20 -7
  210. package/dist/{contradiction-review-QKJH5DKD.js → contradiction-review-WRVLRWHS.js} +6 -2
  211. package/dist/{contradiction-scan-VOTQRRSX.js → contradiction-scan-AKUWPX5N.js} +5 -3
  212. package/dist/converge-config.d.ts +3 -1
  213. package/dist/convergence-refresh.d.ts +4 -2
  214. package/dist/convergence-refresh.js +18 -17
  215. package/dist/conversation-index/backend.d.ts +3 -1
  216. package/dist/conversation-index/chunker.d.ts +3 -1
  217. package/dist/conversation-index/faiss-adapter.d.ts +3 -1
  218. package/dist/conversation-index/indexer.d.ts +3 -1
  219. package/dist/conversation-index/search.d.ts +3 -1
  220. package/dist/corpus-watermark.d.ts +3 -1
  221. package/dist/corpus-watermark.js +18 -17
  222. package/dist/cross-lingual-recall.d.ts +3 -1
  223. package/dist/day-summary.d.ts +3 -1
  224. package/dist/delinearize.d.ts +3 -1
  225. package/dist/dependency-propagation-config.d.ts +3 -1
  226. package/dist/{dependency-propagation-delivery-Co17gxYb.d.ts → dependency-propagation-delivery-B8ZMBBCY.d.ts} +1 -1
  227. package/dist/direct-answer-wiring.d.ts +3 -1
  228. package/dist/direct-answer.d.ts +3 -1
  229. package/dist/embedding-fallback.d.ts +3 -1
  230. package/dist/enrichment/index.d.ts +3 -1
  231. package/dist/entity-origin-fields.d.ts +3 -1
  232. package/dist/entity-retrieval.d.ts +4 -2
  233. package/dist/entity-retrieval.js +16 -15
  234. package/dist/entity-schema.d.ts +3 -1
  235. package/dist/episodic-context.d.ts +3 -1
  236. package/dist/explicit-capture.d.ts +12 -12
  237. package/dist/explicit-capture.js +7 -6
  238. package/dist/external-wiki-access.d.ts +41 -42
  239. package/dist/external-wiki-access.js +37 -36
  240. package/dist/external-wiki-collection-registration.d.ts +3 -1
  241. package/dist/external-wiki-collection.d.ts +3 -1
  242. package/dist/external-wiki-mcp-tools.d.ts +40 -40
  243. package/dist/extraction-error-classification.d.ts +3 -1
  244. package/dist/extraction-faithfulness.d.ts +3 -1
  245. package/dist/extraction-judge-telemetry.d.ts +3 -1
  246. package/dist/extraction-judge-training.d.ts +3 -1
  247. package/dist/extraction-judge.d.ts +3 -1
  248. package/dist/extraction-judge.js +2 -2
  249. package/dist/extraction-liveness.d.ts +3 -1
  250. package/dist/extraction-normalization.d.ts +3 -1
  251. package/dist/extraction-normalization.js +2 -2
  252. package/dist/extraction-prompt.d.ts +4 -2
  253. package/dist/extraction-prompt.js +1 -1
  254. package/dist/extraction-source-grounding-rules.d.ts +3 -1
  255. package/dist/extraction-source-grounding.d.ts +3 -1
  256. package/dist/extraction.d.ts +3 -1
  257. package/dist/extraction.js +22 -21
  258. package/dist/fallback-llm.d.ts +3 -1
  259. package/dist/graph-dashboard-diff.d.ts +3 -1
  260. package/dist/graph-dashboard-key.d.ts +3 -1
  261. package/dist/graph-dashboard-parser.d.ts +3 -1
  262. package/dist/graph-edge-reinforcement.d.ts +3 -1
  263. package/dist/graph-path-reconstruction.d.ts +3 -1
  264. package/dist/graph-path-scoring.d.ts +3 -1
  265. package/dist/graph-snapshot.d.ts +3 -1
  266. package/dist/graph.d.ts +3 -1
  267. package/dist/harmonic-retrieval.js +1 -1
  268. package/dist/importance.d.ts +3 -1
  269. package/dist/importers/index.d.ts +3 -1
  270. package/dist/in-flight-reads.d.ts +3 -1
  271. package/dist/index-CexDrJzC.d.ts +284 -0
  272. package/dist/index.d.ts +946 -707
  273. package/dist/index.js +253 -151
  274. package/dist/intent.d.ts +3 -1
  275. package/dist/lcm/engine.d.ts +3 -1
  276. package/dist/lcm/engine.js +3 -3
  277. package/dist/lcm/index.d.ts +3 -1
  278. package/dist/lcm/index.js +6 -6
  279. package/dist/lcm/tools.d.ts +3 -1
  280. package/dist/lifecycle.d.ts +3 -1
  281. package/dist/live-connectors-runner.d.ts +3 -1
  282. package/dist/local-llm.d.ts +3 -1
  283. package/dist/local-model-endpoint.d.ts +3 -1
  284. package/dist/maintenance/memory-governance.d.ts +3 -1
  285. package/dist/maintenance/memory-governance.js +16 -15
  286. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +4 -2
  287. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +16 -15
  288. package/dist/maintenance/rebuild-memory-projection.d.ts +4 -2
  289. package/dist/maintenance/rebuild-memory-projection.js +17 -16
  290. package/dist/{maintenance-DiSLtVN7.d.ts → maintenance-nkdtSrVr.d.ts} +3 -3
  291. package/dist/mcp-memory-inspector-app.d.ts +37 -37
  292. package/dist/mcp-read-only-tools.js +1 -1
  293. package/dist/memory-action-policy.d.ts +3 -1
  294. package/dist/memory-cache.d.ts +3 -1
  295. package/dist/memory-lifecycle-ledger-utils.d.ts +3 -1
  296. package/dist/memory-projection-store.d.ts +3 -1
  297. package/dist/memory-provenance.d.ts +3 -1
  298. package/dist/memory-snapshot.d.ts +3 -1
  299. package/dist/memory-subject-cli.d.ts +177 -0
  300. package/dist/memory-subject-cli.js +16 -0
  301. package/dist/memory-subject.d.ts +128 -0
  302. package/dist/memory-subject.js +44 -0
  303. package/dist/memory-subject.js.map +1 -0
  304. package/dist/memory-worth-outcomes.d.ts +7 -4
  305. package/dist/memory-worth-outcomes.js +1 -1
  306. package/dist/models-json.d.ts +3 -1
  307. package/dist/namespaces/migrate.d.ts +5 -3
  308. package/dist/namespaces/migrate.js +17 -16
  309. package/dist/namespaces/principal.d.ts +3 -1
  310. package/dist/namespaces/search.d.ts +3 -1
  311. package/dist/namespaces/search.js +6 -6
  312. package/dist/namespaces/storage.d.ts +5 -3
  313. package/dist/namespaces/storage.js +16 -15
  314. package/dist/native-knowledge.d.ts +3 -1
  315. package/dist/offline-sync-impression-drain.d.ts +3 -1
  316. package/dist/operator-doctor-corpus.d.ts +3 -1
  317. package/dist/operator-doctor-corpus.js +19 -18
  318. package/dist/operator-doctor-replica.d.ts +3 -1
  319. package/dist/operator-toolkit.d.ts +5 -3
  320. package/dist/operator-toolkit.js +29 -24
  321. package/dist/orchestration/compression-guideline-coordinator.d.ts +4 -2
  322. package/dist/orchestration/maintenance.d.ts +6 -4
  323. package/dist/orchestration/maintenance.js +22 -21
  324. package/dist/{orchestrator-DzCaxNS4.d.ts → orchestrator-Bvq1-RQs.d.ts} +23 -9
  325. package/dist/orchestrator.d.ts +12 -12
  326. package/dist/orchestrator.js +111 -108
  327. package/dist/patterns-cli.d.ts +3 -1
  328. package/dist/{pipeline-HJ8DKbFl.d.ts → pipeline-C8vfIiTX.d.ts} +1 -1
  329. package/dist/policy-runtime.d.ts +3 -1
  330. package/dist/proactive-contention.d.ts +3 -1
  331. package/dist/provenance.d.ts +3 -1
  332. package/dist/{public-http-DwXauTX3.d.ts → public-http-Cy0aYbys.d.ts} +1 -1
  333. package/dist/{qmd-BzxluoLt.d.ts → qmd-B9p1SZTZ.d.ts} +1 -1
  334. package/dist/qmd-preflight.d.ts +4 -2
  335. package/dist/qmd-recall-cache.d.ts +3 -1
  336. package/dist/qmd.d.ts +4 -2
  337. package/dist/qmd.js +4 -4
  338. package/dist/recall-concurrency-config.d.ts +3 -1
  339. package/dist/recall-disclosure-escalation.d.ts +3 -1
  340. package/dist/recall-explain-renderer.d.ts +3 -1
  341. package/dist/recall-explain-renderer.js +3 -3
  342. package/dist/recall-memory-map.d.ts +3 -1
  343. package/dist/recall-planner-llm.d.ts +3 -1
  344. package/dist/recall-state.d.ts +3 -1
  345. package/dist/recall-tag-filter.d.ts +3 -1
  346. package/dist/recall-timings.d.ts +3 -1
  347. package/dist/recall-xray-cli.d.ts +3 -1
  348. package/dist/recall-xray-cli.js +4 -4
  349. package/dist/recall-xray-renderer.d.ts +3 -1
  350. package/dist/recall-xray-renderer.js +3 -3
  351. package/dist/recall-xray.d.ts +3 -1
  352. package/dist/recall-xray.js +2 -2
  353. package/dist/reconcile/cursor.d.ts +3 -1
  354. package/dist/reconcile/manifest.d.ts +3 -1
  355. package/dist/reconcile/manifest.js +3 -3
  356. package/dist/reconcile/plan.d.ts +3 -1
  357. package/dist/replay/normalizers/chatgpt.d.ts +3 -1
  358. package/dist/replay/normalizers/claude.d.ts +3 -1
  359. package/dist/replay/normalizers/openclaw.d.ts +3 -1
  360. package/dist/replay/normalizers/shared.d.ts +3 -1
  361. package/dist/replay/runner.d.ts +3 -1
  362. package/dist/replay/types.d.ts +3 -1
  363. package/dist/replica-divergence.d.ts +3 -1
  364. package/dist/replica-peers-config.d.ts +3 -1
  365. package/dist/resolution-4552BNRV.js +36 -0
  366. package/dist/resolution-4552BNRV.js.map +1 -0
  367. package/dist/resolve-auth-token.d.ts +3 -1
  368. package/dist/resume-bundles.js +9 -2
  369. package/dist/retrieval-agents.d.ts +4 -2
  370. package/dist/retrieval-tiers.d.ts +3 -1
  371. package/dist/routing/engine.d.ts +3 -1
  372. package/dist/routing/store.d.ts +3 -1
  373. package/dist/salvage-envelope.d.ts +3 -1
  374. package/dist/salvage-envelope.js +10 -2
  375. package/dist/schemas.d.ts +130 -116
  376. package/dist/schemas.js +1 -1
  377. package/dist/{scope-profiles-CEMZz0t5.d.ts → scope-profiles-DLrRxFWR.d.ts} +1 -1
  378. package/dist/search/embed-helper.d.ts +3 -1
  379. package/dist/search/factory.d.ts +3 -1
  380. package/dist/search/factory.js +5 -5
  381. package/dist/search/index.d.ts +3 -1
  382. package/dist/search/index.js +9 -9
  383. package/dist/search/lancedb-backend.d.ts +3 -1
  384. package/dist/search/meilisearch-backend.d.ts +3 -1
  385. package/dist/search/noop-backend.d.ts +3 -1
  386. package/dist/search/orama-backend.d.ts +3 -1
  387. package/dist/search/port.d.ts +3 -1
  388. package/dist/search/remote-backend.d.ts +3 -1
  389. package/dist/{semantic-TddhF0y7.d.ts → semantic-BalR6EXU.d.ts} +1 -1
  390. package/dist/{semantic-consolidation-D9dYj6vu.d.ts → semantic-consolidation-DlN6xe20.d.ts} +1 -1
  391. package/dist/semantic-consolidation.d.ts +4 -2
  392. package/dist/semantic-consolidation.js +17 -16
  393. package/dist/semantic-rule-promotion.js +16 -15
  394. package/dist/semantic-rule-verifier.d.ts +3 -1
  395. package/dist/semantic-rule-verifier.js +16 -15
  396. package/dist/{service-_qgST_0y.d.ts → service-GkYyVfm9.d.ts} +2 -2
  397. package/dist/session-observer-bands.d.ts +3 -1
  398. package/dist/session-observer-state.d.ts +3 -1
  399. package/dist/shared-context/manager.d.ts +13 -11
  400. package/dist/signal.d.ts +3 -1
  401. package/dist/source-agent-qualifier.d.ts +3 -1
  402. package/dist/source-agent-qualifier.js +18 -17
  403. package/dist/{storage-B9lbNTYE.d.ts → storage-BIDzuKIn.d.ts} +3 -2
  404. package/dist/storage.d.ts +4 -2
  405. package/dist/storage.js +18 -17
  406. package/dist/subject-config.d.ts +40 -0
  407. package/dist/subject-config.js +20 -0
  408. package/dist/subject-config.js.map +1 -0
  409. package/dist/summarizer.d.ts +3 -1
  410. package/dist/summary-snapshot.d.ts +3 -1
  411. package/dist/support-passport/index.d.ts +43 -43
  412. package/dist/support-passport/index.js +39 -38
  413. package/dist/temporal-supersession.d.ts +4 -2
  414. package/dist/temporal-timeline-recall.d.ts +3 -1
  415. package/dist/temporal-validity.d.ts +3 -1
  416. package/dist/threading.d.ts +3 -1
  417. package/dist/tier-migration.d.ts +4 -2
  418. package/dist/tier-routing.d.ts +3 -1
  419. package/dist/topics.d.ts +3 -1
  420. package/dist/transcript.d.ts +3 -1
  421. package/dist/transfer/backup.js +2 -2
  422. package/dist/transfer/capsule-export.js +2 -2
  423. package/dist/transfer/capsule-import.js +2 -2
  424. package/dist/transfer/types.d.ts +86 -86
  425. package/dist/trust-score-stage.d.ts +3 -1
  426. package/dist/trust-score.d.ts +3 -1
  427. package/dist/{types-BrEzuxPA.d.ts → types-BxAcOl5Q.d.ts} +360 -32
  428. package/dist/types.d.ts +3 -1
  429. package/dist/types.js +1 -1
  430. package/dist/utility-runtime.d.ts +3 -1
  431. package/dist/verified-recall.js +16 -15
  432. package/dist/who-knows-cli.d.ts +40 -40
  433. package/dist/who-knows-cli.js +17 -16
  434. package/dist/who-knows.d.ts +42 -42
  435. package/dist/who-knows.js +16 -15
  436. package/dist/write-envelope.d.ts +7 -2
  437. package/dist/write-envelope.js +10 -1
  438. package/package.json +2 -2
  439. package/scripts/build-with-heap.mjs +1 -1
  440. package/src/access-boundary.ts +6 -0
  441. package/src/access-http.ts +6 -5
  442. package/src/access-mcp-admin-tools.ts +38 -0
  443. package/src/access-mcp-output-schemas.ts +20 -0
  444. package/src/access-mcp.ts +8 -8
  445. package/src/access-operations-batch.ts +13 -0
  446. package/src/access-service.ts +112 -0
  447. package/src/access-surface-catalog.test.ts +24 -0
  448. package/src/access-surface-catalog.ts +6 -0
  449. package/src/coding/action-gate.test.ts +341 -0
  450. package/src/coding/action-gate.ts +556 -0
  451. package/src/config.ts +15 -17
  452. package/src/contradiction/contradiction-review.ts +50 -4
  453. package/src/contradiction/contradiction-scan.ts +14 -3
  454. package/src/contradiction/resolution.ts +50 -2
  455. package/src/extraction-prompt.ts +1 -0
  456. package/src/extraction.ts +4 -1
  457. package/src/index.ts +9 -9
  458. package/src/mcp-read-only-tools.ts +1 -0
  459. package/src/memory-subject-cli.ts +135 -0
  460. package/src/memory-subject.test.ts +48 -0
  461. package/src/memory-subject.ts +314 -0
  462. package/src/memory-worth-outcomes.test.ts +6 -2
  463. package/src/memory-worth-outcomes.ts +11 -7
  464. package/src/operator-toolkit.ts +1 -1
  465. package/src/orchestration/extraction-persist.ts +48 -48
  466. package/src/orchestration/recall-internal.ts +6 -5
  467. package/src/orchestration/recall-rerank-coordinator.ts +123 -4
  468. package/src/orchestration/recall-result-formatter.ts +6 -2
  469. package/src/orchestration/recall-search-pipeline.ts +14 -1
  470. package/src/preferences/drift-config.ts +118 -0
  471. package/src/preferences/drift-recall.ts +133 -0
  472. package/src/preferences/drift-types.ts +87 -0
  473. package/src/preferences/index.ts +12 -0
  474. package/src/preferences/preference-drift.test.ts +690 -0
  475. package/src/preferences/preference-drift.ts +724 -0
  476. package/src/procedural/library-maintenance.test.ts +582 -0
  477. package/src/procedural/library-maintenance.ts +546 -0
  478. package/src/procedural/maintenance-config.ts +78 -0
  479. package/src/procedural/procedure-recall.ts +29 -1
  480. package/src/procedural/procedure-stats.ts +20 -0
  481. package/src/review/review-deck-access.test.ts +325 -0
  482. package/src/review/review-deck-http-base.ts +133 -0
  483. package/src/review/review-deck-mutation.test.ts +417 -0
  484. package/src/review/review-deck-mutation.ts +677 -0
  485. package/src/review/review-deck-snapshot.ts +196 -0
  486. package/src/review/review-deck-surface.ts +117 -0
  487. package/src/review/review-deck.test.ts +347 -0
  488. package/src/review/review-deck.ts +311 -0
  489. package/src/schemas.ts +7 -0
  490. package/src/spaces/index.ts +38 -2
  491. package/src/storage.ts +10 -8
  492. package/src/subject-config.ts +80 -0
  493. package/src/types.ts +33 -32
  494. package/src/write-envelope.test.ts +14 -0
  495. package/src/write-envelope.ts +24 -3
  496. package/dist/chunk-35NN3ZFA.js.map +0 -1
  497. package/dist/chunk-3PXVYJMC.js.map +0 -1
  498. package/dist/chunk-3RHFGGI5.js.map +0 -1
  499. package/dist/chunk-4NZHHGVL.js.map +0 -1
  500. package/dist/chunk-CEQF6L5K.js.map +0 -1
  501. package/dist/chunk-CUS6S7PN.js.map +0 -1
  502. package/dist/chunk-DBXZZIDU.js.map +0 -1
  503. package/dist/chunk-DEFI2QBT.js.map +0 -1
  504. package/dist/chunk-EIR5VLIH.js.map +0 -1
  505. package/dist/chunk-GEULB2VI.js.map +0 -1
  506. package/dist/chunk-JFJ3MHGV.js.map +0 -1
  507. package/dist/chunk-JG22O53B.js.map +0 -1
  508. package/dist/chunk-LCU5R6TQ.js.map +0 -1
  509. package/dist/chunk-MDVBCPOS.js +0 -402
  510. package/dist/chunk-MDVBCPOS.js.map +0 -1
  511. package/dist/chunk-MSTNSVXI.js.map +0 -1
  512. package/dist/chunk-WTOE7CW4.js.map +0 -1
  513. package/dist/chunk-YQ3CBLL4.js.map +0 -1
  514. package/dist/chunk-Z54TXZ2F.js.map +0 -1
  515. package/dist/resolution-DKMBPXHI.js +0 -18
  516. /package/dist/{capsule-crypto-7FJQINUR.js.map → capsule-crypto-YO5QJ6L3.js.map} +0 -0
  517. /package/dist/{chunk-MIBKEW7A.js.map → chunk-2VXWFYJE.js.map} +0 -0
  518. /package/dist/{chunk-3YTTAGPB.js.map → chunk-3DVBKTSO.js.map} +0 -0
  519. /package/dist/{chunk-JTSVMJHV.js.map → chunk-4XDGYCZI.js.map} +0 -0
  520. /package/dist/{chunk-HQSBYI5X.js.map → chunk-57HVIG5U.js.map} +0 -0
  521. /package/dist/{chunk-PMVPCZJZ.js.map → chunk-6433HV72.js.map} +0 -0
  522. /package/dist/{chunk-N6TRHP72.js.map → chunk-6TAX66IA.js.map} +0 -0
  523. /package/dist/{chunk-AGKIG3YA.js.map → chunk-6VALIZKG.js.map} +0 -0
  524. /package/dist/{chunk-NS5ETDYD.js.map → chunk-7BEPVIH3.js.map} +0 -0
  525. /package/dist/{chunk-LYIZXQYY.js.map → chunk-7KFIMGMP.js.map} +0 -0
  526. /package/dist/{chunk-LWVO2QZV.js.map → chunk-7QOO4LGC.js.map} +0 -0
  527. /package/dist/{chunk-CCTVAVTT.js.map → chunk-AUO2LJ3K.js.map} +0 -0
  528. /package/dist/{chunk-ALCJRQ72.js.map → chunk-AYDDB3XI.js.map} +0 -0
  529. /package/dist/{chunk-3TMYV3LP.js.map → chunk-AYYGRVRP.js.map} +0 -0
  530. /package/dist/{chunk-W6TSGWYS.js.map → chunk-AZAA5DNP.js.map} +0 -0
  531. /package/dist/{chunk-6JJT5AKI.js.map → chunk-BQUEAVNW.js.map} +0 -0
  532. /package/dist/{chunk-2NLLXCJG.js.map → chunk-BXLOS5AJ.js.map} +0 -0
  533. /package/dist/{chunk-CEH2AFXG.js.map → chunk-C24UZSFW.js.map} +0 -0
  534. /package/dist/{chunk-ZPN7W3OP.js.map → chunk-CDUUDBWJ.js.map} +0 -0
  535. /package/dist/{chunk-Y23B2QXP.js.map → chunk-D27J626P.js.map} +0 -0
  536. /package/dist/{chunk-2572MRP2.js.map → chunk-DHTQP334.js.map} +0 -0
  537. /package/dist/{chunk-HJQZQUPC.js.map → chunk-DJZWNKFO.js.map} +0 -0
  538. /package/dist/{chunk-X7Y7WX73.js.map → chunk-DQEMWVMT.js.map} +0 -0
  539. /package/dist/{chunk-VJ6ECBIP.js.map → chunk-E4MVQQVX.js.map} +0 -0
  540. /package/dist/{chunk-SYJ6EKKE.js.map → chunk-EIVIB73I.js.map} +0 -0
  541. /package/dist/{chunk-HUNSEO5U.js.map → chunk-EV3YFLCB.js.map} +0 -0
  542. /package/dist/{chunk-VPGRXEAB.js.map → chunk-G57LQRP6.js.map} +0 -0
  543. /package/dist/{chunk-BC4QD3FM.js.map → chunk-GN55KU2P.js.map} +0 -0
  544. /package/dist/{chunk-4W6INNXO.js.map → chunk-GUXS322H.js.map} +0 -0
  545. /package/dist/{chunk-3MADV4YC.js.map → chunk-IQSC3V2E.js.map} +0 -0
  546. /package/dist/{chunk-UYCIS6V5.js.map → chunk-JCWY73FK.js.map} +0 -0
  547. /package/dist/{chunk-T42L3S6A.js.map → chunk-LBWQ65SX.js.map} +0 -0
  548. /package/dist/{chunk-256FBCVX.js.map → chunk-M4AHBM72.js.map} +0 -0
  549. /package/dist/{chunk-YEQEGSJA.js.map → chunk-MBDJJTAT.js.map} +0 -0
  550. /package/dist/{chunk-IAY7YBXS.js.map → chunk-MRTUN665.js.map} +0 -0
  551. /package/dist/{chunk-R3AAOKR2.js.map → chunk-NZWEEALH.js.map} +0 -0
  552. /package/dist/{chunk-I2HTKOOP.js.map → chunk-ODZG724P.js.map} +0 -0
  553. /package/dist/{chunk-7QFBLYFP.js.map → chunk-OJD4WS2E.js.map} +0 -0
  554. /package/dist/{chunk-53ENM6F6.js.map → chunk-P4DHENRE.js.map} +0 -0
  555. /package/dist/{chunk-KPBLJCCV.js.map → chunk-PDVQ5JU3.js.map} +0 -0
  556. /package/dist/{chunk-ESCQ6LY7.js.map → chunk-QFMO32TO.js.map} +0 -0
  557. /package/dist/{chunk-HQSPXTQO.js.map → chunk-QXIQPCCN.js.map} +0 -0
  558. /package/dist/{chunk-CFRBTATE.js.map → chunk-R47WINCY.js.map} +0 -0
  559. /package/dist/{chunk-G72IPMR7.js.map → chunk-R4OCGPSH.js.map} +0 -0
  560. /package/dist/{chunk-VZVP2W4O.js.map → chunk-RK4WXUI2.js.map} +0 -0
  561. /package/dist/{chunk-JBPKEARU.js.map → chunk-RKNJBZ55.js.map} +0 -0
  562. /package/dist/{chunk-6L27N6YI.js.map → chunk-S7Q5CM7E.js.map} +0 -0
  563. /package/dist/{chunk-CTQRPANJ.js.map → chunk-SVSRPG6M.js.map} +0 -0
  564. /package/dist/{chunk-GXWDWOWP.js.map → chunk-TDKSCV62.js.map} +0 -0
  565. /package/dist/{chunk-S2VBSTTA.js.map → chunk-THG4GYIE.js.map} +0 -0
  566. /package/dist/{chunk-IXRC7EQG.js.map → chunk-TR7DGXGI.js.map} +0 -0
  567. /package/dist/{chunk-63FHSH7E.js.map → chunk-TYUS5TLG.js.map} +0 -0
  568. /package/dist/{chunk-7PWWGYGO.js.map → chunk-URHCUXKI.js.map} +0 -0
  569. /package/dist/{chunk-KQAFEZQX.js.map → chunk-VDX2J7OX.js.map} +0 -0
  570. /package/dist/{chunk-MUJ4QFUQ.js.map → chunk-W4BMEGQA.js.map} +0 -0
  571. /package/dist/{chunk-5HK3CJAR.js.map → chunk-W675UJCZ.js.map} +0 -0
  572. /package/dist/{chunk-X5SDZMO7.js.map → chunk-YHCBJULX.js.map} +0 -0
  573. /package/dist/{chunk-5UYSCYR7.js.map → chunk-Z4RPXHJH.js.map} +0 -0
  574. /package/dist/{contradiction-review-QKJH5DKD.js.map → contradiction-review-WRVLRWHS.js.map} +0 -0
  575. /package/dist/{contradiction-scan-VOTQRRSX.js.map → contradiction-scan-AKUWPX5N.js.map} +0 -0
  576. /package/dist/{resolution-DKMBPXHI.js.map → memory-subject-cli.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
@@ -37,10 +37,13 @@ import { expandTildePath } from "./utils/path.js";
37
37
  // lives in connectors/coerce.ts (a tiny, dependency-free module) so neither
38
38
  // config.ts → connectors/index.ts nor the reverse circular import arises.
39
39
  import { coerceBool, coerceBooleanLike, coerceInstallExtension, coerceNumber } from "./connectors/coerce.js";
40
+ import { parseSubjectRuntimeConfig } from "./subject-config.js";
40
41
  import { parseRecallConcurrencyConfig } from "./recall-concurrency-config.js";
41
42
  import { parseExtractionLivenessConfig } from "./extraction-liveness.js";
42
43
  import { parseReplicaPeersConfig } from "./replica-peers-config.js";
43
44
  import { parseDependencyPropagationConfig } from "./dependency-propagation-config.js";
45
+ import { parseProceduralMaintenanceConfig } from "./procedural/maintenance-config.js";
46
+ import { parseDriftDetectionConfig } from "./preferences/drift-config.js";
44
47
  import {
45
48
  parseContradictionLocalizationConfig,
46
49
  parseContradictionScanConfig,
@@ -66,6 +69,7 @@ import { parseLocationConfig } from "./location/config.js";
66
69
  import { parseOkfConfig } from "./okf/config.js";
67
70
  import { parseBoundedJsonlStateConfig } from "./bounded-jsonl-state.js";
68
71
  import { parseCodingKnowledgeConfig } from "./coding/coding-knowledge-config.js";
72
+ import { parseActionGateConfig } from "./coding/action-gate.js";
69
73
  import { parseChatConfig } from "./chat/chat-config.js";
70
74
  import { parseSupportPassportConfig } from "./support-passport/config.js";
71
75
  import { parseCorrectionIntentConfig, parseFaithfulnessGateConfig } from "./faithfulness-config.js";
@@ -1123,16 +1127,9 @@ export function parseConfig(
1123
1127
  recallMaxCoerced !== undefined && Number.isFinite(recallMaxCoerced)
1124
1128
  ? Math.min(10, Math.max(1, Math.floor(recallMaxCoerced)))
1125
1129
  : 2;
1126
- // Default-on procedural memory (issue #567 PR 4/5): if the user has NOT
1127
- // explicitly set `procedural.enabled`, enable it. Explicit `false` (or any
1128
- // value coerceBool reads as false: `"0"`, `"no"`, `"off"`, `false`) keeps
1129
- // the feature off. CLAUDE.md rules:
1130
- // - #30 — escape hatch remains for operators who want to stay opt-out.
1131
- // - #36 — "false"-ish strings coerce to false via coerceBool.
1132
- // - #51 — when the key IS present but the value can't be understood
1133
- // (typo like `"fales"` or a number like `0`), reject loudly instead
1134
- // of silently flipping the default. Silent fallback on bad input is
1135
- // how procedural memory would end up "fail-open" for typos.
1130
+ const maintenance = parseProceduralMaintenanceConfig(rawProcedural.maintenance);
1131
+ // Default-on procedural memory (issue #567 PR 4/5). Explicit false-ish
1132
+ // values stay off. Unknown values throw.
1136
1133
  const rawEnabledValue = rawProcedural.enabled;
1137
1134
  let proceduralEnabled: boolean;
1138
1135
  if (rawEnabledValue === undefined) {
@@ -1147,6 +1144,7 @@ export function parseConfig(
1147
1144
  proceduralEnabled = enabledCoerced;
1148
1145
  }
1149
1146
  const procedural: ProceduralConfig = {
1147
+ maintenance,
1150
1148
  enabled: proceduralEnabled,
1151
1149
  /** `0` skips all mining (`minOccurrences_zero`); otherwise clusters need at least this many members. */
1152
1150
  minOccurrences: Math.min(1000, Math.max(0, proceduralMinRaw)),
@@ -1793,6 +1791,8 @@ export function parseConfig(
1793
1791
  contradictionAutoResolve: cfg.contradictionAutoResolve !== false,
1794
1792
  // Contradiction Scan cron (issue #520)
1795
1793
  contradictionScan: parseContradictionScanConfig(cfg.contradictionScan),
1794
+ // Preference drift detection (issue #2371)
1795
+ driftDetection: parseDriftDetectionConfig(cfg.driftDetection),
1796
1796
  dependencyPropagation: parseDependencyPropagationConfig(cfg),
1797
1797
  // Temporal Supersession (issue #375)
1798
1798
  temporalSupersessionEnabled: cfg.temporalSupersessionEnabled !== false, // On by default
@@ -2333,6 +2333,7 @@ export function parseConfig(
2333
2333
  bridgeMode: cfg.bridgeMode === undefined ? "embedded" : String(cfg.bridgeMode),
2334
2334
  codexCompat,
2335
2335
  codingKnowledge: parseCodingKnowledgeConfig(cfg.codingKnowledge),
2336
+ actionGate: parseActionGateConfig(cfg.actionGate),
2336
2337
  chat: parseChatConfig(cfg.chat),
2337
2338
  supportPassport: parseSupportPassportConfig(cfg.supportPassport),
2338
2339
  hourlySummariesEnabled: cfg.hourlySummariesEnabled !== false, // default: true
@@ -2755,11 +2756,11 @@ export function parseConfig(
2755
2756
  }
2756
2757
  return "low";
2757
2758
  })(),
2758
- // Extraction scope classification. When enabled, the extraction prompt
2759
- // asks the LLM to classify each fact as "project" or "global". Global
2760
- // facts are promoted to the shared namespace. Default true (rule 30 gate).
2759
+ // Extraction scope classification (rule 30 gate): "global" facts promote
2760
+ // to the shared namespace. Default true.
2761
2761
  extractionScopeClassificationEnabled:
2762
2762
  coerceBool(cfg.extractionScopeClassificationEnabled) !== false,
2763
+ ...parseSubjectRuntimeConfig(cfg),
2763
2764
  // Extraction judge (issue #376). Opt-in LLM-as-judge fact-worthiness gate.
2764
2765
  extractionJudgeEnabled: cfg.extractionJudgeEnabled === true,
2765
2766
  extractionJudgeModel:
@@ -2778,10 +2779,7 @@ export function parseConfig(
2778
2779
  ? Math.floor(cfg.extractionJudgeMaxDeferrals)
2779
2780
  : 2,
2780
2781
  // Judge telemetry (issue #562 PR 3): opt-in structured emit to the
2781
- // observation ledger for defer-rate / latency metrics.
2782
- // Uses `coerceBool` so CLI-style string inputs (`"true"`, `"false"`,
2783
- // `"1"`, `"0"`) are accepted consistently with the rest of the
2784
- // codebase (CLAUDE.md gotcha 36).
2782
+ // observation ledger; `coerceBool` accepts CLI-style strings (gotcha 36).
2785
2783
  extractionJudgeTelemetryEnabled:
2786
2784
  coerceBool(cfg.extractionJudgeTelemetryEnabled) === true,
2787
2785
  // Judge training-pair collection (issue #562 PR 4): opt-in shim for a