create-principles-disciple 1.93.0 → 1.95.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 (526) hide show
  1. package/console/dist/server/config/WorkspaceConfigStore.js +2 -1
  2. package/console/dist/server/config/pd-config-store.d.ts +40 -1
  3. package/console/dist/server/config/pd-config-store.js +170 -1
  4. package/console/dist/server/index.js +28 -10
  5. package/console/dist/server/models/ApprovalsConsoleModel.js +4 -12
  6. package/console/dist/server/models/EvidenceChainConsoleModel.d.ts +0 -2
  7. package/console/dist/server/models/EvidenceChainConsoleModel.js +36 -2
  8. package/console/dist/server/models/HealthCheckModel.js +5 -3
  9. package/console/dist/server/models/IntentDecisionModel.d.ts +66 -0
  10. package/console/dist/server/models/IntentDecisionModel.js +207 -0
  11. package/console/dist/server/models/IntentPageModel.d.ts +18 -0
  12. package/console/dist/server/models/IntentPageModel.js +90 -0
  13. package/console/dist/server/models/PrinciplesConsoleModel.d.ts +2 -0
  14. package/console/dist/server/models/PrinciplesConsoleModel.js +37 -1
  15. package/console/dist/server/models/WorkspaceService.d.ts +0 -28
  16. package/console/dist/server/models/WorkspaceService.js +0 -115
  17. package/console/dist/server/routes/config.js +55 -1
  18. package/console/dist/server/routes/feedback-reports.js +1 -1
  19. package/console/dist/server/routes/intent-decisions.d.ts +33 -0
  20. package/console/dist/server/routes/intent-decisions.js +499 -0
  21. package/console/dist/server/routes/intent.d.ts +3 -0
  22. package/console/dist/server/routes/intent.js +35 -0
  23. package/console/dist/server/routes/principles.js +67 -1
  24. package/console/dist/server/routes/update.d.ts +0 -1
  25. package/console/dist/server/routes/update.js +14 -11
  26. package/console/dist/ui/App.js +2 -7
  27. package/console/dist/ui/api.d.ts +44 -18
  28. package/console/dist/ui/api.js +44 -5
  29. package/console/dist/ui/components/layout/app-sidebar.js +2 -1
  30. package/console/dist/ui/components/ui/badge.d.ts +1 -1
  31. package/console/dist/ui/components/ui/button.d.ts +1 -1
  32. package/console/dist/ui/components/ui/shiny-text.d.ts +28 -0
  33. package/console/dist/ui/components/ui/shiny-text.js +46 -0
  34. package/console/dist/ui/i18n/en.json +167 -3
  35. package/console/dist/ui/i18n/zh-CN.json +167 -3
  36. package/console/dist/ui/pages/activation/ActivationPage.js +2 -1
  37. package/console/dist/ui/pages/control-center/ControlCenterPage.js +28 -2
  38. package/console/dist/ui/pages/control-center/EmpathyObserverCostHint.d.ts +28 -0
  39. package/console/dist/ui/pages/control-center/EmpathyObserverCostHint.js +38 -0
  40. package/console/dist/ui/pages/debt/DebtPage.js +219 -2
  41. package/console/dist/ui/pages/focus/FocusPage.js +2 -1
  42. package/console/dist/ui/pages/intent/IntentPage.d.ts +1 -0
  43. package/console/dist/ui/pages/intent/IntentPage.js +147 -0
  44. package/console/dist/ui/pages/pain/PainPage.js +234 -4
  45. package/console/dist/ui/pages/pain/pain-card-helpers.d.ts +75 -0
  46. package/console/dist/ui/pages/pain/pain-card-helpers.js +78 -0
  47. package/console/dist/ui/pages/principles/PrinciplesPage.js +2 -1
  48. package/console/dist/ui/utils/validators.d.ts +163 -0
  49. package/console/dist/ui/utils/validators.js +433 -0
  50. package/console/dist/web/assets/app.css +138 -0
  51. package/console/dist/web/assets/app.js +3124 -1288
  52. package/console/package.json +3 -0
  53. package/core/dist/index.d.ts +2 -2
  54. package/core/dist/index.d.ts.map +1 -1
  55. package/core/dist/index.js +1 -1
  56. package/core/dist/index.js.map +1 -1
  57. package/core/dist/principle-tree-ledger.d.ts +55 -4
  58. package/core/dist/principle-tree-ledger.d.ts.map +1 -1
  59. package/core/dist/principle-tree-ledger.js +472 -13
  60. package/core/dist/principle-tree-ledger.js.map +1 -1
  61. package/core/dist/prompt-builder/__tests__/model-config.test.d.ts +2 -0
  62. package/core/dist/prompt-builder/__tests__/model-config.test.d.ts.map +1 -0
  63. package/core/dist/prompt-builder/__tests__/model-config.test.js +158 -0
  64. package/core/dist/prompt-builder/__tests__/model-config.test.js.map +1 -0
  65. package/core/dist/prompt-builder/__tests__/prompt-builder-core.test.js +58 -0
  66. package/core/dist/prompt-builder/__tests__/prompt-builder-core.test.js.map +1 -1
  67. package/core/dist/prompt-builder/__tests__/xml-escape.test.d.ts +2 -0
  68. package/core/dist/prompt-builder/__tests__/xml-escape.test.d.ts.map +1 -0
  69. package/core/dist/prompt-builder/__tests__/xml-escape.test.js +42 -0
  70. package/core/dist/prompt-builder/__tests__/xml-escape.test.js.map +1 -0
  71. package/core/dist/prompt-builder/empathy-keyword-matching.d.ts.map +1 -1
  72. package/core/dist/prompt-builder/empathy-keyword-matching.js +9 -6
  73. package/core/dist/prompt-builder/empathy-keyword-matching.js.map +1 -1
  74. package/core/dist/prompt-builder/index.d.ts +3 -0
  75. package/core/dist/prompt-builder/index.d.ts.map +1 -1
  76. package/core/dist/prompt-builder/index.js +2 -0
  77. package/core/dist/prompt-builder/index.js.map +1 -1
  78. package/core/dist/prompt-builder/model-config.d.ts +42 -0
  79. package/core/dist/prompt-builder/model-config.d.ts.map +1 -0
  80. package/core/dist/prompt-builder/model-config.js +84 -0
  81. package/core/dist/prompt-builder/model-config.js.map +1 -0
  82. package/core/dist/prompt-builder/size-guard.d.ts +1 -0
  83. package/core/dist/prompt-builder/size-guard.d.ts.map +1 -1
  84. package/core/dist/prompt-builder/size-guard.js +21 -0
  85. package/core/dist/prompt-builder/size-guard.js.map +1 -1
  86. package/core/dist/prompt-builder/types.d.ts +2 -0
  87. package/core/dist/prompt-builder/types.d.ts.map +1 -1
  88. package/core/dist/prompt-builder/xml-escape.d.ts +12 -0
  89. package/core/dist/prompt-builder/xml-escape.d.ts.map +1 -0
  90. package/core/dist/prompt-builder/xml-escape.js +19 -0
  91. package/core/dist/prompt-builder/xml-escape.js.map +1 -0
  92. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js +205 -48
  93. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
  94. package/core/dist/runtime-v2/__tests__/evidence-chain-intent-tension.test.d.ts +2 -0
  95. package/core/dist/runtime-v2/__tests__/evidence-chain-intent-tension.test.d.ts.map +1 -0
  96. package/core/dist/runtime-v2/__tests__/evidence-chain-intent-tension.test.js +284 -0
  97. package/core/dist/runtime-v2/__tests__/evidence-chain-intent-tension.test.js.map +1 -0
  98. package/core/dist/runtime-v2/__tests__/pain-signal-bridge-result-shaping.test.d.ts +2 -0
  99. package/core/dist/runtime-v2/__tests__/pain-signal-bridge-result-shaping.test.d.ts.map +1 -0
  100. package/core/dist/runtime-v2/__tests__/pain-signal-bridge-result-shaping.test.js +500 -0
  101. package/core/dist/runtime-v2/__tests__/pain-signal-bridge-result-shaping.test.js.map +1 -0
  102. package/core/dist/runtime-v2/__tests__/pain-signal-observability.test.js +7 -5
  103. package/core/dist/runtime-v2/__tests__/pain-signal-observability.test.js.map +1 -1
  104. package/core/dist/runtime-v2/__tests__/pi-artifact-store.test.js +11 -0
  105. package/core/dist/runtime-v2/__tests__/pi-artifact-store.test.js.map +1 -1
  106. package/core/dist/runtime-v2/__tests__/proven-channel-baseline.test.js +15 -2
  107. package/core/dist/runtime-v2/__tests__/proven-channel-baseline.test.js.map +1 -1
  108. package/core/dist/runtime-v2/__tests__/schema-float-precision.test.d.ts +2 -0
  109. package/core/dist/runtime-v2/__tests__/schema-float-precision.test.d.ts.map +1 -0
  110. package/core/dist/runtime-v2/__tests__/schema-float-precision.test.js +290 -0
  111. package/core/dist/runtime-v2/__tests__/schema-float-precision.test.js.map +1 -0
  112. package/core/dist/runtime-v2/__tests__/schema-orphan-detection.test.d.ts +2 -0
  113. package/core/dist/runtime-v2/__tests__/schema-orphan-detection.test.d.ts.map +1 -0
  114. package/core/dist/runtime-v2/__tests__/schema-orphan-detection.test.js +158 -0
  115. package/core/dist/runtime-v2/__tests__/schema-orphan-detection.test.js.map +1 -0
  116. package/core/dist/runtime-v2/activation/__tests__/approval-store-extended.test.js +15 -1
  117. package/core/dist/runtime-v2/activation/__tests__/approval-store-extended.test.js.map +1 -1
  118. package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-state-store-fk.test.d.ts +2 -0
  119. package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-state-store-fk.test.d.ts.map +1 -0
  120. package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-state-store-fk.test.js +62 -0
  121. package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-state-store-fk.test.js.map +1 -0
  122. package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-state-store.test.js +12 -2
  123. package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-state-store.test.js.map +1 -1
  124. package/core/dist/runtime-v2/activation/__tests__/sqlite-approval-store-fk.test.d.ts +2 -0
  125. package/core/dist/runtime-v2/activation/__tests__/sqlite-approval-store-fk.test.d.ts.map +1 -0
  126. package/core/dist/runtime-v2/activation/__tests__/sqlite-approval-store-fk.test.js +56 -0
  127. package/core/dist/runtime-v2/activation/__tests__/sqlite-approval-store-fk.test.js.map +1 -0
  128. package/core/dist/runtime-v2/activation/__tests__/sqlite-approval-store.test.js +8 -0
  129. package/core/dist/runtime-v2/activation/__tests__/sqlite-approval-store.test.js.map +1 -1
  130. package/core/dist/runtime-v2/activation/__tests__/story-a-acceptance.test.js +20 -0
  131. package/core/dist/runtime-v2/activation/__tests__/story-a-acceptance.test.js.map +1 -1
  132. package/core/dist/runtime-v2/activation/sqlite-activation-state-store.d.ts.map +1 -1
  133. package/core/dist/runtime-v2/activation/sqlite-activation-state-store.js +6 -0
  134. package/core/dist/runtime-v2/activation/sqlite-activation-state-store.js.map +1 -1
  135. package/core/dist/runtime-v2/activation/sqlite-approval-store.d.ts.map +1 -1
  136. package/core/dist/runtime-v2/activation/sqlite-approval-store.js +86 -32
  137. package/core/dist/runtime-v2/activation/sqlite-approval-store.js.map +1 -1
  138. package/core/dist/runtime-v2/activation/writers/__tests__/rule-host-writer.test.js +65 -1
  139. package/core/dist/runtime-v2/activation/writers/__tests__/rule-host-writer.test.js.map +1 -1
  140. package/core/dist/runtime-v2/activation/writers/rule-host-writer.d.ts.map +1 -1
  141. package/core/dist/runtime-v2/activation/writers/rule-host-writer.js +33 -11
  142. package/core/dist/runtime-v2/activation/writers/rule-host-writer.js.map +1 -1
  143. package/core/dist/runtime-v2/bridge-result-shaper.d.ts +53 -0
  144. package/core/dist/runtime-v2/bridge-result-shaper.d.ts.map +1 -0
  145. package/core/dist/runtime-v2/bridge-result-shaper.js +117 -0
  146. package/core/dist/runtime-v2/bridge-result-shaper.js.map +1 -0
  147. package/core/dist/runtime-v2/detection/__tests__/detection-funnel-policy.test.d.ts +13 -0
  148. package/core/dist/runtime-v2/detection/__tests__/detection-funnel-policy.test.d.ts.map +1 -0
  149. package/core/dist/runtime-v2/detection/__tests__/detection-funnel-policy.test.js +111 -0
  150. package/core/dist/runtime-v2/detection/__tests__/detection-funnel-policy.test.js.map +1 -0
  151. package/core/dist/runtime-v2/detection/detection-funnel-policy.d.ts +103 -0
  152. package/core/dist/runtime-v2/detection/detection-funnel-policy.d.ts.map +1 -0
  153. package/core/dist/runtime-v2/detection/detection-funnel-policy.js +135 -0
  154. package/core/dist/runtime-v2/detection/detection-funnel-policy.js.map +1 -0
  155. package/core/dist/runtime-v2/detection/index.d.ts +10 -0
  156. package/core/dist/runtime-v2/detection/index.d.ts.map +1 -0
  157. package/core/dist/runtime-v2/detection/index.js +9 -0
  158. package/core/dist/runtime-v2/detection/index.js.map +1 -0
  159. package/core/dist/runtime-v2/diagnostician/__tests__/diag-rootcause-output.test.js +134 -15
  160. package/core/dist/runtime-v2/diagnostician/__tests__/diag-rootcause-output.test.js.map +1 -1
  161. package/core/dist/runtime-v2/diagnostician/__tests__/intent-tension-schema.test.d.ts +18 -0
  162. package/core/dist/runtime-v2/diagnostician/__tests__/intent-tension-schema.test.d.ts.map +1 -0
  163. package/core/dist/runtime-v2/diagnostician/__tests__/intent-tension-schema.test.js +251 -0
  164. package/core/dist/runtime-v2/diagnostician/__tests__/intent-tension-schema.test.js.map +1 -0
  165. package/core/dist/runtime-v2/diagnostician/__tests__/rootcause-prompt-builder.test.js +73 -0
  166. package/core/dist/runtime-v2/diagnostician/__tests__/rootcause-prompt-builder.test.js.map +1 -1
  167. package/core/dist/runtime-v2/diagnostician/diag-rootcause-output.d.ts +98 -0
  168. package/core/dist/runtime-v2/diagnostician/diag-rootcause-output.d.ts.map +1 -1
  169. package/core/dist/runtime-v2/diagnostician/diag-rootcause-output.js +131 -0
  170. package/core/dist/runtime-v2/diagnostician/diag-rootcause-output.js.map +1 -1
  171. package/core/dist/runtime-v2/diagnostician/rootcause-prompt-builder.d.ts +8 -0
  172. package/core/dist/runtime-v2/diagnostician/rootcause-prompt-builder.d.ts.map +1 -1
  173. package/core/dist/runtime-v2/diagnostician/rootcause-prompt-builder.js +66 -3
  174. package/core/dist/runtime-v2/diagnostician/rootcause-prompt-builder.js.map +1 -1
  175. package/core/dist/runtime-v2/diagnostician-output.d.ts +23 -0
  176. package/core/dist/runtime-v2/diagnostician-output.d.ts.map +1 -1
  177. package/core/dist/runtime-v2/diagnostician-output.js +16 -0
  178. package/core/dist/runtime-v2/diagnostician-output.js.map +1 -1
  179. package/core/dist/runtime-v2/diagnostician-prompt-builder.d.ts +32 -0
  180. package/core/dist/runtime-v2/diagnostician-prompt-builder.d.ts.map +1 -1
  181. package/core/dist/runtime-v2/diagnostician-prompt-builder.js.map +1 -1
  182. package/core/dist/runtime-v2/evidence-triage/__tests__/observation-resolver.test.d.ts +12 -0
  183. package/core/dist/runtime-v2/evidence-triage/__tests__/observation-resolver.test.d.ts.map +1 -0
  184. package/core/dist/runtime-v2/evidence-triage/__tests__/observation-resolver.test.js +181 -0
  185. package/core/dist/runtime-v2/evidence-triage/__tests__/observation-resolver.test.js.map +1 -0
  186. package/core/dist/runtime-v2/evidence-triage/__tests__/triage-policy.test.js +104 -1
  187. package/core/dist/runtime-v2/evidence-triage/__tests__/triage-policy.test.js.map +1 -1
  188. package/core/dist/runtime-v2/evidence-triage/index.d.ts +3 -0
  189. package/core/dist/runtime-v2/evidence-triage/index.d.ts.map +1 -1
  190. package/core/dist/runtime-v2/evidence-triage/index.js +3 -0
  191. package/core/dist/runtime-v2/evidence-triage/index.js.map +1 -1
  192. package/core/dist/runtime-v2/evidence-triage/observation-resolver.d.ts +128 -0
  193. package/core/dist/runtime-v2/evidence-triage/observation-resolver.d.ts.map +1 -0
  194. package/core/dist/runtime-v2/evidence-triage/observation-resolver.js +203 -0
  195. package/core/dist/runtime-v2/evidence-triage/observation-resolver.js.map +1 -0
  196. package/core/dist/runtime-v2/evidence-triage/source-descriptors.d.ts +1 -1
  197. package/core/dist/runtime-v2/evidence-triage/source-descriptors.js +1 -1
  198. package/core/dist/runtime-v2/evidence-triage/triage-policy.d.ts +4 -0
  199. package/core/dist/runtime-v2/evidence-triage/triage-policy.d.ts.map +1 -1
  200. package/core/dist/runtime-v2/evidence-triage/triage-policy.js +66 -9
  201. package/core/dist/runtime-v2/evidence-triage/triage-policy.js.map +1 -1
  202. package/core/dist/runtime-v2/evidence-triage/types.d.ts +14 -0
  203. package/core/dist/runtime-v2/evidence-triage/types.d.ts.map +1 -1
  204. package/core/dist/runtime-v2/evidence-triage/types.js.map +1 -1
  205. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js +56 -4
  206. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js.map +1 -1
  207. package/core/dist/runtime-v2/feature-flags/__tests__/intent-engineering-flag.test.d.ts +2 -0
  208. package/core/dist/runtime-v2/feature-flags/__tests__/intent-engineering-flag.test.d.ts.map +1 -0
  209. package/core/dist/runtime-v2/feature-flags/__tests__/intent-engineering-flag.test.js +30 -0
  210. package/core/dist/runtime-v2/feature-flags/__tests__/intent-engineering-flag.test.js.map +1 -0
  211. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
  212. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js +11 -2
  213. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
  214. package/core/dist/runtime-v2/feature-flags/plugin-surface-registry.d.ts.map +1 -1
  215. package/core/dist/runtime-v2/feature-flags/plugin-surface-registry.js +0 -9
  216. package/core/dist/runtime-v2/feature-flags/plugin-surface-registry.js.map +1 -1
  217. package/core/dist/runtime-v2/feedback/__tests__/redact-sensitive.test.d.ts +15 -0
  218. package/core/dist/runtime-v2/feedback/__tests__/redact-sensitive.test.d.ts.map +1 -0
  219. package/core/dist/runtime-v2/feedback/__tests__/redact-sensitive.test.js +450 -0
  220. package/core/dist/runtime-v2/feedback/__tests__/redact-sensitive.test.js.map +1 -0
  221. package/core/dist/runtime-v2/feedback/__tests__/render-github-url.test.d.ts +13 -0
  222. package/core/dist/runtime-v2/feedback/__tests__/render-github-url.test.d.ts.map +1 -0
  223. package/core/dist/runtime-v2/feedback/__tests__/render-github-url.test.js +243 -0
  224. package/core/dist/runtime-v2/feedback/__tests__/render-github-url.test.js.map +1 -0
  225. package/core/dist/runtime-v2/feedback/__tests__/safe-stringify.test.d.ts +12 -0
  226. package/core/dist/runtime-v2/feedback/__tests__/safe-stringify.test.d.ts.map +1 -0
  227. package/core/dist/runtime-v2/feedback/__tests__/safe-stringify.test.js +172 -0
  228. package/core/dist/runtime-v2/feedback/__tests__/safe-stringify.test.js.map +1 -0
  229. package/core/dist/runtime-v2/index.d.ts +15 -6
  230. package/core/dist/runtime-v2/index.d.ts.map +1 -1
  231. package/core/dist/runtime-v2/index.js +15 -4
  232. package/core/dist/runtime-v2/index.js.map +1 -1
  233. package/core/dist/runtime-v2/intent/__tests__/intent-decision-record.test.d.ts +2 -0
  234. package/core/dist/runtime-v2/intent/__tests__/intent-decision-record.test.d.ts.map +1 -0
  235. package/core/dist/runtime-v2/intent/__tests__/intent-decision-record.test.js +185 -0
  236. package/core/dist/runtime-v2/intent/__tests__/intent-decision-record.test.js.map +1 -0
  237. package/core/dist/runtime-v2/intent/__tests__/intent-doc.test.d.ts +2 -0
  238. package/core/dist/runtime-v2/intent/__tests__/intent-doc.test.d.ts.map +1 -0
  239. package/core/dist/runtime-v2/intent/__tests__/intent-doc.test.js +91 -0
  240. package/core/dist/runtime-v2/intent/__tests__/intent-doc.test.js.map +1 -0
  241. package/core/dist/runtime-v2/intent/__tests__/intent-friction-block.test.d.ts +2 -0
  242. package/core/dist/runtime-v2/intent/__tests__/intent-friction-block.test.d.ts.map +1 -0
  243. package/core/dist/runtime-v2/intent/__tests__/intent-friction-block.test.js +168 -0
  244. package/core/dist/runtime-v2/intent/__tests__/intent-friction-block.test.js.map +1 -0
  245. package/core/dist/runtime-v2/intent/__tests__/intent-patch-proposal.test.d.ts +2 -0
  246. package/core/dist/runtime-v2/intent/__tests__/intent-patch-proposal.test.d.ts.map +1 -0
  247. package/core/dist/runtime-v2/intent/__tests__/intent-patch-proposal.test.js +121 -0
  248. package/core/dist/runtime-v2/intent/__tests__/intent-patch-proposal.test.js.map +1 -0
  249. package/core/dist/runtime-v2/intent/index.d.ts +6 -0
  250. package/core/dist/runtime-v2/intent/index.d.ts.map +1 -0
  251. package/core/dist/runtime-v2/intent/index.js +6 -0
  252. package/core/dist/runtime-v2/intent/index.js.map +1 -0
  253. package/core/dist/runtime-v2/intent/intent-decision-record.d.ts +125 -0
  254. package/core/dist/runtime-v2/intent/intent-decision-record.d.ts.map +1 -0
  255. package/core/dist/runtime-v2/intent/intent-decision-record.js +21 -0
  256. package/core/dist/runtime-v2/intent/intent-decision-record.js.map +1 -0
  257. package/core/dist/runtime-v2/intent/intent-doc-reader-port.d.ts +95 -0
  258. package/core/dist/runtime-v2/intent/intent-doc-reader-port.d.ts.map +1 -0
  259. package/core/dist/runtime-v2/intent/intent-doc-reader-port.js +43 -0
  260. package/core/dist/runtime-v2/intent/intent-doc-reader-port.js.map +1 -0
  261. package/core/dist/runtime-v2/intent/intent-doc.d.ts +19 -0
  262. package/core/dist/runtime-v2/intent/intent-doc.d.ts.map +1 -0
  263. package/core/dist/runtime-v2/intent/intent-doc.js +70 -0
  264. package/core/dist/runtime-v2/intent/intent-doc.js.map +1 -0
  265. package/core/dist/runtime-v2/intent/intent-friction-block.d.ts +63 -0
  266. package/core/dist/runtime-v2/intent/intent-friction-block.d.ts.map +1 -0
  267. package/core/dist/runtime-v2/intent/intent-friction-block.js +129 -0
  268. package/core/dist/runtime-v2/intent/intent-friction-block.js.map +1 -0
  269. package/core/dist/runtime-v2/intent/intent-patch-proposal.d.ts +42 -0
  270. package/core/dist/runtime-v2/intent/intent-patch-proposal.d.ts.map +1 -0
  271. package/core/dist/runtime-v2/intent/intent-patch-proposal.js +81 -0
  272. package/core/dist/runtime-v2/intent/intent-patch-proposal.js.map +1 -0
  273. package/core/dist/runtime-v2/internalization/__tests__/__fixtures__/intent-tension-cases.d.ts +54 -0
  274. package/core/dist/runtime-v2/internalization/__tests__/__fixtures__/intent-tension-cases.d.ts.map +1 -0
  275. package/core/dist/runtime-v2/internalization/__tests__/__fixtures__/intent-tension-cases.js +219 -0
  276. package/core/dist/runtime-v2/internalization/__tests__/__fixtures__/intent-tension-cases.js.map +1 -0
  277. package/core/dist/runtime-v2/internalization/__tests__/c2-live-runner-chain.test.d.ts +2 -0
  278. package/core/dist/runtime-v2/internalization/__tests__/c2-live-runner-chain.test.d.ts.map +1 -0
  279. package/core/dist/runtime-v2/internalization/__tests__/c2-live-runner-chain.test.js +306 -0
  280. package/core/dist/runtime-v2/internalization/__tests__/c2-live-runner-chain.test.js.map +1 -0
  281. package/core/dist/runtime-v2/internalization/__tests__/diag-rootcause-intent-tension.test.d.ts +2 -0
  282. package/core/dist/runtime-v2/internalization/__tests__/diag-rootcause-intent-tension.test.d.ts.map +1 -0
  283. package/core/dist/runtime-v2/internalization/__tests__/diag-rootcause-intent-tension.test.js +360 -0
  284. package/core/dist/runtime-v2/internalization/__tests__/diag-rootcause-intent-tension.test.js.map +1 -0
  285. package/core/dist/runtime-v2/internalization/__tests__/diag-router-intent-tension.test.d.ts +2 -0
  286. package/core/dist/runtime-v2/internalization/__tests__/diag-router-intent-tension.test.d.ts.map +1 -0
  287. package/core/dist/runtime-v2/internalization/__tests__/diag-router-intent-tension.test.js +333 -0
  288. package/core/dist/runtime-v2/internalization/__tests__/diag-router-intent-tension.test.js.map +1 -0
  289. package/core/dist/runtime-v2/internalization/__tests__/intent-tension-cases.test.d.ts +2 -0
  290. package/core/dist/runtime-v2/internalization/__tests__/intent-tension-cases.test.d.ts.map +1 -0
  291. package/core/dist/runtime-v2/internalization/__tests__/intent-tension-cases.test.js +113 -0
  292. package/core/dist/runtime-v2/internalization/__tests__/intent-tension-cases.test.js.map +1 -0
  293. package/core/dist/runtime-v2/internalization/diag-rootcause-runner.d.ts +13 -0
  294. package/core/dist/runtime-v2/internalization/diag-rootcause-runner.d.ts.map +1 -1
  295. package/core/dist/runtime-v2/internalization/diag-rootcause-runner.js +42 -0
  296. package/core/dist/runtime-v2/internalization/diag-rootcause-runner.js.map +1 -1
  297. package/core/dist/runtime-v2/internalization/diag-router-runner.d.ts.map +1 -1
  298. package/core/dist/runtime-v2/internalization/diag-router-runner.js +27 -0
  299. package/core/dist/runtime-v2/internalization/diag-router-runner.js.map +1 -1
  300. package/core/dist/runtime-v2/internalization/index.d.ts +0 -16
  301. package/core/dist/runtime-v2/internalization/index.d.ts.map +1 -1
  302. package/core/dist/runtime-v2/internalization/index.js +0 -8
  303. package/core/dist/runtime-v2/internalization/index.js.map +1 -1
  304. package/core/dist/runtime-v2/pain-gate/__tests__/pain-diagnostic-gate-policy.test.d.ts +15 -0
  305. package/core/dist/runtime-v2/pain-gate/__tests__/pain-diagnostic-gate-policy.test.d.ts.map +1 -0
  306. package/core/dist/runtime-v2/pain-gate/__tests__/pain-diagnostic-gate-policy.test.js +179 -0
  307. package/core/dist/runtime-v2/pain-gate/__tests__/pain-diagnostic-gate-policy.test.js.map +1 -0
  308. package/core/dist/runtime-v2/pain-gate/index.d.ts +10 -0
  309. package/core/dist/runtime-v2/pain-gate/index.d.ts.map +1 -0
  310. package/core/dist/runtime-v2/pain-gate/index.js +9 -0
  311. package/core/dist/runtime-v2/pain-gate/index.js.map +1 -0
  312. package/core/dist/runtime-v2/pain-gate/pain-diagnostic-gate-policy.d.ts +121 -0
  313. package/core/dist/runtime-v2/pain-gate/pain-diagnostic-gate-policy.d.ts.map +1 -0
  314. package/core/dist/runtime-v2/pain-gate/pain-diagnostic-gate-policy.js +157 -0
  315. package/core/dist/runtime-v2/pain-gate/pain-diagnostic-gate-policy.js.map +1 -0
  316. package/core/dist/runtime-v2/pain-signal-bridge.d.ts.map +1 -1
  317. package/core/dist/runtime-v2/pain-signal-bridge.js +14 -88
  318. package/core/dist/runtime-v2/pain-signal-bridge.js.map +1 -1
  319. package/core/dist/runtime-v2/pain-signal-observability.d.ts.map +1 -1
  320. package/core/dist/runtime-v2/pain-signal-observability.js +272 -61
  321. package/core/dist/runtime-v2/pain-signal-observability.js.map +1 -1
  322. package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts +12 -0
  323. package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts.map +1 -1
  324. package/core/dist/runtime-v2/pain-signal-runtime-factory.js +1 -1
  325. package/core/dist/runtime-v2/pain-signal-runtime-factory.js.map +1 -1
  326. package/core/dist/runtime-v2/pain-to-principle-service.d.ts +6 -0
  327. package/core/dist/runtime-v2/pain-to-principle-service.d.ts.map +1 -1
  328. package/core/dist/runtime-v2/pain-to-principle-service.js +2 -0
  329. package/core/dist/runtime-v2/pain-to-principle-service.js.map +1 -1
  330. package/core/dist/runtime-v2/principle-tree/ledger-codec.js.map +1 -1
  331. package/core/dist/runtime-v2/proven-channel-baseline.js +1 -1
  332. package/core/dist/runtime-v2/proven-channel-baseline.js.map +1 -1
  333. package/core/dist/runtime-v2/store/artifact/__tests__/sqlite-pi-artifact-store-fk.test.d.ts +2 -0
  334. package/core/dist/runtime-v2/store/artifact/__tests__/sqlite-pi-artifact-store-fk.test.d.ts.map +1 -0
  335. package/core/dist/runtime-v2/store/artifact/__tests__/sqlite-pi-artifact-store-fk.test.js +55 -0
  336. package/core/dist/runtime-v2/store/artifact/__tests__/sqlite-pi-artifact-store-fk.test.js.map +1 -0
  337. package/core/dist/runtime-v2/store/artifact/sqlite-pi-artifact-store.d.ts.map +1 -1
  338. package/core/dist/runtime-v2/store/artifact/sqlite-pi-artifact-store.js +6 -0
  339. package/core/dist/runtime-v2/store/artifact/sqlite-pi-artifact-store.js.map +1 -1
  340. package/core/dist/runtime-v2/store/intent/__tests__/sqlite-intent-decision-store.test.d.ts +2 -0
  341. package/core/dist/runtime-v2/store/intent/__tests__/sqlite-intent-decision-store.test.d.ts.map +1 -0
  342. package/core/dist/runtime-v2/store/intent/__tests__/sqlite-intent-decision-store.test.js +272 -0
  343. package/core/dist/runtime-v2/store/intent/__tests__/sqlite-intent-decision-store.test.js.map +1 -0
  344. package/core/dist/runtime-v2/store/intent/index.d.ts +6 -0
  345. package/core/dist/runtime-v2/store/intent/index.d.ts.map +1 -0
  346. package/core/dist/runtime-v2/store/intent/index.js +5 -0
  347. package/core/dist/runtime-v2/store/intent/index.js.map +1 -0
  348. package/core/dist/runtime-v2/store/intent/sqlite-intent-decision-store.d.ts +51 -0
  349. package/core/dist/runtime-v2/store/intent/sqlite-intent-decision-store.d.ts.map +1 -0
  350. package/core/dist/runtime-v2/store/intent/sqlite-intent-decision-store.js +306 -0
  351. package/core/dist/runtime-v2/store/intent/sqlite-intent-decision-store.js.map +1 -0
  352. package/core/dist/runtime-v2/store/sqlite-connection-pragma.test.js +14 -3
  353. package/core/dist/runtime-v2/store/sqlite-connection-pragma.test.js.map +1 -1
  354. package/core/dist/runtime-v2/store/sqlite-connection-schema-version.test.d.ts +2 -0
  355. package/core/dist/runtime-v2/store/sqlite-connection-schema-version.test.d.ts.map +1 -0
  356. package/core/dist/runtime-v2/store/sqlite-connection-schema-version.test.js +72 -0
  357. package/core/dist/runtime-v2/store/sqlite-connection-schema-version.test.js.map +1 -0
  358. package/core/dist/runtime-v2/store/sqlite-connection.d.ts +27 -0
  359. package/core/dist/runtime-v2/store/sqlite-connection.d.ts.map +1 -1
  360. package/core/dist/runtime-v2/store/sqlite-connection.js +124 -12
  361. package/core/dist/runtime-v2/store/sqlite-connection.js.map +1 -1
  362. package/core/dist/runtime-v2/types/event-payload.d.ts +1 -20
  363. package/core/dist/runtime-v2/types/event-payload.d.ts.map +1 -1
  364. package/core/dist/runtime-v2/types/event-payload.js +0 -12
  365. package/core/dist/runtime-v2/types/event-payload.js.map +1 -1
  366. package/core/dist/runtime-v2/types/event-types.d.ts +5 -61
  367. package/core/dist/runtime-v2/types/event-types.d.ts.map +1 -1
  368. package/core/dist/runtime-v2/types/event-types.js +2 -36
  369. package/core/dist/runtime-v2/types/event-types.js.map +1 -1
  370. package/core/dist/runtime-v2/types/evidence-chain-contract.d.ts +63 -0
  371. package/core/dist/runtime-v2/types/evidence-chain-contract.d.ts.map +1 -1
  372. package/core/dist/runtime-v2/types/evidence-chain-contract.js +234 -9
  373. package/core/dist/runtime-v2/types/evidence-chain-contract.js.map +1 -1
  374. package/core/dist/runtime-v2/types/index.d.ts +5 -5
  375. package/core/dist/runtime-v2/types/index.d.ts.map +1 -1
  376. package/core/dist/runtime-v2/types/index.js +7 -3
  377. package/core/dist/runtime-v2/types/index.js.map +1 -1
  378. package/core/dist/runtime-v2/types/ledger-store.d.ts +30 -30
  379. package/core/dist/runtime-v2/types/ledger-store.d.ts.map +1 -1
  380. package/core/dist/runtime-v2/types/ledger-store.js +10 -5
  381. package/core/dist/runtime-v2/types/ledger-store.js.map +1 -1
  382. package/core/dist/runtime-v2/types/pain-signal.d.ts +2 -2
  383. package/core/dist/runtime-v2/types/pain-signal.js +2 -2
  384. package/core/dist/workflow-funnel-loader.d.ts +2 -2
  385. package/core/dist/workflow-funnel-loader.d.ts.map +1 -1
  386. package/dist/installer.d.ts.map +1 -1
  387. package/dist/installer.js +16 -0
  388. package/dist/installer.js.map +1 -1
  389. package/dist/mvp-config.d.ts +0 -10
  390. package/dist/mvp-config.d.ts.map +1 -1
  391. package/dist/mvp-config.js +0 -65
  392. package/dist/mvp-config.js.map +1 -1
  393. package/package.json +1 -1
  394. package/pd-cli/dist/commands/__tests__/intent-flag-wiring.test.d.ts +9 -0
  395. package/pd-cli/dist/commands/__tests__/intent-flag-wiring.test.d.ts.map +1 -0
  396. package/pd-cli/dist/commands/__tests__/intent-flag-wiring.test.js +166 -0
  397. package/pd-cli/dist/commands/__tests__/intent-flag-wiring.test.js.map +1 -0
  398. package/pd-cli/dist/commands/intent.d.ts +59 -0
  399. package/pd-cli/dist/commands/intent.d.ts.map +1 -0
  400. package/pd-cli/dist/commands/intent.js +350 -0
  401. package/pd-cli/dist/commands/intent.js.map +1 -0
  402. package/pd-cli/dist/commands/mvp-smoke.js +1 -1
  403. package/pd-cli/dist/commands/mvp-smoke.js.map +1 -1
  404. package/pd-cli/dist/commands/rulecode.js +1 -1
  405. package/pd-cli/dist/commands/rulecode.js.map +1 -1
  406. package/pd-cli/dist/commands/runtime-canary.d.ts.map +1 -1
  407. package/pd-cli/dist/commands/runtime-canary.js +10 -11
  408. package/pd-cli/dist/commands/runtime-canary.js.map +1 -1
  409. package/pd-cli/dist/commands/runtime-init.d.ts +43 -0
  410. package/pd-cli/dist/commands/runtime-init.d.ts.map +1 -0
  411. package/pd-cli/dist/commands/runtime-init.js +264 -0
  412. package/pd-cli/dist/commands/runtime-init.js.map +1 -0
  413. package/pd-cli/dist/commands/runtime-internalization-queue.d.ts.map +1 -1
  414. package/pd-cli/dist/commands/runtime-internalization-queue.js +13 -16
  415. package/pd-cli/dist/commands/runtime-internalization-queue.js.map +1 -1
  416. package/pd-cli/dist/commands/runtime-internalization-run-once.d.ts.map +1 -1
  417. package/pd-cli/dist/commands/runtime-internalization-run-once.js +3 -0
  418. package/pd-cli/dist/commands/runtime-internalization-run-once.js.map +1 -1
  419. package/pd-cli/dist/commands/runtime-internalization-run-rulehost.d.ts.map +1 -1
  420. package/pd-cli/dist/commands/runtime-internalization-run-rulehost.js +61 -7
  421. package/pd-cli/dist/commands/runtime-internalization-run-rulehost.js.map +1 -1
  422. package/pd-cli/dist/commands/runtime.js +1 -1
  423. package/pd-cli/dist/commands/runtime.js.map +1 -1
  424. package/pd-cli/dist/index.js +92 -34
  425. package/pd-cli/dist/index.js.map +1 -1
  426. package/pd-cli/dist/services/__tests__/rulehost-readiness.test.d.ts +2 -0
  427. package/pd-cli/dist/services/__tests__/rulehost-readiness.test.d.ts.map +1 -0
  428. package/pd-cli/dist/services/__tests__/rulehost-readiness.test.js +314 -0
  429. package/pd-cli/dist/services/__tests__/rulehost-readiness.test.js.map +1 -0
  430. package/pd-cli/dist/services/__tests__/runtime-adapter-resolver.test.js +20 -12
  431. package/pd-cli/dist/services/__tests__/runtime-adapter-resolver.test.js.map +1 -1
  432. package/pd-cli/dist/services/demo-story-a-runner.d.ts.map +1 -1
  433. package/pd-cli/dist/services/demo-story-a-runner.js +6 -0
  434. package/pd-cli/dist/services/demo-story-a-runner.js.map +1 -1
  435. package/pd-cli/dist/services/rulehost-readiness.d.ts +62 -0
  436. package/pd-cli/dist/services/rulehost-readiness.d.ts.map +1 -0
  437. package/pd-cli/dist/services/rulehost-readiness.js +214 -0
  438. package/pd-cli/dist/services/rulehost-readiness.js.map +1 -0
  439. package/pd-cli/dist/services/runtime-adapter-resolver.d.ts +1 -1
  440. package/pd-cli/dist/services/runtime-adapter-resolver.js +3 -3
  441. package/pd-cli/dist/services/runtime-adapter-resolver.js.map +1 -1
  442. package/pd-cli/package.json +1 -0
  443. package/plugin/dist/commands/evolution-status.js +0 -2
  444. package/plugin/dist/commands/pain.js +2 -0
  445. package/plugin/dist/core/control-ui-db.d.ts +11 -0
  446. package/plugin/dist/core/control-ui-db.js +40 -16
  447. package/plugin/dist/core/detection-funnel.d.ts +25 -11
  448. package/plugin/dist/core/detection-funnel.js +32 -80
  449. package/plugin/dist/core/event-log.d.ts +1 -3
  450. package/plugin/dist/core/event-log.js +5 -21
  451. package/plugin/dist/core/evolution-reducer.d.ts +0 -8
  452. package/plugin/dist/core/evolution-reducer.js +9 -19
  453. package/plugin/dist/core/intent-doc-reader-adapter.d.ts +28 -0
  454. package/plugin/dist/core/intent-doc-reader-adapter.js +56 -0
  455. package/plugin/dist/core/intent-doc-reader.d.ts +80 -0
  456. package/plugin/dist/core/intent-doc-reader.js +189 -0
  457. package/plugin/dist/core/pain-diagnostic-gate.d.ts +37 -28
  458. package/plugin/dist/core/pain-diagnostic-gate.js +53 -89
  459. package/plugin/dist/core/pain.d.ts +0 -63
  460. package/plugin/dist/core/pain.js +0 -167
  461. package/plugin/dist/core/paths.d.ts +0 -1
  462. package/plugin/dist/core/paths.js +2 -1
  463. package/plugin/dist/core/principle-tree-ledger.d.ts +27 -79
  464. package/plugin/dist/core/principle-tree-ledger.js +39 -524
  465. package/plugin/dist/core/reflection/reflection-context.d.ts +2 -2
  466. package/plugin/dist/core/schema/migrations/001-init-trajectory.js +3 -6
  467. package/plugin/dist/core/schema/schema-definitions.js +4 -9
  468. package/plugin/dist/core/trajectory.d.ts +16 -16
  469. package/plugin/dist/core/trajectory.js +338 -311
  470. package/plugin/dist/core/workspace-context.d.ts +2 -3
  471. package/plugin/dist/hooks/after-tool-call-helpers.d.ts +4 -1
  472. package/plugin/dist/hooks/after-tool-call-helpers.js +13 -17
  473. package/plugin/dist/hooks/gate-block-helper.js +57 -17
  474. package/plugin/dist/hooks/lifecycle.js +3 -6
  475. package/plugin/dist/hooks/llm.js +66 -26
  476. package/plugin/dist/hooks/pain.d.ts +3 -1
  477. package/plugin/dist/hooks/pain.js +124 -49
  478. package/plugin/dist/hooks/prompt-helpers.d.ts +105 -0
  479. package/plugin/dist/hooks/prompt-helpers.js +288 -0
  480. package/plugin/dist/hooks/prompt-types.d.ts +74 -0
  481. package/plugin/dist/hooks/prompt-types.js +12 -0
  482. package/plugin/dist/hooks/prompt.d.ts +7 -38
  483. package/plugin/dist/hooks/prompt.js +433 -338
  484. package/plugin/dist/hooks/raw-observation-adapter.d.ts +9 -50
  485. package/plugin/dist/hooks/raw-observation-adapter.js +9 -164
  486. package/plugin/dist/hooks/raw-observation-types.d.ts +6 -57
  487. package/plugin/dist/hooks/raw-observation-types.js +5 -9
  488. package/plugin/dist/hooks/triage-adapter.js +6 -26
  489. package/plugin/dist/hooks/trigger-cooldown-tracker.d.ts +12 -0
  490. package/plugin/dist/hooks/trigger-cooldown-tracker.js +25 -0
  491. package/plugin/dist/index.d.ts +3 -1
  492. package/plugin/dist/index.js +9 -5
  493. package/plugin/dist/service/evolution-worker.js +6 -64
  494. package/plugin/dist/service/runtime-summary-service.d.ts +0 -2
  495. package/plugin/dist/service/runtime-summary-service.js +1 -5
  496. package/plugin/dist/service/subagent-workflow/workflow-store.d.ts +14 -0
  497. package/plugin/dist/service/subagent-workflow/workflow-store.js +91 -2
  498. package/plugin/dist/types/event-types.d.ts +1 -1
  499. package/plugin/package.json +6 -3
  500. package/plugin/scripts/acceptance-test.mjs +3 -3
  501. package/plugin/scripts/sync-plugin.mjs +33 -22
  502. package/plugin/templates/langs/en/skills/pd-cli-operator/SKILL.md +20 -11
  503. package/plugin/templates/langs/en/skills/pd-runtime-v2/SKILL.md +10 -0
  504. package/plugin/templates/langs/zh/skills/pd-cli-operator/SKILL.md +20 -11
  505. package/plugin/templates/langs/zh/skills/pd-runtime-v2/SKILL.md +10 -0
  506. package/console/dist/server/config/feature-flags.d.ts +0 -25
  507. package/console/dist/server/config/feature-flags.js +0 -101
  508. package/pd-cli/dist/commands/central-sync.d.ts +0 -10
  509. package/pd-cli/dist/commands/central-sync.d.ts.map +0 -1
  510. package/pd-cli/dist/commands/central-sync.js +0 -32
  511. package/pd-cli/dist/commands/central-sync.js.map +0 -1
  512. package/pd-cli/dist/services/feature-flag-loader.d.ts +0 -6
  513. package/pd-cli/dist/services/feature-flag-loader.d.ts.map +0 -1
  514. package/pd-cli/dist/services/feature-flag-loader.js +0 -53
  515. package/pd-cli/dist/services/feature-flag-loader.js.map +0 -1
  516. package/plugin/dist/core/observability.d.ts +0 -40
  517. package/plugin/dist/core/observability.js +0 -164
  518. package/plugin/dist/core/principle-tree-ledger-adapter.d.ts +0 -32
  519. package/plugin/dist/core/principle-tree-ledger-adapter.js +0 -125
  520. package/plugin/dist/hooks/subagent.d.ts +0 -9
  521. package/plugin/dist/hooks/subagent.js +0 -122
  522. package/plugin/dist/service/central-database.d.ts +0 -138
  523. package/plugin/dist/service/central-database.js +0 -731
  524. package/plugin/dist/service/central-sync-service.d.ts +0 -8
  525. package/plugin/dist/service/central-sync-service.js +0 -71
  526. package/plugin/scripts/validate-live-path.ts +0 -480
@@ -86,9 +86,12 @@ export declare function evaluatePainAdmissionForToolCall(event: PluginHookAfterT
86
86
  *
87
87
  * Only called when the admission decision is 'admitted'.
88
88
  */
89
- export declare function emitPainIfAdmitted(wctx: WorkspaceContext, event: PluginHookAfterToolCallEvent, observation: ToolCallObservation, outcome: ToolCallOutcome, admission: PainAdmissionDecision, sessionId: string, agentId: string | undefined, workspaceDir: string, emitPainDetectedEvent: (wctx: WorkspaceContext, event: import('../core/evolution-types.js').EvolutionLoopEvent) => Promise<void>): void;
89
+ export declare function emitPainIfAdmitted(wctx: WorkspaceContext, event: PluginHookAfterToolCallEvent, observation: ToolCallObservation, outcome: ToolCallOutcome, admission: PainAdmissionDecision, sessionId: string, agentId: string | undefined, workspaceDir: string, emitPainDetectedEvent: (wctx: WorkspaceContext, event: import('../core/evolution-types.js').EvolutionLoopEvent, options?: {
90
+ recordObservability?: boolean;
91
+ }) => Promise<void>): void;
90
92
  export { buildTrajectoryEvidence } from './trajectory-evidence.js';
91
93
  /**
92
94
  * Reset trigger cooldown state (for tests).
95
+ * PRI-454: Delegates to shared cooldown Map reset.
93
96
  */
94
97
  export declare function resetTriggerCooldownForTest(): void;
@@ -19,7 +19,7 @@ import { denoiseError, computeHash } from '../utils/hashing.js';
19
19
  import { SystemLogger } from '../core/system-logger.js';
20
20
  import { getEvolutionLogger, createTraceId } from '../core/evolution-logger.js';
21
21
  import { recordEvolutionSuccess, recordEvolutionFailure } from '../core/evolution-engine.js';
22
- import { isCooldownActive as isTriggerCooldownActive, markEpisodeAsDiagnosed, clearCooldownState } from './trigger-cooldown-tracker.js';
22
+ import { isSharedCooldownActive, markSharedEpisodeAsDiagnosed, resetSharedCooldownForTest } from './trigger-cooldown-tracker.js';
23
23
  import { sanitizeForEvidence, sanitizeToolParamsForEvidence } from './message-sanitize.js';
24
24
  import { resolveSourceKind, buildToolFailureObservation } from './raw-observation-adapter.js';
25
25
  import { evaluateEvidenceTriage } from './triage-adapter.js';
@@ -313,15 +313,6 @@ export function handleProbationFeedback(sessionId, toolName, workspaceDir, wctx,
313
313
  }
314
314
  // ── Stage 6: Pain Admission ─────────────────────────────────────────────────
315
315
  const WRITE_TOOLS = ['write', 'edit', 'apply_patch', 'write_file', 'edit_file', 'replace'];
316
- /**
317
- * Cooldown map for trigger controller decisions.
318
- *
319
- * PRI-363: This replaces the hidden map in PainDiagnosticGate.
320
- * Core trigger-controller is stateless; plugin layer owns cooldown state.
321
- *
322
- * EP-05: Loop state freshness — each check reads fresh state from this map.
323
- */
324
- const TRIGGER_COOLDOWN_MAP = new Map();
325
316
  /**
326
317
  * Evaluate whether a tool failure should trigger pain diagnosis.
327
318
  *
@@ -346,8 +337,8 @@ export function evaluatePainAdmissionForToolCall(event, observation, outcome, la
346
337
  };
347
338
  }
348
339
  const failureSource = outcome.failureSource ?? 'tool_failure';
349
- // Check cooldown before calling trigger controller
350
- const cooldownActive = isTriggerCooldownActive(failureSource, sessionId, latestFailureState?.lastErrorHash, TRIGGER_COOLDOWN_MAP);
340
+ // Check cooldown before calling trigger controller (PRI-454: shared Map)
341
+ const cooldownActive = isSharedCooldownActive(failureSource, sessionId, latestFailureState?.lastErrorHash);
351
342
  // PRI-360 S1: Build RawObservation for unified source mapping
352
343
  const rawObs = {
353
344
  observedAt: new Date().toISOString(),
@@ -386,9 +377,9 @@ export function evaluatePainAdmissionForToolCall(event, observation, outcome, la
386
377
  tool: event.toolName,
387
378
  path: observation.relPath,
388
379
  }));
389
- // If trigger controller says yes, mark cooldown and admit
380
+ // If trigger controller says yes, mark cooldown and admit (PRI-454: shared Map)
390
381
  if (triggerDecision.shouldCreateDiagnosticTask) {
391
- markEpisodeAsDiagnosed(failureSource, sessionId, latestFailureState?.lastErrorHash, TRIGGER_COOLDOWN_MAP);
382
+ markSharedEpisodeAsDiagnosed(failureSource, sessionId, latestFailureState?.lastErrorHash);
392
383
  return {
393
384
  admitted: true,
394
385
  stage: 'trigger_admitted',
@@ -417,6 +408,9 @@ export function emitPainIfAdmitted(wctx, event, observation, outcome, admission,
417
408
  if (!admission.admitted)
418
409
  return;
419
410
  const failureSource = outcome.failureSource ?? 'tool_failure';
411
+ // PRI-453: Generate painId early so it can be passed as canonicalPainId to
412
+ // recordPainEvent, enabling dedup between legacy trajectory write and SDK path.
413
+ const painId = `pain_${Date.now()}_${observation.errorHash.slice(0, 8)}`;
420
414
  // Record to trajectory before Runtime V2 diagnosis
421
415
  wctx.trajectory?.recordPainEvent({
422
416
  sessionId,
@@ -426,6 +420,7 @@ export function emitPainIfAdmitted(wctx, event, observation, outcome, admission,
426
420
  severity: observation.painScore >= 70 ? 'severe' : observation.painScore >= 40 ? 'moderate' : 'mild',
427
421
  origin: 'system_infer',
428
422
  text: sanitizeForEvidence(observation.params.text ?? observation.params.content, workspaceDir) || undefined,
423
+ canonicalPainId: painId,
429
424
  });
430
425
  // Observe: track which principles would have prevented this pain (observation-only)
431
426
  try {
@@ -481,7 +476,7 @@ export function emitPainIfAdmitted(wctx, event, observation, outcome, admission,
481
476
  sessionId,
482
477
  });
483
478
  // Create painId inline (matches original createPainId)
484
- const painId = `pain_${Date.now()}_${observation.errorHash.slice(0, 8)}`;
479
+ // PRI-453: painId is now generated early (above) to pass as canonicalPainId.
485
480
  emitPainDetectedEvent(wctx, {
486
481
  ts: new Date().toISOString(),
487
482
  type: 'pain_detected',
@@ -497,15 +492,16 @@ export function emitPainIfAdmitted(wctx, event, observation, outcome, admission,
497
492
  provenance: 'automatic_hook',
498
493
  evidence: buildTrajectoryEvidence(wctx, sessionId),
499
494
  },
500
- });
495
+ }, { recordObservability: false });
501
496
  }
502
497
  // ── Shared Helpers ──────────────────────────────────────────────────────────
503
498
  export { buildTrajectoryEvidence } from './trajectory-evidence.js';
504
499
  /**
505
500
  * Reset trigger cooldown state (for tests).
501
+ * PRI-454: Delegates to shared cooldown Map reset.
506
502
  */
507
503
  export function resetTriggerCooldownForTest() {
508
- clearCooldownState(TRIGGER_COOLDOWN_MAP);
504
+ resetSharedCooldownForTest();
509
505
  }
510
506
  // ── Source Classification ────────────────────────────────────────────────────
511
507
  // classifyToolFailureSource logic is now in resolveSourceKind (PRI-360 S1)
@@ -15,6 +15,8 @@ import { evaluatePainDiagnosticGate } from '../core/pain-diagnostic-gate.js';
15
15
  import { emitPainDetectedEvent } from './pain.js';
16
16
  import { loadFeatureFlagFromConfig } from '../core/pd-config-loader.js';
17
17
  import { evaluateEvidenceTriage } from './triage-adapter.js';
18
+ import { evaluateTriggerController } from '@principles/core/runtime-v2';
19
+ import { isSharedCooldownActive, markSharedEpisodeAsDiagnosed } from './trigger-cooldown-tracker.js';
18
20
  import { isRisky } from '../utils/io.js';
19
21
  import { normalizeProfile } from '../core/profile.js';
20
22
  import { SystemLogger } from '../core/system-logger.js';
@@ -78,19 +80,19 @@ export function recordGateBlockAndReturn(wctx, blockCtx, logger) {
78
80
  // so one mild block does not start a long diagnostician run.
79
81
  if (sessionId) {
80
82
  const GATE_BLOCK_PAIN_SCORE = 45; // Must be >= pain_trigger (40) so single gate block can trigger diagnosis (PRI-274)
81
- // Record to trajectory (fire-and-forget, no .pain_flag file needed)
82
- wctx.trajectory?.recordPainEvent?.({
83
- sessionId,
84
- source: 'gate_blocked',
85
- score: GATE_BLOCK_PAIN_SCORE,
86
- reason: `Gate blocked ${toolName} on ${filePath}: ${reason}`,
87
- severity: 'mild',
88
- origin: 'system_infer',
89
- });
90
- // PEAT-B1: Evidence triage (feature-flagged)
91
- let triageAdmitted = true;
92
- const gateBlockTriageFlag = loadFeatureFlagFromConfig(wctx.workspaceDir, 'painEvidenceAdmission');
93
- if (gateBlockTriageFlag.enabled) {
83
+ // PRI-453: Generate painId early. SDK observability path (emitPainDetectedEvent
84
+ // with default recordObservability: true) handles all writes: events_*.jsonl +
85
+ // evolution.jsonl + trajectory.db (with canonicalPainId for dedup). No separate
86
+ // legacy recordPainEvent call needed — avoids double-write to trajectory.db.
87
+ const gatePainId = `gate_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
88
+ // PRI-454: Dual-gate migration. When both flags ON → Gate B (TriggerController).
89
+ // When either OFF → Gate A (PainDiagnosticGate, rollback).
90
+ const triageFlag = loadFeatureFlagFromConfig(wctx.workspaceDir, 'painEvidenceAdmission');
91
+ const defaultFlag = loadFeatureFlagFromConfig(wctx.workspaceDir, 'painEvidenceAdmissionDefault');
92
+ const useGateB = triageFlag.enabled && defaultFlag.enabled;
93
+ // PEAT-B1: Evidence triage (runs when Gate B is active)
94
+ const session = getSession(sessionId);
95
+ if (useGateB) {
94
96
  // Load profile with 1MB size guard, matching pain.ts pattern
95
97
  const profilePath = wctx.resolve('PROFILE');
96
98
  let profile = normalizeProfile({});
@@ -115,16 +117,54 @@ export function recordGateBlockAndReturn(wctx, blockCtx, logger) {
115
117
  // weight, NOT the action risk severity. The rulehost principle already determined
116
118
  // this action was important enough to block — that is the real signal.
117
119
  const isUnsafe = isRisky(filePath, profile.risk_paths);
120
+ // PRI-454 P2-1: Pass consecutiveErrors and isRisky to match Gate A's
121
+ // upgrade logic. Rule 3 (consecutiveErrors >= 4 → admit) was being
122
+ // dropped, so non-risky repeated gate blocks never triggered diagnosis.
118
123
  const triage = evaluateEvidenceTriage('rulehost_block', GATE_BLOCK_PAIN_SCORE, {
119
124
  isUnsafeHighConfidence: isUnsafe,
125
+ isRisky: isUnsafe,
126
+ consecutiveErrors: session?.consecutiveErrors,
120
127
  });
121
128
  if (triage.decision !== 'admit') {
122
- triageAdmitted = false;
123
129
  logger.info?.(`[PD_GATE] Triage ${triage.decision}: ${triage.reason}`);
124
130
  }
131
+ else {
132
+ // PRI-454: Gate B path — TriggerController owns admission
133
+ const errorHash = `${toolName}:${filePath}:${reason}`;
134
+ const cooldownActive = isSharedCooldownActive('rulehost_block', sessionId, errorHash);
135
+ const triggerDecision = evaluateTriggerController({
136
+ triageResult: triage,
137
+ isOwnerManual: false,
138
+ isCooldownActive: cooldownActive,
139
+ isValid: true,
140
+ score: GATE_BLOCK_PAIN_SCORE,
141
+ sessionId,
142
+ });
143
+ if (triggerDecision.shouldCreateDiagnosticTask) {
144
+ markSharedEpisodeAsDiagnosed('rulehost_block', sessionId, errorHash);
145
+ void emitPainDetectedEvent(wctx, {
146
+ ts: new Date().toISOString(),
147
+ type: 'pain_detected',
148
+ data: {
149
+ painId: gatePainId,
150
+ painType: 'user_frustration',
151
+ source: 'gate_blocked',
152
+ reason: `Gate blocked ${toolName} on ${filePath}: ${reason}`,
153
+ score: GATE_BLOCK_PAIN_SCORE,
154
+ sessionId,
155
+ agentId: 'main',
156
+ },
157
+ }).catch((emitErr) => {
158
+ logWarn(`[PD_GATE] Failed to emit gate block pain event: ${String(emitErr)}`);
159
+ });
160
+ }
161
+ else {
162
+ logger.info?.(`[PD_GATE] Gate B skipped: ${triggerDecision.reason}`);
163
+ }
164
+ }
125
165
  }
126
- const session = getSession(sessionId);
127
- if (triageAdmitted) {
166
+ else {
167
+ // PRI-454: Gate A path (rollback when either flag is OFF)
128
168
  const gate = evaluatePainDiagnosticGate({
129
169
  source: 'gate_blocked',
130
170
  score: GATE_BLOCK_PAIN_SCORE,
@@ -142,7 +182,7 @@ export function recordGateBlockAndReturn(wctx, blockCtx, logger) {
142
182
  ts: new Date().toISOString(),
143
183
  type: 'pain_detected',
144
184
  data: {
145
- painId: `gate_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`,
185
+ painId: gatePainId,
146
186
  painType: 'user_frustration',
147
187
  source: 'gate_blocked',
148
188
  reason: `Gate blocked ${toolName} on ${filePath}: ${reason}`,
@@ -120,12 +120,9 @@ export async function extractPainFromSessionFile(sessionFile, ctx) {
120
120
  if (!fs.existsSync(dir))
121
121
  fs.mkdirSync(dir, { recursive: true });
122
122
  fs.appendFileSync(dailyLogPath, entry, 'utf8');
123
- const semanticPath = wctx.resolve('SEMANTIC_PAIN');
124
- const semanticDir = path.dirname(semanticPath);
125
- if (!fs.existsSync(semanticDir))
126
- fs.mkdirSync(semanticDir, { recursive: true });
127
- let semanticEntry = `\n### Sample ${timestamp}\n- Source: compaction\n\n\`\`\`\n${painPoints.join('\n---\n')}\n\`\`\`\n`;
128
- fs.appendFileSync(semanticPath, semanticEntry, 'utf8');
123
+ // SEMANTIC_PAIN (confusion_samples.md) write removed (PRI-451 Wave 1):
124
+ // the file had zero readers. The MEMORY.md write above and the fatal-intercept
125
+ // emitPainDetectedEvent below are both LIVE and remain.
129
126
  const hasFatal = painPoints.some(p => p.includes('[FATAL INTERCEPT]'));
130
127
  if (hasFatal) {
131
128
  // Emit via the Runtime v2 pain chain — no .pain_flag file written
@@ -13,6 +13,8 @@ import { evaluatePainDiagnosticGate } from '../core/pain-diagnostic-gate.js';
13
13
  import { loadFeatureFlagFromConfig } from '../core/pd-config-loader.js';
14
14
  import { resolveSourceKind } from './raw-observation-adapter.js';
15
15
  import { evaluateEvidenceTriage } from './triage-adapter.js';
16
+ import { evaluateTriggerController } from '@principles/core/runtime-v2';
17
+ import { isSharedCooldownActive, markSharedEpisodeAsDiagnosed } from './trigger-cooldown-tracker.js';
16
18
  function clamp(value, min, max) {
17
19
  return Math.max(min, Math.min(max, value));
18
20
  }
@@ -194,14 +196,8 @@ export function handleLlmOutput(event, ctx) {
194
196
  const detectionText = isEmpathyAuditPayload(text) ? '' : text;
195
197
  const detectionService = DetectionService.get(wctx.stateDir);
196
198
  const detection = detectionService.detect(detectionText);
197
- if (detection.detected) {
198
- eventLog.recordRuleMatch(ctx.sessionId, {
199
- ruleId: detection.ruleId || detection.source,
200
- layer: detection.source === 'l1_exact' ? 'L1' : (detection.source === 'l2_cache' ? 'L2' : 'L3'),
201
- severity: detection.severity || 0,
202
- textPreview: detectionText.substring(0, 100)
203
- });
204
- }
199
+ // recordRuleMatch call removed (PRI-451 Wave 1): dead code — its only
200
+ // consumer was stats.pain.rulesMatched (dead counter, removed in Wave 1.5).
205
201
  let painScore = detection.detected ? (detection.severity || 0) : 0;
206
202
  let source = detection.detected
207
203
  ? (detection.ruleId ? `llm_${detection.ruleId.toLowerCase()}` : `llm_${detection.source}`)
@@ -247,11 +243,31 @@ export function handleLlmOutput(event, ctx) {
247
243
  matchedReason = `Accumulated GFI (${state.currentGfi.toFixed(1)}) crossed highGfi threshold (${highGfiThreshold}). Source: empathy keyword friction.`;
248
244
  }
249
245
  if (painScore >= painTriggerThreshold) {
250
- // PEAT-B1: Evidence triage (feature-flagged)
251
- let triageAdmitted = true;
252
- const llmTriageFlag = loadFeatureFlagFromConfig(ctx.workspaceDir, 'painEvidenceAdmission');
253
- if (llmTriageFlag.enabled) {
254
- // PRI-360 S1: Build RawObservation for unified source mapping
246
+ // PRI-454: Dual-gate migration. When both flags ON → Gate B (TriggerController).
247
+ // When either OFF → Gate A (PainDiagnosticGate, rollback).
248
+ const triageFlag = loadFeatureFlagFromConfig(ctx.workspaceDir, 'painEvidenceAdmission');
249
+ const defaultFlag = loadFeatureFlagFromConfig(ctx.workspaceDir, 'painEvidenceAdmissionDefault');
250
+ const useGateB = triageFlag.enabled && defaultFlag.enabled;
251
+ eventLog.recordPainSignal(ctx.sessionId, {
252
+ score: painScore,
253
+ source: source,
254
+ reason: matchedReason,
255
+ isRisky: false
256
+ });
257
+ // PRI-453: Generate painId early and write to trajectory.db via legacy
258
+ // recordPainEvent so that disabling SDK observability path does not lose
259
+ // trajectory coverage. canonicalPainId enables dedup.
260
+ const painId = `llm_${Date.now()}`;
261
+ wctx.trajectory?.recordPainEvent?.({
262
+ sessionId: ctx.sessionId || 'unknown',
263
+ source,
264
+ score: painScore,
265
+ reason: matchedReason,
266
+ origin: 'system_infer',
267
+ canonicalPainId: painId,
268
+ });
269
+ if (useGateB) {
270
+ // PRI-454: Gate B path — TriggerController owns admission
255
271
  const rawObs = {
256
272
  observedAt: new Date().toISOString(),
257
273
  workspaceId: ctx.workspaceDir,
@@ -262,17 +278,44 @@ export function handleLlmOutput(event, ctx) {
262
278
  const sourceKind = resolveSourceKind(rawObs);
263
279
  const triage = evaluateEvidenceTriage(sourceKind, painScore);
264
280
  if (triage.decision !== 'admit') {
265
- triageAdmitted = false;
266
281
  ctx.logger?.info?.(`[PD:LLM] Triage ${triage.decision}: ${triage.reason}`);
267
282
  }
283
+ else {
284
+ const cooldownActive = isSharedCooldownActive(sourceKind, ctx.sessionId, source);
285
+ const triggerDecision = evaluateTriggerController({
286
+ triageResult: triage,
287
+ isOwnerManual: false,
288
+ isCooldownActive: cooldownActive,
289
+ isValid: true,
290
+ score: painScore,
291
+ sessionId: ctx.sessionId,
292
+ });
293
+ if (triggerDecision.shouldCreateDiagnosticTask) {
294
+ markSharedEpisodeAsDiagnosed(sourceKind, ctx.sessionId, source);
295
+ const evidence = buildTrajectoryEvidence(wctx, ctx.sessionId || 'unknown');
296
+ emitPainDetectedEvent(wctx, {
297
+ ts: new Date().toISOString(),
298
+ type: 'pain_detected',
299
+ data: {
300
+ painId,
301
+ painType: 'user_frustration',
302
+ source,
303
+ reason: `${matchedReason}; trigger=${triggerDecision.outcome}`,
304
+ score: painScore,
305
+ sessionId: ctx.sessionId || 'unknown',
306
+ agentId: ctx.agentId,
307
+ provenance: 'openclaw_context_bound',
308
+ evidence,
309
+ },
310
+ }, { recordObservability: false });
311
+ }
312
+ else {
313
+ ctx.logger?.info?.(`[PD:LLM] Gate B skipped: ${triggerDecision.reason}`);
314
+ }
315
+ }
268
316
  }
269
- eventLog.recordPainSignal(ctx.sessionId, {
270
- score: painScore,
271
- source: source,
272
- reason: matchedReason,
273
- isRisky: false
274
- });
275
- if (triageAdmitted) {
317
+ else {
318
+ // PRI-454: Gate A path (rollback when either flag is OFF)
276
319
  const gate = evaluatePainDiagnosticGate({
277
320
  source: source === 'llm_paralysis' ? 'llm_paralysis' : 'semantic',
278
321
  score: painScore,
@@ -292,7 +335,7 @@ export function handleLlmOutput(event, ctx) {
292
335
  ts: new Date().toISOString(),
293
336
  type: 'pain_detected',
294
337
  data: {
295
- painId: `llm_${Date.now()}`,
338
+ painId,
296
339
  painType: 'user_frustration',
297
340
  source,
298
341
  reason: `${matchedReason}; diagnosticGate=${gate.reason}`,
@@ -302,15 +345,12 @@ export function handleLlmOutput(event, ctx) {
302
345
  provenance: 'openclaw_context_bound',
303
346
  evidence,
304
347
  },
305
- });
348
+ }, { recordObservability: false });
306
349
  }
307
350
  else {
308
351
  ctx.logger?.info?.(`[PD:LLM] Pain signal recorded without Runtime V2 diagnosis: ${gate.detail}`);
309
352
  }
310
353
  }
311
- else {
312
- ctx.logger?.info?.(`[PD:LLM] Triage evidence-only: pain signal recorded without diagnosis or gate evaluation`);
313
- }
314
354
  }
315
355
  // ═══ Thinking OS: Mental Model Usage Tracking ═══
316
356
  trackThinkingModelUsage({
@@ -19,7 +19,9 @@ import type { EvolutionLoopEvent } from '../core/evolution-types.js';
19
19
  import type { PluginHookAfterToolCallEvent, PluginHookToolContext, OpenClawPluginApi } from '../openclaw-sdk.js';
20
20
  import { buildTrajectoryEvidence } from './trajectory-evidence.js';
21
21
  export { buildTrajectoryEvidence };
22
- export declare function emitPainDetectedEvent(wctx: WorkspaceContext, event: EvolutionLoopEvent): Promise<void>;
22
+ export declare function emitPainDetectedEvent(wctx: WorkspaceContext, event: EvolutionLoopEvent, options?: {
23
+ recordObservability?: boolean;
24
+ }): Promise<void>;
23
25
  /**
24
26
  * Handle after_tool_call hook — decomposed into pipeline stages.
25
27
  *
@@ -24,7 +24,12 @@ import { getEvolutionLogger, createTraceId } from '../core/evolution-logger.js';
24
24
  import { resolveWorkspaceDirForRuntimeV2 } from '../utils/workspace-resolver.js';
25
25
  import { PainToPrincipleService, PrincipleTreeLedgerAdapter } from '@principles/core/runtime-v2';
26
26
  import { evaluatePainDiagnosticGate } from '../core/pain-diagnostic-gate.js';
27
- import { loadPdConfigForPlugin } from '../core/pd-config-loader.js';
27
+ import { loadPdConfigForPlugin, loadFeatureFlagFromConfig } from '../core/pd-config-loader.js';
28
+ import { createIntentDocReader } from '../core/intent-doc-reader-adapter.js';
29
+ import { evaluateTriggerController } from '@principles/core/runtime-v2';
30
+ import { isSharedCooldownActive, markSharedEpisodeAsDiagnosed } from './trigger-cooldown-tracker.js';
31
+ import { buildManualPainObservation, resolveSourceKind } from './raw-observation-adapter.js';
32
+ import { evaluateEvidenceTriage } from './triage-adapter.js';
28
33
  import { classifyToolCallOutcome, buildToolCallObservation, handleFrictionTrackingForFailure, handleFrictionTrackingForSuccess, recordHygieneTracking, handleProbationFeedback, evaluatePainAdmissionForToolCall, emitPainIfAdmitted, } from './after-tool-call-helpers.js';
29
34
  import { buildTrajectoryEvidence } from './trajectory-evidence.js';
30
35
  export { buildTrajectoryEvidence };
@@ -40,11 +45,15 @@ function createPainToPrincipleService(wctx) {
40
45
  autoIntakeEnabled: true,
41
46
  effectiveConfig: configResult.effective,
42
47
  getEnvVar: (name) => process.env[name],
48
+ // PRI-468: wire INTENT.md reader so Stage A can produce intentTension
49
+ // when intent_engineering flag is on. Adapter performs no I/O beyond
50
+ // delegating to safeReadIntentDoc (which owns the flag-first check).
51
+ intentDocReader: createIntentDocReader(wctx.workspaceDir),
43
52
  });
44
53
  }
45
54
  // buildTrajectoryEvidence is in ./trajectory-evidence.ts (re-exported above)
46
55
  // ── Pain Event Emission ─────────────────────────────────────────────────────
47
- export async function emitPainDetectedEvent(wctx, event) {
56
+ export async function emitPainDetectedEvent(wctx, event, options) {
48
57
  try {
49
58
  wctx.evolutionReducer.emitSync(event);
50
59
  }
@@ -68,6 +77,10 @@ export async function emitPainDetectedEvent(wctx, event) {
68
77
  score: painData.score,
69
78
  }));
70
79
  }
80
+ // PRI-453: Hook paths that already write events_*.jsonl + trajectory.db
81
+ // via legacy writers pass recordObservability: false to avoid triple-write.
82
+ // CLI pd pain record and paths without legacy writers keep the default true.
83
+ const recordObs = options?.recordObservability ?? true;
71
84
  const result = await service.recordPain({
72
85
  painId: painData.painId,
73
86
  painType: painData.painType,
@@ -80,7 +93,7 @@ export async function emitPainDetectedEvent(wctx, event) {
80
93
  traceId: painData.traceId,
81
94
  provenance: painData.provenance,
82
95
  evidence: painData.evidence,
83
- recordObservability: true,
96
+ recordObservability: recordObs,
84
97
  });
85
98
  if (result.status === 'failed' && result.failureCategory) {
86
99
  SystemLogger.log(wctx.workspaceDir, 'PAIN_SERVICE_FAILED', JSON.stringify({
@@ -216,6 +229,8 @@ function handleManualPain(event, ctx, wctx, workspaceDir, sessionId) {
216
229
  reason: `User intervention: ${reason}`,
217
230
  isRisky: true
218
231
  });
232
+ // PRI-453: Generate painId early to pass as canonicalPainId for dedup.
233
+ const painId = createPainId(sessionId);
219
234
  wctx.trajectory?.recordPainEvent?.({
220
235
  sessionId,
221
236
  source: 'manual',
@@ -223,6 +238,7 @@ function handleManualPain(event, ctx, wctx, workspaceDir, sessionId) {
223
238
  reason: `User intervention: ${reason}`,
224
239
  origin: 'user_manual',
225
240
  text: reason,
241
+ canonicalPainId: painId,
226
242
  });
227
243
  // Log to EvolutionLogger
228
244
  const evoLogger = getEvolutionLogger(workspaceDir, wctx.trajectory);
@@ -234,61 +250,120 @@ function handleManualPain(event, ctx, wctx, workspaceDir, sessionId) {
234
250
  toolName: event.toolName,
235
251
  sessionId,
236
252
  });
237
- // Apply PainDiagnosticGate with cooldown
238
- const session = getSession(sessionId);
239
- const gate = evaluatePainDiagnosticGate({
240
- source: 'manual',
241
- score: 100,
242
- currentGfi: session?.currentGfi ?? 0,
243
- sessionId,
244
- });
245
- if (!gate.shouldDiagnose) {
246
- SystemLogger.log(workspaceDir, 'MANUAL_PAIN_SKIPPED', `Manual pain within cooldown: ${gate.detail}`);
247
- let payload;
248
- try {
249
- payload = JSON.stringify({
250
- reason: gate.reason,
251
- detail: gate.detail,
252
- source: 'manual',
253
- sessionId,
254
- gfi: 0,
255
- score: 100,
256
- });
257
- }
258
- catch (e) {
259
- SystemLogger.log(workspaceDir, 'PAYLOAD_SERIALIZE_FAILED', String(e));
260
- payload = JSON.stringify({ reason: gate.reason, detail: '(log serialization failed)' });
261
- }
262
- SystemLogger.log(workspaceDir, 'PAIN_GATE_REJECTED', payload);
263
- // PEAT-B2: Record trigger decision even when cooldown blocks manual pain
253
+ // PRI-454: Dual-gate migration. When both flags ON → Gate B (TriggerController).
254
+ // When either OFF → Gate A (PainDiagnosticGate, rollback).
255
+ const triageFlag = loadFeatureFlagFromConfig(workspaceDir, 'painEvidenceAdmission');
256
+ const defaultFlag = loadFeatureFlagFromConfig(workspaceDir, 'painEvidenceAdmissionDefault');
257
+ const useGateB = triageFlag.enabled && defaultFlag.enabled;
258
+ if (useGateB) {
259
+ // PRI-454: Gate B path — manual pain is owner-reported.
260
+ // isOwnerManual: true → evaluateTriggerController returns manual_owner_admitted
261
+ // (bypasses triage and cooldown per PRODUCT_IDENTITY: owner-governed).
262
+ const rawObs = buildManualPainObservation({ sessionId });
263
+ const sourceKind = resolveSourceKind(rawObs); // → 'owner_reported'
264
+ const triage = evaluateEvidenceTriage(sourceKind, 100); // → 'admit'
265
+ const cooldownActive = isSharedCooldownActive(sourceKind, sessionId, 'manual_pain');
266
+ const triggerDecision = evaluateTriggerController({
267
+ triageResult: triage,
268
+ isOwnerManual: true,
269
+ isCooldownActive: cooldownActive,
270
+ isValid: true,
271
+ score: 100,
272
+ sessionId,
273
+ });
274
+ // PEAT-B2: Record trigger decision
264
275
  const painTriageFlag = loadPdConfigForPlugin(workspaceDir);
265
276
  if (painTriageFlag.effective) {
266
277
  SystemLogger.log(workspaceDir, 'TRIGGER_DECISION', JSON.stringify({
267
- outcome: 'cooldown_skipped',
268
- sourceKind: 'owner_reported',
269
- reason: `Manual pain within cooldown: ${gate.detail}`,
270
- nextAction: 'wait_for_cooldown_or_manual_retrigger',
278
+ outcome: triggerDecision.outcome,
279
+ sourceKind: triggerDecision.sourceKind,
280
+ reason: triggerDecision.reason,
281
+ nextAction: triggerDecision.nextAction,
271
282
  isOwnerManual: true,
272
283
  sessionId,
273
284
  score: 100,
274
285
  }));
275
286
  }
276
- return;
287
+ if (triggerDecision.shouldCreateDiagnosticTask) {
288
+ markSharedEpisodeAsDiagnosed(sourceKind, sessionId, 'manual_pain');
289
+ emitPainDetectedEvent(wctx, {
290
+ ts: new Date().toISOString(),
291
+ type: 'pain_detected',
292
+ data: {
293
+ painId,
294
+ painType: 'user_frustration',
295
+ source: event.toolName,
296
+ reason: `User intervention: ${reason}`,
297
+ score: 100,
298
+ sessionId,
299
+ traceId,
300
+ agentId: ctx.agentId,
301
+ provenance: (sessionId && sessionId !== 'unknown') ? 'openclaw_context_bound' : 'owner_reported_no_host_trace',
302
+ evidence: buildTrajectoryEvidence(wctx, sessionId),
303
+ },
304
+ }, { recordObservability: false });
305
+ }
306
+ else {
307
+ SystemLogger.log(workspaceDir, 'MANUAL_PAIN_SKIPPED', triggerDecision.reason);
308
+ }
277
309
  }
278
- emitPainDetectedEvent(wctx, {
279
- ts: new Date().toISOString(),
280
- type: 'pain_detected',
281
- data: {
282
- painId: createPainId(sessionId),
283
- painType: 'user_frustration',
284
- source: event.toolName,
285
- reason: `User intervention: ${reason}`,
310
+ else {
311
+ // PRI-454: Gate A path (rollback when either flag is OFF)
312
+ const session = getSession(sessionId);
313
+ const gate = evaluatePainDiagnosticGate({
314
+ source: 'manual',
286
315
  score: 100,
316
+ currentGfi: session?.currentGfi ?? 0,
287
317
  sessionId,
288
- traceId,
289
- agentId: ctx.agentId,
290
- provenance: (sessionId && sessionId !== 'unknown') ? 'openclaw_context_bound' : 'owner_reported_no_host_trace',
291
- evidence: buildTrajectoryEvidence(wctx, sessionId),
292
- },
293
- });
318
+ });
319
+ if (!gate.shouldDiagnose) {
320
+ SystemLogger.log(workspaceDir, 'MANUAL_PAIN_SKIPPED', `Manual pain within cooldown: ${gate.detail}`);
321
+ let payload;
322
+ try {
323
+ payload = JSON.stringify({
324
+ reason: gate.reason,
325
+ detail: gate.detail,
326
+ source: 'manual',
327
+ sessionId,
328
+ gfi: 0,
329
+ score: 100,
330
+ });
331
+ }
332
+ catch (e) {
333
+ SystemLogger.log(workspaceDir, 'PAYLOAD_SERIALIZE_FAILED', String(e));
334
+ payload = JSON.stringify({ reason: gate.reason, detail: '(log serialization failed)' });
335
+ }
336
+ SystemLogger.log(workspaceDir, 'PAIN_GATE_REJECTED', payload);
337
+ // PEAT-B2: Record trigger decision even when cooldown blocks manual pain
338
+ const painTriageFlag = loadPdConfigForPlugin(workspaceDir);
339
+ if (painTriageFlag.effective) {
340
+ SystemLogger.log(workspaceDir, 'TRIGGER_DECISION', JSON.stringify({
341
+ outcome: 'cooldown_skipped',
342
+ sourceKind: 'owner_reported',
343
+ reason: `Manual pain within cooldown: ${gate.detail}`,
344
+ nextAction: 'wait_for_cooldown_or_manual_retrigger',
345
+ isOwnerManual: true,
346
+ sessionId,
347
+ score: 100,
348
+ }));
349
+ }
350
+ return;
351
+ }
352
+ emitPainDetectedEvent(wctx, {
353
+ ts: new Date().toISOString(),
354
+ type: 'pain_detected',
355
+ data: {
356
+ painId,
357
+ painType: 'user_frustration',
358
+ source: event.toolName,
359
+ reason: `User intervention: ${reason}`,
360
+ score: 100,
361
+ sessionId,
362
+ traceId,
363
+ agentId: ctx.agentId,
364
+ provenance: (sessionId && sessionId !== 'unknown') ? 'openclaw_context_bound' : 'owner_reported_no_host_trace',
365
+ evidence: buildTrajectoryEvidence(wctx, sessionId),
366
+ },
367
+ }, { recordObservability: false });
368
+ }
294
369
  }