@alan512/experienceengine 0.1.2 → 0.2.0

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 (642) hide show
  1. package/.claude-plugin/marketplace.json +0 -0
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.env.example +0 -0
  4. package/.mcp.json +4 -8
  5. package/LICENSE +21 -0
  6. package/README.md +288 -95
  7. package/README.zh-CN.md +316 -65
  8. package/dist/adapters/claude-code/event-store.d.ts +0 -0
  9. package/dist/adapters/claude-code/event-store.js +0 -0
  10. package/dist/adapters/claude-code/event-store.js.map +0 -0
  11. package/dist/adapters/claude-code/hook-normalizer.d.ts +0 -0
  12. package/dist/adapters/claude-code/hook-normalizer.js +0 -0
  13. package/dist/adapters/claude-code/hook-normalizer.js.map +0 -0
  14. package/dist/adapters/claude-code/runtime-projection.d.ts +0 -0
  15. package/dist/adapters/claude-code/runtime-projection.js +0 -0
  16. package/dist/adapters/claude-code/runtime-projection.js.map +0 -0
  17. package/dist/adapters/claude-code/session-store.d.ts +1 -0
  18. package/dist/adapters/claude-code/session-store.js +24 -1
  19. package/dist/adapters/claude-code/session-store.js.map +1 -1
  20. package/dist/adapters/codex/action-registry.d.ts +84 -0
  21. package/dist/adapters/codex/action-registry.js +277 -0
  22. package/dist/adapters/codex/action-registry.js.map +1 -0
  23. package/dist/adapters/codex/broker-tools.d.ts +114 -0
  24. package/dist/adapters/codex/broker-tools.js +130 -0
  25. package/dist/adapters/codex/broker-tools.js.map +1 -0
  26. package/dist/adapters/codex/instruction-template.d.ts +3 -0
  27. package/dist/adapters/codex/instruction-template.js +12 -0
  28. package/dist/adapters/codex/instruction-template.js.map +1 -0
  29. package/dist/adapters/codex/mcp-server.d.ts +59 -41
  30. package/dist/adapters/codex/mcp-server.js +177 -728
  31. package/dist/adapters/codex/mcp-server.js.map +1 -1
  32. package/dist/analyzer/candidate-signals.d.ts +3 -1
  33. package/dist/analyzer/candidate-signals.js +159 -0
  34. package/dist/analyzer/candidate-signals.js.map +1 -1
  35. package/dist/analyzer/experience-analyzer.d.ts +0 -0
  36. package/dist/analyzer/experience-analyzer.js +0 -0
  37. package/dist/analyzer/experience-analyzer.js.map +0 -0
  38. package/dist/analyzer/extraction-evidence.d.ts +0 -0
  39. package/dist/analyzer/extraction-evidence.js +0 -0
  40. package/dist/analyzer/extraction-evidence.js.map +0 -0
  41. package/dist/analyzer/llm-learning-gate.d.ts +12 -1
  42. package/dist/analyzer/llm-learning-gate.js +672 -16
  43. package/dist/analyzer/llm-learning-gate.js.map +1 -1
  44. package/dist/analyzer/node-deduper.d.ts +0 -0
  45. package/dist/analyzer/node-deduper.js +0 -0
  46. package/dist/analyzer/node-deduper.js.map +0 -0
  47. package/dist/analyzer/node-normalizer.d.ts +0 -0
  48. package/dist/analyzer/node-normalizer.js +0 -0
  49. package/dist/analyzer/node-normalizer.js.map +0 -0
  50. package/dist/analyzer/storage-gate.d.ts +0 -0
  51. package/dist/analyzer/storage-gate.js +0 -0
  52. package/dist/analyzer/storage-gate.js.map +0 -0
  53. package/dist/analyzer/strategy-extractor.d.ts +0 -0
  54. package/dist/analyzer/strategy-extractor.js +0 -0
  55. package/dist/analyzer/strategy-extractor.js.map +0 -0
  56. package/dist/analyzer/warning-extractor.d.ts +0 -0
  57. package/dist/analyzer/warning-extractor.js +0 -0
  58. package/dist/analyzer/warning-extractor.js.map +0 -0
  59. package/dist/cli/commands/backup.d.ts +0 -0
  60. package/dist/cli/commands/backup.js +0 -0
  61. package/dist/cli/commands/backup.js.map +0 -0
  62. package/dist/cli/commands/claude-hook.d.ts +0 -0
  63. package/dist/cli/commands/claude-hook.js +23 -7
  64. package/dist/cli/commands/claude-hook.js.map +1 -1
  65. package/dist/cli/commands/codex-mcp-server.d.ts +0 -0
  66. package/dist/cli/commands/codex-mcp-server.js +0 -0
  67. package/dist/cli/commands/codex-mcp-server.js.map +0 -0
  68. package/dist/cli/commands/codex.d.ts +60 -0
  69. package/dist/cli/commands/codex.js +188 -0
  70. package/dist/cli/commands/codex.js.map +1 -0
  71. package/dist/cli/commands/config.d.ts +0 -0
  72. package/dist/cli/commands/config.js +88 -2
  73. package/dist/cli/commands/config.js.map +1 -1
  74. package/dist/cli/commands/cool.d.ts +0 -0
  75. package/dist/cli/commands/cool.js +0 -0
  76. package/dist/cli/commands/cool.js.map +0 -0
  77. package/dist/cli/commands/disable.d.ts +0 -0
  78. package/dist/cli/commands/disable.js +0 -0
  79. package/dist/cli/commands/disable.js.map +0 -0
  80. package/dist/cli/commands/doctor.d.ts +4 -28
  81. package/dist/cli/commands/doctor.js +156 -68
  82. package/dist/cli/commands/doctor.js.map +1 -1
  83. package/dist/cli/commands/enable.d.ts +0 -0
  84. package/dist/cli/commands/enable.js +0 -0
  85. package/dist/cli/commands/enable.js.map +0 -0
  86. package/dist/cli/commands/evaluate.d.ts +9 -3
  87. package/dist/cli/commands/evaluate.js +31 -5
  88. package/dist/cli/commands/evaluate.js.map +1 -1
  89. package/dist/cli/commands/export.d.ts +0 -0
  90. package/dist/cli/commands/export.js +0 -0
  91. package/dist/cli/commands/export.js.map +0 -0
  92. package/dist/cli/commands/feedback.d.ts +0 -0
  93. package/dist/cli/commands/feedback.js +4 -0
  94. package/dist/cli/commands/feedback.js.map +1 -1
  95. package/dist/cli/commands/import.d.ts +0 -0
  96. package/dist/cli/commands/import.js +0 -0
  97. package/dist/cli/commands/import.js.map +0 -0
  98. package/dist/cli/commands/init.d.ts +28 -0
  99. package/dist/cli/commands/init.js +432 -0
  100. package/dist/cli/commands/init.js.map +1 -0
  101. package/dist/cli/commands/inspect.d.ts +0 -0
  102. package/dist/cli/commands/inspect.js +271 -37
  103. package/dist/cli/commands/inspect.js.map +1 -1
  104. package/dist/cli/commands/install.d.ts +0 -0
  105. package/dist/cli/commands/install.js +9 -0
  106. package/dist/cli/commands/install.js.map +1 -1
  107. package/dist/cli/commands/maintenance.d.ts +0 -0
  108. package/dist/cli/commands/maintenance.js +1 -1
  109. package/dist/cli/commands/maintenance.js.map +1 -1
  110. package/dist/cli/commands/mcp-server.d.ts +0 -0
  111. package/dist/cli/commands/mcp-server.js +4 -0
  112. package/dist/cli/commands/mcp-server.js.map +1 -1
  113. package/dist/cli/commands/models.d.ts +0 -0
  114. package/dist/cli/commands/models.js +0 -0
  115. package/dist/cli/commands/models.js.map +0 -0
  116. package/dist/cli/commands/repair.d.ts +0 -0
  117. package/dist/cli/commands/repair.js +3 -3
  118. package/dist/cli/commands/repair.js.map +1 -1
  119. package/dist/cli/commands/retire.d.ts +0 -0
  120. package/dist/cli/commands/retire.js +0 -0
  121. package/dist/cli/commands/retire.js.map +0 -0
  122. package/dist/cli/commands/rollback.d.ts +0 -0
  123. package/dist/cli/commands/rollback.js +0 -0
  124. package/dist/cli/commands/rollback.js.map +0 -0
  125. package/dist/cli/commands/stats.d.ts +0 -0
  126. package/dist/cli/commands/stats.js +0 -0
  127. package/dist/cli/commands/stats.js.map +0 -0
  128. package/dist/cli/commands/status.d.ts +0 -0
  129. package/dist/cli/commands/status.js +89 -7
  130. package/dist/cli/commands/status.js.map +1 -1
  131. package/dist/cli/commands/upgrade.d.ts +0 -0
  132. package/dist/cli/commands/upgrade.js +0 -0
  133. package/dist/cli/commands/upgrade.js.map +0 -0
  134. package/dist/cli/dispatch.d.ts +0 -0
  135. package/dist/cli/dispatch.js +36 -9
  136. package/dist/cli/dispatch.js.map +1 -1
  137. package/dist/cli/index.d.ts +0 -0
  138. package/dist/cli/index.js.map +0 -0
  139. package/dist/cli/state-model.d.ts +14 -0
  140. package/dist/cli/state-model.js +23 -0
  141. package/dist/cli/state-model.js.map +1 -0
  142. package/dist/config/config-schema.d.ts +209 -0
  143. package/dist/config/config-schema.js +168 -1
  144. package/dist/config/config-schema.js.map +1 -1
  145. package/dist/config/default-config.d.ts +0 -0
  146. package/dist/config/default-config.js +22 -1
  147. package/dist/config/default-config.js.map +1 -1
  148. package/dist/config/load-config.d.ts +0 -0
  149. package/dist/config/load-config.js +91 -2
  150. package/dist/config/load-config.js.map +1 -1
  151. package/dist/config/path-resolver.d.ts +0 -1
  152. package/dist/config/path-resolver.js +0 -2
  153. package/dist/config/path-resolver.js.map +1 -1
  154. package/dist/config/runtime-env.d.ts +8 -0
  155. package/dist/config/runtime-env.js +14 -0
  156. package/dist/config/runtime-env.js.map +1 -0
  157. package/dist/config/secrets-store.d.ts +15 -0
  158. package/dist/config/secrets-store.js +56 -0
  159. package/dist/config/secrets-store.js.map +1 -0
  160. package/dist/config/settings-store.d.ts +29 -0
  161. package/dist/config/settings-store.js +55 -0
  162. package/dist/config/settings-store.js.map +1 -1
  163. package/dist/controller/candidate-retriever.d.ts +49 -2
  164. package/dist/controller/candidate-retriever.js +258 -125
  165. package/dist/controller/candidate-retriever.js.map +1 -1
  166. package/dist/controller/injection-renderer.d.ts +0 -0
  167. package/dist/controller/injection-renderer.js +52 -1
  168. package/dist/controller/injection-renderer.js.map +1 -1
  169. package/dist/controller/injection-scorecard.d.ts +2 -2
  170. package/dist/controller/injection-scorecard.js +47 -1
  171. package/dist/controller/injection-scorecard.js.map +1 -1
  172. package/dist/controller/inline-notice.d.ts +0 -0
  173. package/dist/controller/inline-notice.js +0 -0
  174. package/dist/controller/inline-notice.js.map +0 -0
  175. package/dist/controller/intervention-controller.d.ts +3 -2
  176. package/dist/controller/intervention-controller.js +339 -17
  177. package/dist/controller/intervention-controller.js.map +1 -1
  178. package/dist/controller/lexical-retriever.d.ts +14 -0
  179. package/dist/controller/lexical-retriever.js +117 -0
  180. package/dist/controller/lexical-retriever.js.map +1 -0
  181. package/dist/controller/model-reranker.d.ts +20 -0
  182. package/dist/controller/model-reranker.js +187 -0
  183. package/dist/controller/model-reranker.js.map +1 -0
  184. package/dist/controller/node-ranker.d.ts +0 -0
  185. package/dist/controller/node-ranker.js +1 -0
  186. package/dist/controller/node-ranker.js.map +1 -1
  187. package/dist/controller/policy-enricher.d.ts +10 -0
  188. package/dist/controller/policy-enricher.js +186 -0
  189. package/dist/controller/policy-enricher.js.map +1 -0
  190. package/dist/controller/query-rewrite.d.ts +8 -0
  191. package/dist/controller/query-rewrite.js +69 -0
  192. package/dist/controller/query-rewrite.js.map +1 -0
  193. package/dist/controller/retrieval-context.d.ts +3 -0
  194. package/dist/controller/retrieval-context.js +37 -0
  195. package/dist/controller/retrieval-context.js.map +1 -0
  196. package/dist/controller/second-opinion-gate.d.ts +41 -0
  197. package/dist/controller/second-opinion-gate.js +225 -0
  198. package/dist/controller/second-opinion-gate.js.map +1 -0
  199. package/dist/controller/trigger-evaluator.d.ts +27 -2
  200. package/dist/controller/trigger-evaluator.js +63 -3
  201. package/dist/controller/trigger-evaluator.js.map +1 -1
  202. package/dist/distillation/errors.d.ts +0 -0
  203. package/dist/distillation/errors.js +0 -0
  204. package/dist/distillation/errors.js.map +0 -0
  205. package/dist/distillation/experience-family.d.ts +4 -0
  206. package/dist/distillation/experience-family.js +14 -0
  207. package/dist/distillation/experience-family.js.map +1 -0
  208. package/dist/distillation/host-llm.d.ts +1 -0
  209. package/dist/distillation/host-llm.js +5 -1
  210. package/dist/distillation/host-llm.js.map +1 -1
  211. package/dist/distillation/llm-distiller.d.ts +0 -0
  212. package/dist/distillation/llm-distiller.js +4 -0
  213. package/dist/distillation/llm-distiller.js.map +1 -1
  214. package/dist/distillation/merge-decider.d.ts +0 -0
  215. package/dist/distillation/merge-decider.js +4 -0
  216. package/dist/distillation/merge-decider.js.map +1 -1
  217. package/dist/distillation/model-catalog.d.ts +0 -0
  218. package/dist/distillation/model-catalog.js +0 -0
  219. package/dist/distillation/model-catalog.js.map +0 -0
  220. package/dist/distillation/prompt-contract.d.ts +1 -1
  221. package/dist/distillation/prompt-contract.js +6 -1
  222. package/dist/distillation/prompt-contract.js.map +1 -1
  223. package/dist/distillation/providers/anthropic.d.ts +0 -0
  224. package/dist/distillation/providers/anthropic.js +0 -0
  225. package/dist/distillation/providers/anthropic.js.map +0 -0
  226. package/dist/distillation/providers/azure-openai.d.ts +0 -0
  227. package/dist/distillation/providers/azure-openai.js +0 -0
  228. package/dist/distillation/providers/azure-openai.js.map +0 -0
  229. package/dist/distillation/providers/baidu-qianfan.d.ts +0 -0
  230. package/dist/distillation/providers/baidu-qianfan.js +0 -0
  231. package/dist/distillation/providers/baidu-qianfan.js.map +0 -0
  232. package/dist/distillation/providers/bedrock.d.ts +0 -0
  233. package/dist/distillation/providers/bedrock.js +0 -0
  234. package/dist/distillation/providers/bedrock.js.map +0 -0
  235. package/dist/distillation/providers/dashscope.d.ts +0 -0
  236. package/dist/distillation/providers/dashscope.js +0 -0
  237. package/dist/distillation/providers/dashscope.js.map +0 -0
  238. package/dist/distillation/providers/deepseek.d.ts +0 -0
  239. package/dist/distillation/providers/deepseek.js +0 -0
  240. package/dist/distillation/providers/deepseek.js.map +0 -0
  241. package/dist/distillation/providers/gemini.d.ts +0 -0
  242. package/dist/distillation/providers/gemini.js +5 -1
  243. package/dist/distillation/providers/gemini.js.map +1 -1
  244. package/dist/distillation/providers/google-adc.d.ts +0 -0
  245. package/dist/distillation/providers/google-adc.js +0 -0
  246. package/dist/distillation/providers/google-adc.js.map +0 -0
  247. package/dist/distillation/providers/minimax.d.ts +0 -0
  248. package/dist/distillation/providers/minimax.js +0 -0
  249. package/dist/distillation/providers/minimax.js.map +0 -0
  250. package/dist/distillation/providers/moonshot.d.ts +0 -0
  251. package/dist/distillation/providers/moonshot.js +0 -0
  252. package/dist/distillation/providers/moonshot.js.map +0 -0
  253. package/dist/distillation/providers/openai-compatible-factory.d.ts +0 -0
  254. package/dist/distillation/providers/openai-compatible-factory.js +0 -0
  255. package/dist/distillation/providers/openai-compatible-factory.js.map +0 -0
  256. package/dist/distillation/providers/openai-compatible.d.ts +0 -0
  257. package/dist/distillation/providers/openai-compatible.js +0 -0
  258. package/dist/distillation/providers/openai-compatible.js.map +0 -0
  259. package/dist/distillation/providers/openai.d.ts +0 -0
  260. package/dist/distillation/providers/openai.js +0 -0
  261. package/dist/distillation/providers/openai.js.map +0 -0
  262. package/dist/distillation/providers/openrouter.d.ts +0 -0
  263. package/dist/distillation/providers/openrouter.js +0 -0
  264. package/dist/distillation/providers/openrouter.js.map +0 -0
  265. package/dist/distillation/providers/registry.d.ts +0 -0
  266. package/dist/distillation/providers/registry.js +0 -0
  267. package/dist/distillation/providers/registry.js.map +0 -0
  268. package/dist/distillation/providers/siliconflow.d.ts +0 -0
  269. package/dist/distillation/providers/siliconflow.js +0 -0
  270. package/dist/distillation/providers/siliconflow.js.map +0 -0
  271. package/dist/distillation/providers/tencent-hunyuan.d.ts +0 -0
  272. package/dist/distillation/providers/tencent-hunyuan.js +0 -0
  273. package/dist/distillation/providers/tencent-hunyuan.js.map +0 -0
  274. package/dist/distillation/providers/types.d.ts +0 -0
  275. package/dist/distillation/providers/types.js +0 -0
  276. package/dist/distillation/providers/types.js.map +0 -0
  277. package/dist/distillation/providers/volcengine-ark.d.ts +0 -0
  278. package/dist/distillation/providers/volcengine-ark.js +0 -0
  279. package/dist/distillation/providers/volcengine-ark.js.map +0 -0
  280. package/dist/distillation/providers/zhipu.d.ts +0 -0
  281. package/dist/distillation/providers/zhipu.js +0 -0
  282. package/dist/distillation/providers/zhipu.js.map +0 -0
  283. package/dist/distillation/queue-worker.d.ts +0 -0
  284. package/dist/distillation/queue-worker.js +78 -9
  285. package/dist/distillation/queue-worker.js.map +1 -1
  286. package/dist/distillation/types.d.ts +0 -0
  287. package/dist/distillation/types.js +0 -0
  288. package/dist/distillation/types.js.map +0 -0
  289. package/dist/evaluation/benchmark-report.d.ts +0 -0
  290. package/dist/evaluation/benchmark-report.js +0 -0
  291. package/dist/evaluation/benchmark-report.js.map +0 -0
  292. package/dist/evaluation/benchmark-summary.d.ts +0 -0
  293. package/dist/evaluation/benchmark-summary.js +0 -0
  294. package/dist/evaluation/benchmark-summary.js.map +0 -0
  295. package/dist/evaluation/codex-lifecycle-validation.d.ts +60 -0
  296. package/dist/evaluation/codex-lifecycle-validation.js +233 -0
  297. package/dist/evaluation/codex-lifecycle-validation.js.map +1 -0
  298. package/dist/evaluation/hybrid-phase1-rollout-summary.d.ts +63 -0
  299. package/dist/evaluation/hybrid-phase1-rollout-summary.js +108 -0
  300. package/dist/evaluation/hybrid-phase1-rollout-summary.js.map +1 -0
  301. package/dist/evaluation/hybrid-phase3-gate-metrics.d.ts +26 -0
  302. package/dist/evaluation/hybrid-phase3-gate-metrics.js +23 -0
  303. package/dist/evaluation/hybrid-phase3-gate-metrics.js.map +1 -0
  304. package/dist/evaluation/openclaw-baseline.d.ts +8 -0
  305. package/dist/evaluation/openclaw-baseline.js +27 -0
  306. package/dist/evaluation/openclaw-baseline.js.map +1 -1
  307. package/dist/evaluation/openclaw-scenarios.d.ts +0 -0
  308. package/dist/evaluation/openclaw-scenarios.js +0 -0
  309. package/dist/evaluation/openclaw-scenarios.js.map +0 -0
  310. package/dist/experience-management/governance-observability.d.ts +13 -0
  311. package/dist/experience-management/governance-observability.js +37 -0
  312. package/dist/experience-management/governance-observability.js.map +1 -0
  313. package/dist/experience-management/node-lifecycle-governance.d.ts +8 -0
  314. package/dist/experience-management/node-lifecycle-governance.js +80 -0
  315. package/dist/experience-management/node-lifecycle-governance.js.map +1 -0
  316. package/dist/experience-management/task-management-signals.d.ts +29 -0
  317. package/dist/experience-management/task-management-signals.js +148 -0
  318. package/dist/experience-management/task-management-signals.js.map +1 -0
  319. package/dist/feedback/automatic-attribution.d.ts +0 -0
  320. package/dist/feedback/automatic-attribution.js +0 -0
  321. package/dist/feedback/automatic-attribution.js.map +0 -0
  322. package/dist/feedback/feedback-manager.d.ts +4 -1
  323. package/dist/feedback/feedback-manager.js +11 -22
  324. package/dist/feedback/feedback-manager.js.map +1 -1
  325. package/dist/feedback/harm-detector.d.ts +0 -0
  326. package/dist/feedback/harm-detector.js +0 -0
  327. package/dist/feedback/harm-detector.js.map +0 -0
  328. package/dist/feedback/state-transition.d.ts +6 -1
  329. package/dist/feedback/state-transition.js +14 -2
  330. package/dist/feedback/state-transition.js.map +1 -1
  331. package/dist/feedback/stats-updater.d.ts +0 -0
  332. package/dist/feedback/stats-updater.js +0 -0
  333. package/dist/feedback/stats-updater.js.map +0 -0
  334. package/dist/hybrid/capsule-builder.d.ts +23 -0
  335. package/dist/hybrid/capsule-builder.js +114 -0
  336. package/dist/hybrid/capsule-builder.js.map +1 -0
  337. package/dist/hybrid/explain-provider-client.d.ts +19 -0
  338. package/dist/hybrid/explain-provider-client.js +34 -0
  339. package/dist/hybrid/explain-provider-client.js.map +1 -0
  340. package/dist/hybrid/postmortem-provider-client.d.ts +19 -0
  341. package/dist/hybrid/postmortem-provider-client.js +34 -0
  342. package/dist/hybrid/postmortem-provider-client.js.map +1 -0
  343. package/dist/hybrid/rollout.d.ts +9 -0
  344. package/dist/hybrid/rollout.js +49 -0
  345. package/dist/hybrid/rollout.js.map +1 -0
  346. package/dist/hybrid/router.d.ts +4 -0
  347. package/dist/hybrid/router.js +62 -0
  348. package/dist/hybrid/router.js.map +1 -0
  349. package/dist/hybrid/types.d.ts +140 -0
  350. package/dist/{compiler → hybrid}/types.js +0 -0
  351. package/dist/{packs → hybrid}/types.js.map +1 -1
  352. package/dist/hybrid/validators.d.ts +5 -0
  353. package/dist/hybrid/validators.js +94 -0
  354. package/dist/hybrid/validators.js.map +1 -0
  355. package/dist/hybrid/worker-client.d.ts +61 -0
  356. package/dist/hybrid/worker-client.js +196 -0
  357. package/dist/hybrid/worker-client.js.map +1 -0
  358. package/dist/hybrid/workers/explain-decision-llm.d.ts +8 -0
  359. package/dist/hybrid/workers/explain-decision-llm.js +152 -0
  360. package/dist/hybrid/workers/explain-decision-llm.js.map +1 -0
  361. package/dist/hybrid/workers/explain-decision.d.ts +2 -0
  362. package/dist/hybrid/workers/explain-decision.js +40 -0
  363. package/dist/hybrid/workers/explain-decision.js.map +1 -0
  364. package/dist/hybrid/workers/postmortem-review-llm.d.ts +8 -0
  365. package/dist/hybrid/workers/postmortem-review-llm.js +398 -0
  366. package/dist/hybrid/workers/postmortem-review-llm.js.map +1 -0
  367. package/dist/hybrid/workers/postmortem-review.d.ts +2 -0
  368. package/dist/hybrid/workers/postmortem-review.js +66 -0
  369. package/dist/hybrid/workers/postmortem-review.js.map +1 -0
  370. package/dist/index.d.ts +0 -0
  371. package/dist/index.js +0 -0
  372. package/dist/index.js.map +0 -0
  373. package/dist/input/context-summary-adapter.d.ts +0 -0
  374. package/dist/input/context-summary-adapter.js +0 -0
  375. package/dist/input/context-summary-adapter.js.map +0 -0
  376. package/dist/input/input-adapter.d.ts +0 -0
  377. package/dist/input/input-adapter.js +2 -1
  378. package/dist/input/input-adapter.js.map +1 -1
  379. package/dist/input/outcome-resolver.d.ts +0 -0
  380. package/dist/input/outcome-resolver.js +5 -5
  381. package/dist/input/outcome-resolver.js.map +1 -1
  382. package/dist/input/scope-resolver.d.ts +0 -0
  383. package/dist/input/scope-resolver.js +0 -0
  384. package/dist/input/scope-resolver.js.map +0 -0
  385. package/dist/input/tasktype-resolver.d.ts +0 -0
  386. package/dist/input/tasktype-resolver.js +2 -0
  387. package/dist/input/tasktype-resolver.js.map +1 -1
  388. package/dist/input/tool-event-significance.d.ts +5 -0
  389. package/dist/input/tool-event-significance.js +7 -0
  390. package/dist/input/tool-event-significance.js.map +1 -0
  391. package/dist/install/claude-cli.d.ts +0 -0
  392. package/dist/install/claude-cli.js +0 -0
  393. package/dist/install/claude-cli.js.map +0 -0
  394. package/dist/install/claude-code-doctor.d.ts +8 -2
  395. package/dist/install/claude-code-doctor.js +54 -9
  396. package/dist/install/claude-code-doctor.js.map +1 -1
  397. package/dist/install/claude-code-installer.d.ts +0 -0
  398. package/dist/install/claude-code-installer.js +50 -1
  399. package/dist/install/claude-code-installer.js.map +1 -1
  400. package/dist/install/claude-marketplace-state.d.ts +14 -0
  401. package/dist/install/claude-marketplace-state.js +47 -0
  402. package/dist/install/claude-marketplace-state.js.map +1 -0
  403. package/dist/install/claude-runtime-target.d.ts +0 -0
  404. package/dist/install/claude-runtime-target.js +0 -0
  405. package/dist/install/claude-runtime-target.js.map +0 -0
  406. package/dist/install/codex-cli.d.ts +15 -0
  407. package/dist/install/codex-cli.js +55 -3
  408. package/dist/install/codex-cli.js.map +1 -1
  409. package/dist/install/codex-installer.d.ts +18 -0
  410. package/dist/install/codex-installer.js +91 -1
  411. package/dist/install/codex-installer.js.map +1 -1
  412. package/dist/install/codex-runtime-target.d.ts +0 -0
  413. package/dist/install/codex-runtime-target.js +0 -0
  414. package/dist/install/codex-runtime-target.js.map +0 -0
  415. package/dist/install/host-detection.d.ts +0 -0
  416. package/dist/install/host-detection.js +0 -0
  417. package/dist/install/host-detection.js.map +0 -0
  418. package/dist/install/openclaw-cli.d.ts +11 -0
  419. package/dist/install/openclaw-cli.js +0 -0
  420. package/dist/install/openclaw-cli.js.map +1 -1
  421. package/dist/install/openclaw-installer.d.ts +12 -0
  422. package/dist/install/openclaw-installer.js +198 -31
  423. package/dist/install/openclaw-installer.js.map +1 -1
  424. package/dist/install/public-install.d.ts +14 -4
  425. package/dist/install/public-install.js +20 -7
  426. package/dist/install/public-install.js.map +1 -1
  427. package/dist/install/registry-health.d.ts +0 -0
  428. package/dist/install/registry-health.js +0 -0
  429. package/dist/install/registry-health.js.map +0 -0
  430. package/dist/interaction/operational-actions-service.d.ts +0 -0
  431. package/dist/interaction/operational-actions-service.js +0 -0
  432. package/dist/interaction/operational-actions-service.js.map +0 -0
  433. package/dist/interaction/operational-service.d.ts +0 -0
  434. package/dist/interaction/operational-service.js +0 -0
  435. package/dist/interaction/operational-service.js.map +0 -0
  436. package/dist/interaction/repo-summary.d.ts +3 -17
  437. package/dist/interaction/repo-summary.js +10 -27
  438. package/dist/interaction/repo-summary.js.map +1 -1
  439. package/dist/interaction/service.d.ts +59 -95
  440. package/dist/interaction/service.js +505 -266
  441. package/dist/interaction/service.js.map +1 -1
  442. package/dist/interaction/state-artifact-service.d.ts +0 -0
  443. package/dist/interaction/state-artifact-service.js +0 -0
  444. package/dist/interaction/state-artifact-service.js.map +0 -0
  445. package/dist/maintenance/claude-validate-print.d.ts +0 -0
  446. package/dist/maintenance/claude-validate-print.js +0 -0
  447. package/dist/maintenance/claude-validate-print.js.map +0 -0
  448. package/dist/maintenance/embedding-smoke.d.ts +0 -0
  449. package/dist/maintenance/embedding-smoke.js +0 -0
  450. package/dist/maintenance/embedding-smoke.js.map +0 -0
  451. package/dist/maintenance/redistill-rule-nodes.d.ts +0 -0
  452. package/dist/maintenance/redistill-rule-nodes.js +0 -0
  453. package/dist/maintenance/redistill-rule-nodes.js.map +0 -0
  454. package/dist/maintenance/scope-merge.d.ts +0 -1
  455. package/dist/maintenance/scope-merge.js +0 -20
  456. package/dist/maintenance/scope-merge.js.map +1 -1
  457. package/dist/maintenance/warning-variant-cleanup.d.ts +0 -0
  458. package/dist/maintenance/warning-variant-cleanup.js +0 -0
  459. package/dist/maintenance/warning-variant-cleanup.js.map +0 -0
  460. package/dist/plugin/fixture-sanitizer.d.ts +0 -0
  461. package/dist/plugin/fixture-sanitizer.js +0 -0
  462. package/dist/plugin/fixture-sanitizer.js.map +0 -0
  463. package/dist/plugin/hooks/before-prompt-build.d.ts +1 -0
  464. package/dist/plugin/hooks/before-prompt-build.js +4 -1
  465. package/dist/plugin/hooks/before-prompt-build.js.map +1 -1
  466. package/dist/plugin/hooks/message-sent.d.ts +0 -0
  467. package/dist/plugin/hooks/message-sent.js +0 -0
  468. package/dist/plugin/hooks/message-sent.js.map +0 -0
  469. package/dist/plugin/hooks/tool-result-persist.d.ts +0 -0
  470. package/dist/plugin/hooks/tool-result-persist.js +0 -0
  471. package/dist/plugin/hooks/tool-result-persist.js.map +0 -0
  472. package/dist/plugin/openclaw-install-state.d.ts +39 -0
  473. package/dist/plugin/openclaw-install-state.js +24 -0
  474. package/dist/plugin/openclaw-install-state.js.map +1 -0
  475. package/dist/plugin/openclaw-plugin.d.ts +148 -0
  476. package/dist/plugin/openclaw-plugin.js +98 -7
  477. package/dist/plugin/openclaw-plugin.js.map +1 -1
  478. package/dist/plugin/openclaw-routine-interaction.d.ts +7 -0
  479. package/dist/plugin/openclaw-routine-interaction.js +301 -0
  480. package/dist/plugin/openclaw-routine-interaction.js.map +1 -0
  481. package/dist/plugin/openclaw-runtime-defaults.d.ts +16 -0
  482. package/dist/plugin/openclaw-runtime-defaults.js +16 -0
  483. package/dist/plugin/openclaw-runtime-defaults.js.map +1 -0
  484. package/dist/plugin/runtime-capture.d.ts +0 -0
  485. package/dist/plugin/runtime-capture.js +0 -0
  486. package/dist/plugin/runtime-capture.js.map +0 -0
  487. package/dist/plugin/runtime-helpers.d.ts +0 -0
  488. package/dist/plugin/runtime-helpers.js +0 -0
  489. package/dist/plugin/runtime-helpers.js.map +0 -0
  490. package/dist/runtime/service.d.ts +33 -6
  491. package/dist/runtime/service.js +427 -50
  492. package/dist/runtime/service.js.map +1 -1
  493. package/dist/store/logs/jsonl-logger.d.ts +0 -0
  494. package/dist/store/logs/jsonl-logger.js +0 -0
  495. package/dist/store/logs/jsonl-logger.js.map +0 -0
  496. package/dist/store/sqlite/db.d.ts +0 -0
  497. package/dist/store/sqlite/db.js +37 -0
  498. package/dist/store/sqlite/db.js.map +1 -1
  499. package/dist/store/sqlite/migrations.d.ts +0 -0
  500. package/dist/store/sqlite/migrations.js +0 -0
  501. package/dist/store/sqlite/migrations.js.map +0 -0
  502. package/dist/store/sqlite/repositories/candidate-repo.d.ts +0 -0
  503. package/dist/store/sqlite/repositories/candidate-repo.js +8 -2
  504. package/dist/store/sqlite/repositories/candidate-repo.js.map +1 -1
  505. package/dist/store/sqlite/repositories/distillation-job-repo.d.ts +0 -0
  506. package/dist/store/sqlite/repositories/distillation-job-repo.js +0 -0
  507. package/dist/store/sqlite/repositories/distillation-job-repo.js.map +0 -0
  508. package/dist/store/sqlite/repositories/hybrid-invocation-trace-repo.d.ts +11 -0
  509. package/dist/store/sqlite/repositories/hybrid-invocation-trace-repo.js +76 -0
  510. package/dist/store/sqlite/repositories/hybrid-invocation-trace-repo.js.map +1 -0
  511. package/dist/store/sqlite/repositories/hybrid-review-artifact-repo.d.ts +11 -0
  512. package/dist/store/sqlite/repositories/hybrid-review-artifact-repo.js +73 -0
  513. package/dist/store/sqlite/repositories/hybrid-review-artifact-repo.js.map +1 -0
  514. package/dist/store/sqlite/repositories/injection-repo.d.ts +1 -0
  515. package/dist/store/sqlite/repositories/injection-repo.js +11 -0
  516. package/dist/store/sqlite/repositories/injection-repo.js.map +1 -1
  517. package/dist/store/sqlite/repositories/input-record-repo.d.ts +3 -0
  518. package/dist/store/sqlite/repositories/input-record-repo.js +35 -0
  519. package/dist/store/sqlite/repositories/input-record-repo.js.map +1 -1
  520. package/dist/store/sqlite/repositories/node-repo.d.ts +3 -0
  521. package/dist/store/sqlite/repositories/node-repo.js +62 -8
  522. package/dist/store/sqlite/repositories/node-repo.js.map +1 -1
  523. package/dist/store/sqlite/repositories/outcome-record-repo.d.ts +0 -0
  524. package/dist/store/sqlite/repositories/outcome-record-repo.js +0 -0
  525. package/dist/store/sqlite/repositories/outcome-record-repo.js.map +0 -0
  526. package/dist/store/sqlite/repositories/review-event-repo.d.ts +0 -0
  527. package/dist/store/sqlite/repositories/review-event-repo.js +0 -0
  528. package/dist/store/sqlite/repositories/review-event-repo.js.map +0 -0
  529. package/dist/store/sqlite/repositories/scope-repo.d.ts +0 -0
  530. package/dist/store/sqlite/repositories/scope-repo.js +0 -0
  531. package/dist/store/sqlite/repositories/scope-repo.js.map +0 -0
  532. package/dist/store/sqlite/repositories/stats-repo.d.ts +0 -0
  533. package/dist/store/sqlite/repositories/stats-repo.js +0 -0
  534. package/dist/store/sqlite/repositories/stats-repo.js.map +0 -0
  535. package/dist/store/sqlite/repositories/task-run-repo.d.ts +2 -0
  536. package/dist/store/sqlite/repositories/task-run-repo.js +18 -2
  537. package/dist/store/sqlite/repositories/task-run-repo.js.map +1 -1
  538. package/dist/store/sqlite/schema.sql +49 -49
  539. package/dist/store/vector/api-embedding-provider.d.ts +2 -0
  540. package/dist/store/vector/api-embedding-provider.js +23 -19
  541. package/dist/store/vector/api-embedding-provider.js.map +1 -1
  542. package/dist/store/vector/embeddings.d.ts +1 -1
  543. package/dist/store/vector/embeddings.js +26 -5
  544. package/dist/store/vector/embeddings.js.map +1 -1
  545. package/dist/store/vector/lancedb.d.ts +0 -0
  546. package/dist/store/vector/lancedb.js +0 -0
  547. package/dist/store/vector/lancedb.js.map +0 -0
  548. package/dist/store/vector/local-provider.d.ts +0 -0
  549. package/dist/store/vector/local-provider.js +0 -0
  550. package/dist/store/vector/local-provider.js.map +0 -0
  551. package/dist/store/vector/node-index.d.ts +0 -0
  552. package/dist/store/vector/node-index.js +0 -0
  553. package/dist/store/vector/node-index.js.map +0 -0
  554. package/dist/store/vector/provider-types.d.ts +0 -0
  555. package/dist/store/vector/provider-types.js +0 -0
  556. package/dist/store/vector/provider-types.js.map +0 -0
  557. package/dist/types/analyzer.d.ts +0 -0
  558. package/dist/types/analyzer.js +0 -0
  559. package/dist/types/analyzer.js.map +0 -0
  560. package/dist/types/domain.d.ts +166 -47
  561. package/dist/types/domain.js +0 -0
  562. package/dist/types/domain.js.map +0 -0
  563. package/dist/types/plugin.d.ts +3 -1
  564. package/dist/types/plugin.js +0 -0
  565. package/dist/types/plugin.js.map +0 -0
  566. package/dist/types/storage.d.ts +0 -0
  567. package/dist/types/storage.js +0 -0
  568. package/dist/types/storage.js.map +0 -0
  569. package/dist/utils/clock.d.ts +0 -0
  570. package/dist/utils/clock.js +0 -0
  571. package/dist/utils/clock.js.map +0 -0
  572. package/dist/utils/errors.d.ts +0 -0
  573. package/dist/utils/errors.js +0 -0
  574. package/dist/utils/errors.js.map +0 -0
  575. package/dist/utils/hashing.d.ts +0 -0
  576. package/dist/utils/hashing.js +0 -0
  577. package/dist/utils/hashing.js.map +0 -0
  578. package/dist/utils/ids.d.ts +0 -0
  579. package/dist/utils/ids.js +0 -0
  580. package/dist/utils/ids.js.map +0 -0
  581. package/dist/utils/text.d.ts +0 -0
  582. package/dist/utils/text.js +0 -0
  583. package/dist/utils/text.js.map +0 -0
  584. package/dist/version/package-version.d.ts +0 -0
  585. package/dist/version/package-version.js +0 -0
  586. package/dist/version/package-version.js.map +0 -0
  587. package/dist/version/remote-release.d.ts +0 -0
  588. package/dist/version/remote-release.js +0 -0
  589. package/dist/version/remote-release.js.map +0 -0
  590. package/docs/releases/v0.1.0.md +0 -0
  591. package/docs/releases/v0.1.1.md +0 -0
  592. package/docs/releases/v0.1.2.md +3 -3
  593. package/docs/releases/v0.1.3.md +95 -0
  594. package/docs/releases/v0.2.0.md +85 -0
  595. package/docs/user-guide.md +263 -133
  596. package/hooks/hooks.json +0 -0
  597. package/openclaw.plugin.json +81 -1
  598. package/package.json +25 -16
  599. package/plugins/claude-code-experienceengine/.claude-plugin/plugin.json +1 -1
  600. package/plugins/claude-code-experienceengine/.mcp.json +4 -3
  601. package/plugins/claude-code-experienceengine/hooks/hooks.json +0 -0
  602. package/plugins/claude-code-experienceengine/scripts/claude-hook.sh +30 -1
  603. package/plugins/claude-code-experienceengine/scripts/install-deps.sh +41 -6
  604. package/scripts/claude-plugin/claude-hook.sh +0 -0
  605. package/scripts/claude-plugin/install-deps.sh +0 -0
  606. package/dist/cli/commands/pack.d.ts +0 -1
  607. package/dist/cli/commands/pack.js +0 -321
  608. package/dist/cli/commands/pack.js.map +0 -1
  609. package/dist/compiler/agents-renderer.d.ts +0 -4
  610. package/dist/compiler/agents-renderer.js +0 -105
  611. package/dist/compiler/agents-renderer.js.map +0 -1
  612. package/dist/compiler/claude-renderer.d.ts +0 -2
  613. package/dist/compiler/claude-renderer.js +0 -40
  614. package/dist/compiler/claude-renderer.js.map +0 -1
  615. package/dist/compiler/codex-renderer.d.ts +0 -2
  616. package/dist/compiler/codex-renderer.js +0 -40
  617. package/dist/compiler/codex-renderer.js.map +0 -1
  618. package/dist/compiler/compiler.d.ts +0 -4
  619. package/dist/compiler/compiler.js +0 -87
  620. package/dist/compiler/compiler.js.map +0 -1
  621. package/dist/compiler/deployer.d.ts +0 -21
  622. package/dist/compiler/deployer.js +0 -64
  623. package/dist/compiler/deployer.js.map +0 -1
  624. package/dist/compiler/github-renderer.d.ts +0 -2
  625. package/dist/compiler/github-renderer.js +0 -63
  626. package/dist/compiler/github-renderer.js.map +0 -1
  627. package/dist/compiler/types.d.ts +0 -45
  628. package/dist/compiler/types.js.map +0 -1
  629. package/dist/interaction/pack-actions-service.d.ts +0 -59
  630. package/dist/interaction/pack-actions-service.js +0 -172
  631. package/dist/interaction/pack-actions-service.js.map +0 -1
  632. package/dist/packs/fs-registry.d.ts +0 -27
  633. package/dist/packs/fs-registry.js +0 -216
  634. package/dist/packs/fs-registry.js.map +0 -1
  635. package/dist/packs/index-sync.d.ts +0 -9
  636. package/dist/packs/index-sync.js +0 -54
  637. package/dist/packs/index-sync.js.map +0 -1
  638. package/dist/packs/types.d.ts +0 -55
  639. package/dist/packs/types.js +0 -2
  640. package/dist/store/sqlite/repositories/pack-repo.d.ts +0 -16
  641. package/dist/store/sqlite/repositories/pack-repo.js +0 -192
  642. package/dist/store/sqlite/repositories/pack-repo.js.map +0 -1
@@ -1,4 +1,3 @@
1
- import { LlmLearningGate } from "../analyzer/llm-learning-gate.js";
2
1
  import { buildCandidateSignals } from "../analyzer/candidate-signals.js";
3
2
  import { buildInjectionScorecard } from "../controller/injection-scorecard.js";
4
3
  import { classifyFailureAttributionReason } from "../feedback/automatic-attribution.js";
@@ -6,13 +5,16 @@ import { applyFeedback } from "../feedback/feedback-manager.js";
6
5
  import { detectHarm } from "../feedback/harm-detector.js";
7
6
  import { createEmptyStats, updateStats } from "../feedback/stats-updater.js";
8
7
  import { buildExperienceInput } from "../input/input-adapter.js";
8
+ import { buildRetrievalContext } from "../controller/retrieval-context.js";
9
9
  import { resolveScope } from "../input/scope-resolver.js";
10
10
  import { decideIntervention } from "../controller/intervention-controller.js";
11
11
  import { renderInlineNotice } from "../controller/inline-notice.js";
12
+ import { applyGovernedNodeFeedback, deriveNodeOriginProfileForNode } from "../experience-management/node-lifecycle-governance.js";
13
+ import { resolveHybridRolloutState } from "../hybrid/rollout.js";
14
+ import { selectHybridRoute } from "../hybrid/router.js";
12
15
  import { nowIso } from "../utils/clock.js";
13
16
  import { createId, stableId } from "../utils/ids.js";
14
17
  import { bootstrapDatabase, openDatabase, withTransaction } from "../store/sqlite/db.js";
15
- import { DistillationQueueWorker } from "../distillation/queue-worker.js";
16
18
  import { CandidateRepository } from "../store/sqlite/repositories/candidate-repo.js";
17
19
  import { DistillationJobRepository } from "../store/sqlite/repositories/distillation-job-repo.js";
18
20
  import { InputRecordRepository } from "../store/sqlite/repositories/input-record-repo.js";
@@ -23,10 +25,16 @@ import { ScopeRepository } from "../store/sqlite/repositories/scope-repo.js";
23
25
  import { StatsRepository } from "../store/sqlite/repositories/stats-repo.js";
24
26
  import { TaskRunRepository } from "../store/sqlite/repositories/task-run-repo.js";
25
27
  import { InjectionRepository } from "../store/sqlite/repositories/injection-repo.js";
26
- import { ExperiencePackRepository } from "../store/sqlite/repositories/pack-repo.js";
28
+ import { HybridInvocationTraceRepository } from "../store/sqlite/repositories/hybrid-invocation-trace-repo.js";
27
29
  import { RuntimeCaptureWriter } from "../plugin/runtime-capture.js";
28
30
  import { normalizeToolResult } from "../plugin/hooks/tool-result-persist.js";
29
31
  import { extractToolResultsFromPayload } from "../plugin/runtime-helpers.js";
32
+ import { HybridReviewArtifactRepository } from "../store/sqlite/repositories/hybrid-review-artifact-repo.js";
33
+ const loadLlmLearningGate = async () => import("../analyzer/llm-learning-gate.js");
34
+ const loadDistillationQueueWorker = async () => import("../distillation/queue-worker.js");
35
+ const loadHybridWorkerClientModule = async () => import("../hybrid/worker-client.js");
36
+ const loadHybridCapsuleBuilder = async () => import("../hybrid/capsule-builder.js");
37
+ const loadHybridPostmortemProviderClient = async () => import("../hybrid/postmortem-provider-client.js");
30
38
  const toEvidence = (input) => input.tool_events.map((event) => [event.tool_name, event.status, event.error_signature ?? event.output_summary]
31
39
  .filter(Boolean)
32
40
  .join(": "));
@@ -47,7 +55,7 @@ const toTaskRun = (input, sessionId, context) => {
47
55
  const signals = buildCandidateSignals(input);
48
56
  return {
49
57
  id: stableId("taskrun", `${sessionId}:${input.task_summary}:${timestamp}`),
50
- host: "openclaw",
58
+ host: context.host ?? "openclaw",
51
59
  scope_id: input.scope_id,
52
60
  session_id: sessionId,
53
61
  task_type: input.task_type,
@@ -58,6 +66,8 @@ const toTaskRun = (input, sessionId, context) => {
58
66
  ended_at: timestamp,
59
67
  final_status: input.outcome_signal === "success" ? "success" : input.outcome_signal === "failure" ? "failure" : "unknown",
60
68
  failure_signature: signals.failure_signature,
69
+ learning_status: undefined,
70
+ learning_reason: undefined,
61
71
  created_at: timestamp,
62
72
  updated_at: timestamp
63
73
  };
@@ -81,9 +91,57 @@ const buildCandidateSourceSignal = (input) => {
81
91
  failure_signature: signals.failure_signature,
82
92
  retry_count: signals.retry_count,
83
93
  correction_signals: signals.correction_signals,
94
+ directional_correction: signals.directional_correction,
95
+ evidence_driven_reversal: signals.evidence_driven_reversal,
84
96
  tool_event_summary: signals.tool_event_summary
85
97
  };
86
98
  };
99
+ const mergeDirectionalCorrectionIntoSourceSignal = (sourceSignal, draft) => {
100
+ const directionalCorrection = sourceSignal.directional_correction;
101
+ if (!directionalCorrection) {
102
+ return sourceSignal;
103
+ }
104
+ const semanticDetected = Boolean(draft.experience_kind === "expectation_correction" &&
105
+ draft.correction_category &&
106
+ draft.deviation_pattern &&
107
+ draft.corrected_constraint);
108
+ if (!semanticDetected) {
109
+ return sourceSignal;
110
+ }
111
+ return {
112
+ ...sourceSignal,
113
+ directional_correction: {
114
+ ...directionalCorrection,
115
+ semantic_detected: true,
116
+ correction_category: draft.correction_category,
117
+ deviation_pattern: draft.deviation_pattern,
118
+ corrected_constraint: draft.corrected_constraint
119
+ }
120
+ };
121
+ };
122
+ const mergeEvidenceDrivenReversalIntoSourceSignal = (sourceSignal, draft) => {
123
+ const reversal = sourceSignal.evidence_driven_reversal;
124
+ if (!reversal) {
125
+ return sourceSignal;
126
+ }
127
+ const semanticDetected = Boolean(draft.experience_kind === "expectation_correction" &&
128
+ draft.correction_category &&
129
+ draft.deviation_pattern &&
130
+ draft.corrected_constraint);
131
+ if (!semanticDetected) {
132
+ return sourceSignal;
133
+ }
134
+ return {
135
+ ...sourceSignal,
136
+ evidence_driven_reversal: {
137
+ ...reversal,
138
+ semantic_detected: true,
139
+ correction_category: draft.correction_category,
140
+ deviation_pattern: draft.deviation_pattern,
141
+ corrected_constraint: draft.corrected_constraint
142
+ }
143
+ };
144
+ };
87
145
  const summarizeRawCandidate = (sourceSignal) => {
88
146
  const fragments = [...sourceSignal.tool_event_summary];
89
147
  if (sourceSignal.failure_signature) {
@@ -103,9 +161,14 @@ const resolveCandidateKind = (input, sourceSignal) => {
103
161
  }
104
162
  return "failure";
105
163
  };
106
- const draftToCandidate = (draft, input, originRecordId, taskRunId) => {
164
+ const draftToCandidate = (draft, input, originRecordId, taskRunId, directionalCorrectionSignal, evidenceDrivenReversalSignal) => {
107
165
  const timestamp = nowIso();
108
- const sourceSignal = buildCandidateSourceSignal(input);
166
+ const baseSourceSignal = buildCandidateSourceSignal(input);
167
+ const sourceSignal = mergeEvidenceDrivenReversalIntoSourceSignal(mergeDirectionalCorrectionIntoSourceSignal({
168
+ ...baseSourceSignal,
169
+ directional_correction: directionalCorrectionSignal ?? baseSourceSignal.directional_correction,
170
+ evidence_driven_reversal: evidenceDrivenReversalSignal ?? baseSourceSignal.evidence_driven_reversal
171
+ }, draft), draft);
109
172
  const candidateId = stableId("candidate", [draft.scope_id, draft.task_type, draft.node_type, draft.compact_hint, originRecordId].join(":"));
110
173
  return {
111
174
  id: candidateId,
@@ -137,6 +200,7 @@ const candidateToInitialJob = (candidate, extractorProfile) => {
137
200
  };
138
201
  };
139
202
  const mergeContext = (existing, incoming) => ({
203
+ host: incoming.host ?? existing?.host,
140
204
  sessionId: incoming.sessionId ?? existing?.sessionId,
141
205
  cwd: incoming.cwd ?? existing?.cwd,
142
206
  userMessage: incoming.userMessage || existing?.userMessage || "",
@@ -185,6 +249,23 @@ const resolveDeliveryMode = (evaluationMode, holdoutRate, sessionId, taskSummary
185
249
  delivered: true
186
250
  };
187
251
  };
252
+ const HYBRID_LIGHTWEIGHT_PATTERN = /\b(wording-only|wording only|copy-only|copy only|copy pass|inline notice wording|expression-layer refinement)\b/i;
253
+ const isLightweightHybridExcludedTask = (input) => HYBRID_LIGHTWEIGHT_PATTERN.test(`${input.task_summary} ${input.context_summary ?? ""}`);
254
+ export const decidePosttaskHybridRoute = (config, input, signals, rolloutKey = input.task_summary) => {
255
+ const rollout = resolveHybridRolloutState(config, rolloutKey);
256
+ return selectHybridRoute({
257
+ ...signals,
258
+ explicitExplanationRequest: false,
259
+ existingConservativePathRequired: false,
260
+ lightweightOrExcludedTask: signals.lightweightOrExcludedTask || isLightweightHybridExcludedTask(input),
261
+ rolloutAllowsAsyncPostmortem: config.hybridAsyncPostmortemEnabled && rollout.hybridActive
262
+ }, {
263
+ enabled: config.hybridEnabled && rollout.hybridActive,
264
+ syncExplainEnabled: false,
265
+ asyncPostmortemEnabled: config.hybridAsyncPostmortemEnabled && rollout.hybridActive,
266
+ policyVersion: config.hybridRoutePolicyVersion
267
+ });
268
+ };
188
269
  export class ExperienceRuntimeService {
189
270
  config;
190
271
  db;
@@ -201,13 +282,21 @@ export class ExperienceRuntimeService {
201
282
  reviewEventRepo;
202
283
  statsRepo;
203
284
  injectionRepo;
204
- packRepo;
205
- distillationWorker;
206
- learningGate;
285
+ hybridReviewArtifactRepo;
286
+ hybridTraceRepo;
287
+ runtimeOptions;
288
+ backgroundLearningEnabled;
289
+ hybridPosttaskEnabled;
290
+ distillationWorkerPromise;
291
+ learningGatePromise;
292
+ hybridWorkerClientPromise;
207
293
  pendingLearningTasks = new Set();
208
294
  captureWriter;
209
295
  constructor(config, logger, runtimeOptions = {}) {
210
296
  this.config = config;
297
+ this.runtimeOptions = runtimeOptions;
298
+ this.backgroundLearningEnabled = !runtimeOptions.disableBackgroundLearning;
299
+ this.hybridPosttaskEnabled = !runtimeOptions.disableHybridPosttask;
211
300
  this.logger = logger ?? {};
212
301
  this.db = openDatabase(config);
213
302
  bootstrapDatabase(this.db);
@@ -221,9 +310,8 @@ export class ExperienceRuntimeService {
221
310
  this.reviewEventRepo = new ReviewEventRepository(this.db);
222
311
  this.statsRepo = new StatsRepository(this.db);
223
312
  this.injectionRepo = new InjectionRepository(this.db);
224
- this.packRepo = new ExperiencePackRepository(this.db);
225
- this.distillationWorker = new DistillationQueueWorker(config, this.candidateRepo, this.jobRepo, this.nodeRepo, runtimeOptions);
226
- this.learningGate = new LlmLearningGate(config, runtimeOptions);
313
+ this.hybridReviewArtifactRepo = new HybridReviewArtifactRepository(this.db);
314
+ this.hybridTraceRepo = new HybridInvocationTraceRepository(this.db);
227
315
  this.captureWriter = new RuntimeCaptureWriter(config, this.logger);
228
316
  }
229
317
  getSession(sessionId) {
@@ -248,31 +336,9 @@ export class ExperienceRuntimeService {
248
336
  session.toolEventKeys.add(key);
249
337
  session.toolEvents.push(toolEvent);
250
338
  }
251
- resolveScopedNodes(scopeId) {
252
- const scopedNodes = this.nodeRepo.listInjectableByScope(scopeId);
253
- const activations = this.packRepo
254
- .listActivations(scopeId)
255
- .filter((activation) => activation.enabled);
256
- if (!activations.length) {
257
- return scopedNodes;
258
- }
259
- const allowedNodeIds = new Set();
260
- for (const activation of activations) {
261
- const version = activation.pinned_version ?? this.packRepo.getPack(activation.pack_id)?.current_version;
262
- if (!version) {
263
- continue;
264
- }
265
- for (const membership of this.packRepo.listMemberships(activation.pack_id, version)) {
266
- allowedNodeIds.add(membership.node_id);
267
- }
268
- }
269
- if (!allowedNodeIds.size) {
270
- return scopedNodes;
271
- }
272
- return [
273
- ...scopedNodes,
274
- ...this.nodeRepo.listByIds(Array.from(allowedNodeIds)).filter((node) => node.scope_id === scopeId)
275
- ].filter((node, index, nodes) => nodes.findIndex((entry) => entry.id === node.id) === index);
339
+ // The shipped runtime path stays exact-scope-only in this rollout.
340
+ resolveExactScopeInjectableNodes(scopeId) {
341
+ return this.nodeRepo.listLiveInjectableByExactScope(scopeId);
276
342
  }
277
343
  recoverToolEvents(sessionId, payload) {
278
344
  for (const toolResult of extractToolResultsFromPayload(payload)) {
@@ -325,8 +391,260 @@ export class ExperienceRuntimeService {
325
391
  async waitForBackgroundLearning() {
326
392
  await Promise.allSettled([...this.pendingLearningTasks]);
327
393
  }
394
+ async getLearningGate() {
395
+ if (!this.backgroundLearningEnabled) {
396
+ return undefined;
397
+ }
398
+ this.learningGatePromise ??= loadLlmLearningGate().then(({ LlmLearningGate: LoadedLlmLearningGate }) => new LoadedLlmLearningGate(this.config, this.runtimeOptions));
399
+ return this.learningGatePromise;
400
+ }
401
+ async getDistillationWorker() {
402
+ if (!this.backgroundLearningEnabled) {
403
+ return undefined;
404
+ }
405
+ this.distillationWorkerPromise ??= loadDistillationQueueWorker().then(({ DistillationQueueWorker: LoadedDistillationQueueWorker }) => new LoadedDistillationQueueWorker(this.config, this.candidateRepo, this.jobRepo, this.nodeRepo, this.runtimeOptions));
406
+ return this.distillationWorkerPromise;
407
+ }
408
+ async getHybridWorkerClient() {
409
+ if (!this.hybridPosttaskEnabled) {
410
+ return undefined;
411
+ }
412
+ this.hybridWorkerClientPromise ??= loadHybridWorkerClientModule().then(({ HybridWorkerClient: LoadedHybridWorkerClient }) => new LoadedHybridWorkerClient({
413
+ explainDecisionEnabled: this.config.hybridEnabled && this.config.hybridSyncExplainEnabled,
414
+ postmortemReviewEnabled: this.config.hybridEnabled && this.config.hybridAsyncPostmortemEnabled,
415
+ postmortemReviewLlmEnabled: this.config.hybridEnabled
416
+ && this.config.hybridAsyncPostmortemEnabled
417
+ && this.config.hybridAsyncPostmortemLlmEnabled,
418
+ ...this.runtimeOptions.hybridWorkerClientOptions
419
+ }));
420
+ return this.hybridWorkerClientPromise;
421
+ }
422
+ buildPostmortemArtifact(input) {
423
+ const timestamp = nowIso();
424
+ return {
425
+ id: createId("hybridreview"),
426
+ task_run_id: input.taskRun.id,
427
+ scope_id: input.taskRun.scope_id,
428
+ worker_task: "postmortem_review",
429
+ approval_class: input.result.approvalClass === "policy_gated" ? "policy_gated" : "review_artifact",
430
+ schema_version: this.config.hybridCapsuleSchemaVersion,
431
+ route_policy_version: input.routeDecision.policyVersion,
432
+ worker_profile_version: this.config.hybridPostmortemReviewProfileVersion,
433
+ recommendation: input.result.value.candidate_recommendation,
434
+ summary: input.result.value.review_artifact?.summary ?? input.result.value.reason,
435
+ payload: input.result.value,
436
+ created_at: timestamp,
437
+ updated_at: timestamp
438
+ };
439
+ }
440
+ applyPostmortemDeliveryRecommendation(node, recommendation) {
441
+ if (recommendation === "keep" || recommendation === "review") {
442
+ return node;
443
+ }
444
+ if (recommendation === "quarantine") {
445
+ return {
446
+ ...node,
447
+ delivery_state: "quarantined",
448
+ quarantined_at: node.quarantined_at ?? nowIso(),
449
+ quarantine_reason: node.quarantine_reason ?? "postmortem_review"
450
+ };
451
+ }
452
+ if (node.delivery_state === "quarantined") {
453
+ return node;
454
+ }
455
+ return {
456
+ ...node,
457
+ delivery_state: node.delivery_state === "shadow_only" ? "shadow_only" : "conservative_only"
458
+ };
459
+ }
460
+ applyAcceptedPostmortemNodeReviews(input) {
461
+ const reviews = input.result.value.injected_node_reviews ?? [];
462
+ if (!reviews.length || input.taskRun.final_status === "cancelled") {
463
+ return false;
464
+ }
465
+ const allowedIds = new Set(input.experienceInput.injected_node_ids);
466
+ const existingEvents = this.reviewEventRepo.listByTaskRunId(input.taskRun.id);
467
+ let applied = false;
468
+ for (const review of reviews) {
469
+ if (!allowedIds.has(review.node_id) || review.confidence === "low") {
470
+ continue;
471
+ }
472
+ const current = this.nodeRepo.getById(review.node_id);
473
+ if (!current) {
474
+ continue;
475
+ }
476
+ const existingNodeEvents = existingEvents.filter((event) => event.node_id === review.node_id && event.source === "automatic");
477
+ const alreadyMarkedHelped = existingNodeEvents.some((event) => event.event_type === "mark_helped");
478
+ const alreadyMarkedHarmed = existingNodeEvents.some((event) => event.event_type === "mark_harmed");
479
+ let nextNode = current;
480
+ let feedbackEventType;
481
+ if (review.feedback_verdict === "helped" && !alreadyMarkedHelped) {
482
+ nextNode = applyGovernedNodeFeedback(nextNode, "helped", deriveNodeOriginProfileForNode(this.inputRepo, nextNode));
483
+ feedbackEventType = "mark_helped";
484
+ }
485
+ else if (review.feedback_verdict === "harmed" && !alreadyMarkedHarmed) {
486
+ nextNode = applyGovernedNodeFeedback(nextNode, "harmed", deriveNodeOriginProfileForNode(this.inputRepo, nextNode));
487
+ feedbackEventType = "mark_harmed";
488
+ }
489
+ const nodeAfterDelivery = this.applyPostmortemDeliveryRecommendation(nextNode, review.delivery_recommendation);
490
+ if (feedbackEventType
491
+ || nodeAfterDelivery.delivery_state !== current.delivery_state
492
+ || nodeAfterDelivery.state !== current.state
493
+ || nodeAfterDelivery.helped_count !== current.helped_count
494
+ || nodeAfterDelivery.harmed_count !== current.harmed_count
495
+ || nodeAfterDelivery.last_feedback_verdict !== current.last_feedback_verdict) {
496
+ this.nodeRepo.upsert(nodeAfterDelivery);
497
+ applied = true;
498
+ }
499
+ if (feedbackEventType) {
500
+ this.reviewEventRepo.upsert({
501
+ id: createId("review"),
502
+ node_id: review.node_id,
503
+ task_run_id: input.taskRun.id,
504
+ event_type: feedbackEventType,
505
+ source: "automatic",
506
+ created_at: nowIso()
507
+ });
508
+ }
509
+ if (current.delivery_state !== "quarantined" && nodeAfterDelivery.delivery_state === "quarantined") {
510
+ this.reviewEventRepo.upsert({
511
+ id: createId("review"),
512
+ node_id: review.node_id,
513
+ task_run_id: input.taskRun.id,
514
+ event_type: "quarantine",
515
+ source: "automatic",
516
+ created_at: nowIso()
517
+ });
518
+ }
519
+ }
520
+ return applied;
521
+ }
522
+ async persistHybridPostmortemArtifactAsync(input) {
523
+ if (!this.hybridPosttaskEnabled) {
524
+ return;
525
+ }
526
+ if (this.hybridReviewArtifactRepo.getByTaskRunId(input.taskRun.id)) {
527
+ return;
528
+ }
529
+ const hybridWorkerClient = await this.getHybridWorkerClient();
530
+ if (!hybridWorkerClient) {
531
+ return;
532
+ }
533
+ const candidateSignals = buildCandidateSignals(input.experienceInput);
534
+ const [{ buildPostmortemReviewCapsule }, { resolveHybridPostmortemProviderEndpoint }] = await Promise.all([
535
+ loadHybridCapsuleBuilder(),
536
+ loadHybridPostmortemProviderClient()
537
+ ]);
538
+ const capsule = buildPostmortemReviewCapsule({
539
+ schemaVersion: this.config.hybridCapsuleSchemaVersion,
540
+ routeDecision: input.routeDecision,
541
+ taskRun: input.taskRun,
542
+ outcomeSignal: input.experienceInput.outcome_signal,
543
+ triggers: {
544
+ directionalCorrectionPresent: candidateSignals.directional_correction?.detected === true
545
+ || candidateSignals.evidence_driven_reversal?.detected === true,
546
+ injectedNodeInteractionPresent: input.experienceInput.injected_node_ids.length > 0,
547
+ retryOrInvalidationSignaturePresent: candidateSignals.retry_count > 0 || candidateSignals.evidence_driven_reversal?.invalidating_evidence === true,
548
+ meaningfulFailureSignaturePresent: Boolean(candidateSignals.failure_signature),
549
+ conservativeTransitionReviewWorthy: input.experienceInput.outcome_signal === "success" && input.experienceInput.injected_node_ids.length > 0
550
+ },
551
+ injectedNodes: input.experienceInput.injected_node_ids
552
+ .map((id) => this.nodeRepo.getById(id))
553
+ .filter((node) => Boolean(node)),
554
+ toolEvents: input.toolEvents
555
+ });
556
+ const providerResolution = this.config.hybridAsyncPostmortemLlmEnabled
557
+ ? resolveHybridPostmortemProviderEndpoint(this.config)
558
+ : { status: "disabled", reason: "Phase 3 provider-backed postmortem review is disabled." };
559
+ const result = this.config.hybridAsyncPostmortemLlmEnabled && providerResolution.status === "unavailable"
560
+ ? {
561
+ status: "fallback",
562
+ reason: "provider_unavailable"
563
+ }
564
+ : await hybridWorkerClient.runPostmortemReview(capsule, providerResolution.status === "configured"
565
+ ? {
566
+ mode: "provider",
567
+ endpoint: providerResolution.endpoint
568
+ }
569
+ : undefined);
570
+ const timestamp = nowIso();
571
+ const persistAcceptedArtifact = result.status === "accepted"
572
+ && input.rolloutMode !== "shadow"
573
+ && (result.approvalClass === "review_artifact" || result.approvalClass === "policy_gated");
574
+ const appliedNodeWriteback = result.status === "accepted" && input.rolloutMode !== "shadow"
575
+ ? this.applyAcceptedPostmortemNodeReviews({
576
+ taskRun: input.taskRun,
577
+ experienceInput: input.experienceInput,
578
+ result
579
+ })
580
+ : false;
581
+ this.hybridTraceRepo.upsert({
582
+ id: createId("hybridtrace"),
583
+ surface: "runtime",
584
+ session_id: input.taskRun.session_id,
585
+ scope_id: input.taskRun.scope_id,
586
+ worker_task: "postmortem_review",
587
+ route: input.routeDecision.route,
588
+ route_policy_version: input.routeDecision.policyVersion,
589
+ capsule_schema_version: this.config.hybridCapsuleSchemaVersion,
590
+ worker_profile_version: this.config.hybridAsyncPostmortemLlmEnabled
591
+ ? this.config.hybridPostmortemModelProfileVersion
592
+ : this.config.hybridPostmortemReviewProfileVersion,
593
+ rollout_mode: input.rolloutMode,
594
+ rollout_reason: input.rolloutReason,
595
+ worker_ran: result.status !== "fallback" || result.reason !== "provider_unavailable",
596
+ validation_status: result.status === "accepted" ? "accepted" : "fallback",
597
+ output_action: persistAcceptedArtifact || appliedNodeWriteback ? "stored" : "rejected",
598
+ fallback_reason: result.status === "accepted" ? undefined : result.reason,
599
+ created_at: timestamp
600
+ });
601
+ if (result.status !== "accepted") {
602
+ this.logger.debug?.("experienceengine.hybrid_postmortem_skipped", {
603
+ taskRunId: input.taskRun.id,
604
+ reason: result.reason
605
+ });
606
+ return;
607
+ }
608
+ if (persistAcceptedArtifact) {
609
+ this.hybridReviewArtifactRepo.upsert(this.buildPostmortemArtifact({
610
+ taskRun: input.taskRun,
611
+ result,
612
+ routeDecision: input.routeDecision
613
+ }));
614
+ }
615
+ }
328
616
  async persistCandidatesAsync(input, originRecordId, taskRunId, sessionId) {
329
- const result = await this.learningGate.generateCandidateDrafts(input);
617
+ const learningGate = await this.getLearningGate();
618
+ if (!learningGate) {
619
+ if (taskRunId) {
620
+ const taskRun = this.taskRunRepo.getById(taskRunId);
621
+ if (taskRun) {
622
+ this.taskRunRepo.upsert({
623
+ ...taskRun,
624
+ learning_status: "not_applicable",
625
+ learning_reason: "background learning disabled",
626
+ updated_at: nowIso()
627
+ });
628
+ }
629
+ }
630
+ return;
631
+ }
632
+ const result = await learningGate.generateCandidateDrafts(input);
633
+ if (taskRunId) {
634
+ const taskRun = this.taskRunRepo.getById(taskRunId);
635
+ if (taskRun) {
636
+ this.taskRunRepo.upsert({
637
+ ...taskRun,
638
+ learning_status: result.drafts.length
639
+ ? "captured"
640
+ : result.source === "disabled" && result.reason === "distillation disabled"
641
+ ? "not_applicable"
642
+ : "rejected",
643
+ learning_reason: result.reason,
644
+ updated_at: nowIso()
645
+ });
646
+ }
647
+ }
330
648
  if (!result.drafts.length) {
331
649
  this.logger.debug?.("experienceengine.learning_skipped", {
332
650
  sessionId,
@@ -336,7 +654,7 @@ export class ExperienceRuntimeService {
336
654
  });
337
655
  return;
338
656
  }
339
- const persistedCandidates = result.drafts.map((draft) => draftToCandidate(draft, input, originRecordId, taskRunId));
657
+ const persistedCandidates = result.drafts.map((draft) => draftToCandidate(draft, input, originRecordId, taskRunId, result.directionalCorrectionSignal, result.evidenceDrivenReversalSignal));
340
658
  withTransaction(this.db, () => {
341
659
  for (const candidate of persistedCandidates) {
342
660
  this.candidateRepo.upsert(candidate);
@@ -351,7 +669,11 @@ export class ExperienceRuntimeService {
351
669
  reason: result.reason
352
670
  });
353
671
  if (this.config.distillationAutoDrain) {
354
- await this.distillationWorker.drain().catch((error) => {
672
+ const distillationWorker = await this.getDistillationWorker();
673
+ if (!distillationWorker) {
674
+ return;
675
+ }
676
+ await distillationWorker.drain().catch((error) => {
355
677
  this.logger.error?.("experienceengine.distillation_drain_failed", {
356
678
  sessionId,
357
679
  error: error instanceof Error ? error.message : String(error)
@@ -371,7 +693,7 @@ export class ExperienceRuntimeService {
371
693
  if (input.outcome_signal === "success") {
372
694
  return {
373
695
  nodeId: node.id,
374
- eventType: "mark_helped"
696
+ eventType: "mark_uncertain"
375
697
  };
376
698
  }
377
699
  if (detectHarm(input, node)) {
@@ -383,7 +705,10 @@ export class ExperienceRuntimeService {
383
705
  return undefined;
384
706
  })
385
707
  .filter((value) => Boolean(value));
386
- for (const node of applyFeedback(input, touched, attributionRecordId)) {
708
+ const originProfilesByNodeId = Object.fromEntries(touched.map((node) => {
709
+ return [node.id, deriveNodeOriginProfileForNode(this.inputRepo, node)];
710
+ }));
711
+ for (const node of applyFeedback(input, touched, attributionRecordId, { originProfilesByNodeId })) {
387
712
  this.nodeRepo.upsert(node);
388
713
  }
389
714
  for (const event of automaticEvents) {
@@ -402,6 +727,7 @@ export class ExperienceRuntimeService {
402
727
  const session = this.getSession(sessionId);
403
728
  session.context = mergeContext(session.context, context);
404
729
  const input = buildExperienceInput(session.context, session.toolEvents);
730
+ const retrievalContext = buildRetrievalContext(input, session.context);
405
731
  const resolvedScope = resolveScope(session.context.cwd);
406
732
  const existingScope = this.scopeRepo.getById(resolvedScope.scope_id);
407
733
  if (existingScope?.is_disabled) {
@@ -419,6 +745,7 @@ export class ExperienceRuntimeService {
419
745
  mode: "skip",
420
746
  text: undefined,
421
747
  notice: undefined,
748
+ retrievalContext,
422
749
  input: {
423
750
  ...input,
424
751
  scope_id: existingScope.scope_id,
@@ -427,8 +754,8 @@ export class ExperienceRuntimeService {
427
754
  };
428
755
  }
429
756
  const stats = input.task_type !== "unknown" ? this.statsRepo.get(input.scope_id, input.task_type) : undefined;
430
- const nodes = input.task_type !== "unknown" ? this.resolveScopedNodes(input.scope_id) : [];
431
- const decision = await decideIntervention(input, nodes, stats, this.config.triggerThreshold, this.config.maxHints, this.config);
757
+ const nodes = input.task_type !== "unknown" ? this.resolveExactScopeInjectableNodes(input.scope_id) : [];
758
+ const decision = await decideIntervention(input, nodes, stats, this.config.triggerThreshold, this.config.maxHints, this.config, retrievalContext);
432
759
  const selectedNodeIds = decision.selected.map((node) => node.id);
433
760
  const delivery = resolveDeliveryMode(this.config.evaluationMode, this.config.holdoutRate, sessionId, input.task_summary, decision.mode !== "skip" && selectedNodeIds.length > 0);
434
761
  session.injectedNodeIds = delivery.delivered ? selectedNodeIds : [];
@@ -437,7 +764,7 @@ export class ExperienceRuntimeService {
437
764
  injectedNodeIds: session.injectedNodeIds
438
765
  };
439
766
  if (decision.mode !== "skip") {
440
- const scorecard = buildInjectionScorecard(input, decision.mode, decision.selected, sessionId);
767
+ const scorecard = buildInjectionScorecard(input, decision.mode, decision.selected, sessionId, decision.diagnostics);
441
768
  const injectionEvent = {
442
769
  injection_id: createId("inject"),
443
770
  session_id: sessionId,
@@ -475,6 +802,7 @@ export class ExperienceRuntimeService {
475
802
  scorecard: decision.mode !== "skip" ? session.lastInjectionEvent?.scorecard : undefined,
476
803
  deliveryMode: decision.mode !== "skip" ? delivery.deliveryMode : undefined,
477
804
  delivered: decision.mode !== "skip" ? delivery.delivered : undefined,
805
+ retrievalContext,
478
806
  input: {
479
807
  ...input,
480
808
  injected_node_ids: session.injectedNodeIds
@@ -536,22 +864,71 @@ export class ExperienceRuntimeService {
536
864
  input,
537
865
  originRecordId: record.record_id,
538
866
  taskRunId: taskRun.id,
539
- sessionId
867
+ sessionId,
868
+ taskRun,
869
+ toolEvents: [...session.toolEvents]
540
870
  };
541
871
  });
542
872
  this.sessions.delete(sessionId);
543
- if (learningTaskContext) {
544
- this.trackLearningTask(this.persistCandidatesAsync(learningTaskContext.input, learningTaskContext.originRecordId, learningTaskContext.taskRunId, learningTaskContext.sessionId));
873
+ const rollout = resolveHybridRolloutState(this.config, `${sessionId}:${input.task_summary}`);
874
+ const hybridPosttaskRoute = decidePosttaskHybridRoute(this.config, input, {
875
+ taskStage: "posttask",
876
+ completedRun: true,
877
+ terminalOutcomeRecorded: true,
878
+ boundedPosttaskCapsuleAvailable: Boolean(input.task_summary),
879
+ postmortemAlreadyRecorded: learningTaskContext
880
+ ? Boolean(this.hybridReviewArtifactRepo.getByTaskRunId(learningTaskContext.taskRun.id))
881
+ : false,
882
+ lightweightOrExcludedTask: false,
883
+ directionalCorrectionPresent: Boolean(learningTaskContext
884
+ ? buildCandidateSignals(learningTaskContext.input).directional_correction?.detected
885
+ || buildCandidateSignals(learningTaskContext.input).evidence_driven_reversal?.detected
886
+ : false),
887
+ injectedNodeInteractionPresent: input.injected_node_ids.length > 0,
888
+ retryOrInvalidationSignaturePresent: Boolean(learningTaskContext
889
+ ? buildCandidateSignals(learningTaskContext.input).retry_count > 0
890
+ || buildCandidateSignals(learningTaskContext.input).evidence_driven_reversal?.invalidating_evidence
891
+ : false),
892
+ meaningfulFailureSignaturePresent: Boolean(learningTaskContext
893
+ ? buildCandidateSignals(learningTaskContext.input).failure_signature
894
+ : input.outcome_signal === "failure"),
895
+ conservativeTransitionReviewWorthy: false
896
+ }, `${sessionId}:${input.task_summary}`);
897
+ if (learningTaskContext && this.backgroundLearningEnabled) {
898
+ this.trackLearningTask((async () => {
899
+ await this.persistCandidatesAsync(learningTaskContext.input, learningTaskContext.originRecordId, learningTaskContext.taskRunId, learningTaskContext.sessionId);
900
+ if (hybridPosttaskRoute.route !== "ESCALATE_ASYNC_POSTMORTEM") {
901
+ return;
902
+ }
903
+ const refreshedTaskRun = this.taskRunRepo.getById(learningTaskContext.taskRun.id) ?? learningTaskContext.taskRun;
904
+ await this.persistHybridPostmortemArtifactAsync({
905
+ taskRun: refreshedTaskRun,
906
+ experienceInput: learningTaskContext.input,
907
+ routeDecision: hybridPosttaskRoute,
908
+ toolEvents: learningTaskContext.toolEvents,
909
+ rolloutMode: rollout.effectiveMode,
910
+ rolloutReason: rollout.reason
911
+ });
912
+ })());
545
913
  }
546
914
  this.logger.info?.("experienceengine.finalize", {
547
915
  sessionId,
548
916
  taskType: input.task_type,
549
- outcome: input.outcome_signal
917
+ outcome: input.outcome_signal,
918
+ hybridPosttaskRoute: hybridPosttaskRoute.route,
919
+ hybridPosttaskRouteReason: hybridPosttaskRoute.reasonCode,
920
+ hybridRoutePolicyVersion: hybridPosttaskRoute.policyVersion,
921
+ hybridRolloutMode: rollout.effectiveMode,
922
+ hybridRolloutReason: rollout.reason
550
923
  });
551
924
  return input;
552
925
  }
553
926
  async drainDistillationQueue(limit) {
554
- return this.distillationWorker.drain(limit);
927
+ const distillationWorker = await this.getDistillationWorker();
928
+ if (!distillationWorker) {
929
+ return 0;
930
+ }
931
+ return distillationWorker.drain(limit);
555
932
  }
556
933
  }
557
934
  //# sourceMappingURL=service.js.map