create-principles-disciple 1.92.0 → 1.94.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 (335) hide show
  1. package/console/dist/server/config/AuthConfig.js +6 -0
  2. package/console/dist/server/config/pd-config-store.d.ts +7 -1
  3. package/console/dist/server/config/pd-config-store.js +11 -1
  4. package/console/dist/server/index.js +41 -22
  5. package/console/dist/server/models/ApprovalsConsoleModel.js +4 -12
  6. package/console/dist/server/models/ApprovalsGroupedConsoleModel.js +6 -3
  7. package/console/dist/server/models/ConsoleLifecycleDatasource.js +1 -1
  8. package/console/dist/server/routes/activations.js +4 -0
  9. package/console/dist/server/routes/approvals.js +24 -4
  10. package/console/dist/server/routes/feedback-reports.js +7 -5
  11. package/console/dist/server/routes/lifecycle.js +6 -1
  12. package/console/dist/server/routes/principles.js +10 -2
  13. package/console/dist/server/routes/workspaces.js +4 -0
  14. package/console/dist/ui/components/ui/charts.js +4 -1
  15. package/console/dist/ui/components/ui/markdown.js +9 -5
  16. package/console/dist/ui/utils/enum-labels.js +4 -1
  17. package/console/dist/web/assets/app.js +5 -2
  18. package/core/dist/index.d.ts +2 -3
  19. package/core/dist/index.d.ts.map +1 -1
  20. package/core/dist/index.js +1 -3
  21. package/core/dist/index.js.map +1 -1
  22. package/core/dist/pain-signal.d.ts +11 -71
  23. package/core/dist/pain-signal.d.ts.map +1 -1
  24. package/core/dist/pain-signal.js +10 -120
  25. package/core/dist/pain-signal.js.map +1 -1
  26. package/core/dist/principle-tree-ledger.d.ts +4 -87
  27. package/core/dist/principle-tree-ledger.d.ts.map +1 -1
  28. package/core/dist/principle-tree-ledger.js +51 -148
  29. package/core/dist/principle-tree-ledger.js.map +1 -1
  30. package/core/dist/prompt-builder/__tests__/model-config.test.d.ts +2 -0
  31. package/core/dist/prompt-builder/__tests__/model-config.test.d.ts.map +1 -0
  32. package/core/dist/prompt-builder/__tests__/model-config.test.js +158 -0
  33. package/core/dist/prompt-builder/__tests__/model-config.test.js.map +1 -0
  34. package/core/dist/prompt-builder/__tests__/xml-escape.test.d.ts +2 -0
  35. package/core/dist/prompt-builder/__tests__/xml-escape.test.d.ts.map +1 -0
  36. package/core/dist/prompt-builder/__tests__/xml-escape.test.js +42 -0
  37. package/core/dist/prompt-builder/__tests__/xml-escape.test.js.map +1 -0
  38. package/core/dist/prompt-builder/index.d.ts +3 -0
  39. package/core/dist/prompt-builder/index.d.ts.map +1 -1
  40. package/core/dist/prompt-builder/index.js +2 -0
  41. package/core/dist/prompt-builder/index.js.map +1 -1
  42. package/core/dist/prompt-builder/model-config.d.ts +42 -0
  43. package/core/dist/prompt-builder/model-config.d.ts.map +1 -0
  44. package/core/dist/prompt-builder/model-config.js +84 -0
  45. package/core/dist/prompt-builder/model-config.js.map +1 -0
  46. package/core/dist/prompt-builder/xml-escape.d.ts +12 -0
  47. package/core/dist/prompt-builder/xml-escape.d.ts.map +1 -0
  48. package/core/dist/prompt-builder/xml-escape.js +19 -0
  49. package/core/dist/prompt-builder/xml-escape.js.map +1 -0
  50. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js +265 -20
  51. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
  52. package/core/dist/runtime-v2/__tests__/barrel-io-cleanup.test.d.ts +12 -0
  53. package/core/dist/runtime-v2/__tests__/barrel-io-cleanup.test.d.ts.map +1 -0
  54. package/core/dist/runtime-v2/__tests__/barrel-io-cleanup.test.js +46 -0
  55. package/core/dist/runtime-v2/__tests__/barrel-io-cleanup.test.js.map +1 -0
  56. package/core/dist/runtime-v2/__tests__/io-deletion.test.d.ts +12 -0
  57. package/core/dist/runtime-v2/__tests__/io-deletion.test.d.ts.map +1 -0
  58. package/core/dist/runtime-v2/__tests__/io-deletion.test.js +92 -0
  59. package/core/dist/runtime-v2/__tests__/io-deletion.test.js.map +1 -0
  60. package/core/dist/runtime-v2/__tests__/ledger-codec.test.d.ts +2 -0
  61. package/core/dist/runtime-v2/__tests__/ledger-codec.test.d.ts.map +1 -0
  62. package/core/dist/runtime-v2/__tests__/ledger-codec.test.js +429 -0
  63. package/core/dist/runtime-v2/__tests__/ledger-codec.test.js.map +1 -0
  64. package/core/dist/runtime-v2/__tests__/ledger-store.test.d.ts +2 -0
  65. package/core/dist/runtime-v2/__tests__/ledger-store.test.d.ts.map +1 -0
  66. package/core/dist/runtime-v2/__tests__/ledger-store.test.js +65 -0
  67. package/core/dist/runtime-v2/__tests__/ledger-store.test.js.map +1 -0
  68. package/core/dist/runtime-v2/__tests__/pain-signal-bridge-result-shaping.test.d.ts +2 -0
  69. package/core/dist/runtime-v2/__tests__/pain-signal-bridge-result-shaping.test.d.ts.map +1 -0
  70. package/core/dist/runtime-v2/__tests__/pain-signal-bridge-result-shaping.test.js +395 -0
  71. package/core/dist/runtime-v2/__tests__/pain-signal-bridge-result-shaping.test.js.map +1 -0
  72. package/core/dist/runtime-v2/__tests__/pain-signal-observability.test.js +146 -0
  73. package/core/dist/runtime-v2/__tests__/pain-signal-observability.test.js.map +1 -1
  74. package/core/dist/runtime-v2/__tests__/pain-signal-unification.test.d.ts +2 -0
  75. package/core/dist/runtime-v2/__tests__/pain-signal-unification.test.d.ts.map +1 -0
  76. package/core/dist/runtime-v2/__tests__/pain-signal-unification.test.js +150 -0
  77. package/core/dist/runtime-v2/__tests__/pain-signal-unification.test.js.map +1 -0
  78. package/core/dist/runtime-v2/adapter/__tests__/test-double-runtime-adapter.test.js +199 -0
  79. package/core/dist/runtime-v2/adapter/__tests__/test-double-runtime-adapter.test.js.map +1 -1
  80. package/core/dist/runtime-v2/bridge-result-shaper.d.ts +53 -0
  81. package/core/dist/runtime-v2/bridge-result-shaper.d.ts.map +1 -0
  82. package/core/dist/runtime-v2/bridge-result-shaper.js +117 -0
  83. package/core/dist/runtime-v2/bridge-result-shaper.js.map +1 -0
  84. package/core/dist/runtime-v2/detection/__tests__/detection-funnel-policy.test.d.ts +13 -0
  85. package/core/dist/runtime-v2/detection/__tests__/detection-funnel-policy.test.d.ts.map +1 -0
  86. package/core/dist/runtime-v2/detection/__tests__/detection-funnel-policy.test.js +111 -0
  87. package/core/dist/runtime-v2/detection/__tests__/detection-funnel-policy.test.js.map +1 -0
  88. package/core/dist/runtime-v2/detection/detection-funnel-policy.d.ts +103 -0
  89. package/core/dist/runtime-v2/detection/detection-funnel-policy.d.ts.map +1 -0
  90. package/core/dist/runtime-v2/detection/detection-funnel-policy.js +135 -0
  91. package/core/dist/runtime-v2/detection/detection-funnel-policy.js.map +1 -0
  92. package/core/dist/runtime-v2/detection/index.d.ts +10 -0
  93. package/core/dist/runtime-v2/detection/index.d.ts.map +1 -0
  94. package/core/dist/runtime-v2/detection/index.js +9 -0
  95. package/core/dist/runtime-v2/detection/index.js.map +1 -0
  96. package/core/dist/runtime-v2/diagnostician/__tests__/diag-rootcause-output.test.js +156 -0
  97. package/core/dist/runtime-v2/diagnostician/__tests__/diag-rootcause-output.test.js.map +1 -1
  98. package/core/dist/runtime-v2/evidence-triage/__tests__/observation-resolver.test.d.ts +12 -0
  99. package/core/dist/runtime-v2/evidence-triage/__tests__/observation-resolver.test.d.ts.map +1 -0
  100. package/core/dist/runtime-v2/evidence-triage/__tests__/observation-resolver.test.js +181 -0
  101. package/core/dist/runtime-v2/evidence-triage/__tests__/observation-resolver.test.js.map +1 -0
  102. package/core/dist/runtime-v2/evidence-triage/__tests__/triage-policy.test.js +104 -1
  103. package/core/dist/runtime-v2/evidence-triage/__tests__/triage-policy.test.js.map +1 -1
  104. package/core/dist/runtime-v2/evidence-triage/index.d.ts +3 -0
  105. package/core/dist/runtime-v2/evidence-triage/index.d.ts.map +1 -1
  106. package/core/dist/runtime-v2/evidence-triage/index.js +3 -0
  107. package/core/dist/runtime-v2/evidence-triage/index.js.map +1 -1
  108. package/core/dist/runtime-v2/evidence-triage/observation-resolver.d.ts +128 -0
  109. package/core/dist/runtime-v2/evidence-triage/observation-resolver.d.ts.map +1 -0
  110. package/core/dist/runtime-v2/evidence-triage/observation-resolver.js +203 -0
  111. package/core/dist/runtime-v2/evidence-triage/observation-resolver.js.map +1 -0
  112. package/core/dist/runtime-v2/evidence-triage/triage-policy.d.ts +4 -0
  113. package/core/dist/runtime-v2/evidence-triage/triage-policy.d.ts.map +1 -1
  114. package/core/dist/runtime-v2/evidence-triage/triage-policy.js +66 -9
  115. package/core/dist/runtime-v2/evidence-triage/triage-policy.js.map +1 -1
  116. package/core/dist/runtime-v2/evidence-triage/types.d.ts +14 -0
  117. package/core/dist/runtime-v2/evidence-triage/types.d.ts.map +1 -1
  118. package/core/dist/runtime-v2/evidence-triage/types.js.map +1 -1
  119. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js +33 -4
  120. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js.map +1 -1
  121. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
  122. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js +9 -2
  123. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
  124. package/core/dist/runtime-v2/feedback/__tests__/redact-sensitive.test.d.ts +15 -0
  125. package/core/dist/runtime-v2/feedback/__tests__/redact-sensitive.test.d.ts.map +1 -0
  126. package/core/dist/runtime-v2/feedback/__tests__/redact-sensitive.test.js +450 -0
  127. package/core/dist/runtime-v2/feedback/__tests__/redact-sensitive.test.js.map +1 -0
  128. package/core/dist/runtime-v2/feedback/__tests__/render-github-url.test.d.ts +13 -0
  129. package/core/dist/runtime-v2/feedback/__tests__/render-github-url.test.d.ts.map +1 -0
  130. package/core/dist/runtime-v2/feedback/__tests__/render-github-url.test.js +243 -0
  131. package/core/dist/runtime-v2/feedback/__tests__/render-github-url.test.js.map +1 -0
  132. package/core/dist/runtime-v2/feedback/__tests__/safe-stringify.test.d.ts +12 -0
  133. package/core/dist/runtime-v2/feedback/__tests__/safe-stringify.test.d.ts.map +1 -0
  134. package/core/dist/runtime-v2/feedback/__tests__/safe-stringify.test.js +172 -0
  135. package/core/dist/runtime-v2/feedback/__tests__/safe-stringify.test.js.map +1 -0
  136. package/core/dist/runtime-v2/index.d.ts +9 -6
  137. package/core/dist/runtime-v2/index.d.ts.map +1 -1
  138. package/core/dist/runtime-v2/index.js +8 -4
  139. package/core/dist/runtime-v2/index.js.map +1 -1
  140. package/core/dist/runtime-v2/internalization/__tests__/c2-live-runner-chain.test.d.ts +2 -0
  141. package/core/dist/runtime-v2/internalization/__tests__/c2-live-runner-chain.test.d.ts.map +1 -0
  142. package/core/dist/runtime-v2/internalization/__tests__/c2-live-runner-chain.test.js +306 -0
  143. package/core/dist/runtime-v2/internalization/__tests__/c2-live-runner-chain.test.js.map +1 -0
  144. package/core/dist/runtime-v2/internalization/index.d.ts +0 -16
  145. package/core/dist/runtime-v2/internalization/index.d.ts.map +1 -1
  146. package/core/dist/runtime-v2/internalization/index.js +0 -8
  147. package/core/dist/runtime-v2/internalization/index.js.map +1 -1
  148. package/core/dist/runtime-v2/pain-gate/__tests__/pain-diagnostic-gate-policy.test.d.ts +15 -0
  149. package/core/dist/runtime-v2/pain-gate/__tests__/pain-diagnostic-gate-policy.test.d.ts.map +1 -0
  150. package/core/dist/runtime-v2/pain-gate/__tests__/pain-diagnostic-gate-policy.test.js +179 -0
  151. package/core/dist/runtime-v2/pain-gate/__tests__/pain-diagnostic-gate-policy.test.js.map +1 -0
  152. package/core/dist/runtime-v2/pain-gate/index.d.ts +10 -0
  153. package/core/dist/runtime-v2/pain-gate/index.d.ts.map +1 -0
  154. package/core/dist/runtime-v2/pain-gate/index.js +9 -0
  155. package/core/dist/runtime-v2/pain-gate/index.js.map +1 -0
  156. package/core/dist/runtime-v2/pain-gate/pain-diagnostic-gate-policy.d.ts +121 -0
  157. package/core/dist/runtime-v2/pain-gate/pain-diagnostic-gate-policy.d.ts.map +1 -0
  158. package/core/dist/runtime-v2/pain-gate/pain-diagnostic-gate-policy.js +157 -0
  159. package/core/dist/runtime-v2/pain-gate/pain-diagnostic-gate-policy.js.map +1 -0
  160. package/core/dist/runtime-v2/pain-signal-bridge.d.ts.map +1 -1
  161. package/core/dist/runtime-v2/pain-signal-bridge.js +14 -88
  162. package/core/dist/runtime-v2/pain-signal-bridge.js.map +1 -1
  163. package/core/dist/runtime-v2/pain-signal-observability.d.ts.map +1 -1
  164. package/core/dist/runtime-v2/pain-signal-observability.js +15 -5
  165. package/core/dist/runtime-v2/pain-signal-observability.js.map +1 -1
  166. package/core/dist/runtime-v2/principle-tree/ledger-codec.d.ts +30 -0
  167. package/core/dist/runtime-v2/principle-tree/ledger-codec.d.ts.map +1 -0
  168. package/core/dist/runtime-v2/principle-tree/ledger-codec.js +154 -0
  169. package/core/dist/runtime-v2/principle-tree/ledger-codec.js.map +1 -0
  170. package/core/dist/runtime-v2/types/event-types.d.ts +0 -27
  171. package/core/dist/runtime-v2/types/event-types.d.ts.map +1 -1
  172. package/core/dist/runtime-v2/types/event-types.js +2 -17
  173. package/core/dist/runtime-v2/types/event-types.js.map +1 -1
  174. package/core/dist/runtime-v2/types/index.d.ts +4 -2
  175. package/core/dist/runtime-v2/types/index.d.ts.map +1 -1
  176. package/core/dist/runtime-v2/types/index.js +4 -1
  177. package/core/dist/runtime-v2/types/index.js.map +1 -1
  178. package/core/dist/runtime-v2/types/ledger-store.d.ts +101 -0
  179. package/core/dist/runtime-v2/types/ledger-store.d.ts.map +1 -0
  180. package/core/dist/runtime-v2/types/ledger-store.js +15 -0
  181. package/core/dist/runtime-v2/types/ledger-store.js.map +1 -0
  182. package/core/dist/runtime-v2/types/pain-signal.d.ts +7 -5
  183. package/core/dist/runtime-v2/types/pain-signal.d.ts.map +1 -1
  184. package/core/dist/runtime-v2/types/pain-signal.js +25 -5
  185. package/core/dist/runtime-v2/types/pain-signal.js.map +1 -1
  186. package/core/package.json +3 -3
  187. package/dist/installer.d.ts.map +1 -1
  188. package/dist/installer.js +9 -3
  189. package/dist/installer.js.map +1 -1
  190. package/dist/mvp-config.d.ts +0 -10
  191. package/dist/mvp-config.d.ts.map +1 -1
  192. package/dist/mvp-config.js +0 -64
  193. package/dist/mvp-config.js.map +1 -1
  194. package/dist/utils/env.d.ts.map +1 -1
  195. package/dist/utils/env.js +10 -4
  196. package/dist/utils/env.js.map +1 -1
  197. package/package.json +1 -1
  198. package/pd-cli/dist/commands/__tests__/legacy-cleanup.test.js +11 -3
  199. package/pd-cli/dist/commands/__tests__/legacy-cleanup.test.js.map +1 -1
  200. package/pd-cli/dist/commands/candidate.d.ts.map +1 -1
  201. package/pd-cli/dist/commands/candidate.js +2 -1
  202. package/pd-cli/dist/commands/candidate.js.map +1 -1
  203. package/pd-cli/dist/commands/health.d.ts.map +1 -1
  204. package/pd-cli/dist/commands/health.js +2 -1
  205. package/pd-cli/dist/commands/health.js.map +1 -1
  206. package/pd-cli/dist/commands/mvp-smoke.js +1 -1
  207. package/pd-cli/dist/commands/mvp-smoke.js.map +1 -1
  208. package/pd-cli/dist/commands/rulecode.js +1 -1
  209. package/pd-cli/dist/commands/rulecode.js.map +1 -1
  210. package/pd-cli/dist/commands/runtime-canary.d.ts.map +1 -1
  211. package/pd-cli/dist/commands/runtime-canary.js +10 -11
  212. package/pd-cli/dist/commands/runtime-canary.js.map +1 -1
  213. package/pd-cli/dist/commands/runtime-internalization-integrity.d.ts.map +1 -1
  214. package/pd-cli/dist/commands/runtime-internalization-integrity.js +3 -1
  215. package/pd-cli/dist/commands/runtime-internalization-integrity.js.map +1 -1
  216. package/pd-cli/dist/commands/runtime-internalization-queue.d.ts.map +1 -1
  217. package/pd-cli/dist/commands/runtime-internalization-queue.js +13 -16
  218. package/pd-cli/dist/commands/runtime-internalization-queue.js.map +1 -1
  219. package/pd-cli/dist/commands/runtime-internalization-run-once.d.ts.map +1 -1
  220. package/pd-cli/dist/commands/runtime-internalization-run-once.js +3 -0
  221. package/pd-cli/dist/commands/runtime-internalization-run-once.js.map +1 -1
  222. package/pd-cli/dist/commands/runtime-internalization-run-rulehost.d.ts.map +1 -1
  223. package/pd-cli/dist/commands/runtime-internalization-run-rulehost.js +61 -7
  224. package/pd-cli/dist/commands/runtime-internalization-run-rulehost.js.map +1 -1
  225. package/pd-cli/dist/commands/runtime-uat.d.ts.map +1 -1
  226. package/pd-cli/dist/commands/runtime-uat.js +4 -1
  227. package/pd-cli/dist/commands/runtime-uat.js.map +1 -1
  228. package/pd-cli/dist/commands/runtime.js +1 -1
  229. package/pd-cli/dist/commands/runtime.js.map +1 -1
  230. package/pd-cli/dist/index.js +67 -34
  231. package/pd-cli/dist/index.js.map +1 -1
  232. package/pd-cli/dist/legacy/session-history-import.js +7 -5
  233. package/pd-cli/dist/legacy/session-history-import.js.map +1 -1
  234. package/pd-cli/dist/services/__tests__/rulehost-readiness.test.d.ts +2 -0
  235. package/pd-cli/dist/services/__tests__/rulehost-readiness.test.d.ts.map +1 -0
  236. package/pd-cli/dist/services/__tests__/rulehost-readiness.test.js +314 -0
  237. package/pd-cli/dist/services/__tests__/rulehost-readiness.test.js.map +1 -0
  238. package/pd-cli/dist/services/__tests__/runtime-adapter-resolver.test.js +33 -14
  239. package/pd-cli/dist/services/__tests__/runtime-adapter-resolver.test.js.map +1 -1
  240. package/pd-cli/dist/services/pain-flood-simulation-runner.d.ts.map +1 -1
  241. package/pd-cli/dist/services/pain-flood-simulation-runner.js +6 -2
  242. package/pd-cli/dist/services/pain-flood-simulation-runner.js.map +1 -1
  243. package/pd-cli/dist/services/rulehost-readiness.d.ts +62 -0
  244. package/pd-cli/dist/services/rulehost-readiness.d.ts.map +1 -0
  245. package/pd-cli/dist/services/rulehost-readiness.js +214 -0
  246. package/pd-cli/dist/services/rulehost-readiness.js.map +1 -0
  247. package/pd-cli/dist/services/runtime-adapter-resolver.d.ts +1 -1
  248. package/pd-cli/dist/services/runtime-adapter-resolver.d.ts.map +1 -1
  249. package/pd-cli/dist/services/runtime-adapter-resolver.js +9 -7
  250. package/pd-cli/dist/services/runtime-adapter-resolver.js.map +1 -1
  251. package/plugin/dist/commands/capabilities.js +3 -2
  252. package/plugin/dist/commands/disable-impl.js +1 -1
  253. package/plugin/dist/commands/evolution-status.js +0 -2
  254. package/plugin/dist/commands/focus.js +10 -2
  255. package/plugin/dist/commands/rollback-impl.js +1 -1
  256. package/plugin/dist/commands/thinking-os.js +5 -1
  257. package/plugin/dist/core/correction-cue-learner.js +2 -0
  258. package/plugin/dist/core/detection-funnel.d.ts +25 -11
  259. package/plugin/dist/core/detection-funnel.js +32 -80
  260. package/plugin/dist/core/event-log.d.ts +1 -3
  261. package/plugin/dist/core/event-log.js +27 -31
  262. package/plugin/dist/core/evolution-reducer.d.ts +0 -8
  263. package/plugin/dist/core/evolution-reducer.js +9 -19
  264. package/plugin/dist/core/focus-history.js +1 -1
  265. package/plugin/dist/core/hygiene/tracker.js +3 -3
  266. package/plugin/dist/core/pain-diagnostic-gate.d.ts +37 -28
  267. package/plugin/dist/core/pain-diagnostic-gate.js +53 -89
  268. package/plugin/dist/core/pain.d.ts +0 -63
  269. package/plugin/dist/core/pain.js +0 -167
  270. package/plugin/dist/core/paths.d.ts +0 -1
  271. package/plugin/dist/core/paths.js +2 -1
  272. package/plugin/dist/core/principle-compiler/compiler.js +2 -0
  273. package/plugin/dist/core/replay-engine.js +1 -1
  274. package/plugin/dist/core/rule-host.js +3 -1
  275. package/plugin/dist/core/schema/migrations/001-init-trajectory.js +3 -6
  276. package/plugin/dist/core/schema/schema-definitions.js +4 -9
  277. package/plugin/dist/core/thinking-os-parser.js +13 -4
  278. package/plugin/dist/core/trajectory.d.ts +0 -16
  279. package/plugin/dist/core/trajectory.js +9 -60
  280. package/plugin/dist/hooks/after-tool-call-helpers.d.ts +4 -1
  281. package/plugin/dist/hooks/after-tool-call-helpers.js +13 -17
  282. package/plugin/dist/hooks/gate-block-helper.js +57 -17
  283. package/plugin/dist/hooks/lifecycle.js +3 -6
  284. package/plugin/dist/hooks/llm.js +66 -26
  285. package/plugin/dist/hooks/pain.d.ts +3 -1
  286. package/plugin/dist/hooks/pain.js +119 -49
  287. package/plugin/dist/hooks/prompt-helpers.d.ts +87 -0
  288. package/plugin/dist/hooks/prompt-helpers.js +251 -0
  289. package/plugin/dist/hooks/prompt-types.d.ts +66 -0
  290. package/plugin/dist/hooks/prompt-types.js +12 -0
  291. package/plugin/dist/hooks/prompt.d.ts +7 -38
  292. package/plugin/dist/hooks/prompt.js +361 -325
  293. package/plugin/dist/hooks/raw-observation-adapter.d.ts +9 -50
  294. package/plugin/dist/hooks/raw-observation-adapter.js +9 -164
  295. package/plugin/dist/hooks/raw-observation-types.d.ts +6 -57
  296. package/plugin/dist/hooks/raw-observation-types.js +5 -9
  297. package/plugin/dist/hooks/trajectory-collector.d.ts +20 -4
  298. package/plugin/dist/hooks/trajectory-collector.js +95 -156
  299. package/plugin/dist/hooks/triage-adapter.js +6 -26
  300. package/plugin/dist/hooks/trigger-cooldown-tracker.d.ts +12 -0
  301. package/plugin/dist/hooks/trigger-cooldown-tracker.js +25 -0
  302. package/plugin/dist/index.js +7 -2
  303. package/plugin/dist/openclaw-sdk.d.ts +4 -1
  304. package/plugin/dist/service/evolution-worker.js +8 -62
  305. package/plugin/dist/service/internalization-auto-consumer-service.js +2 -1
  306. package/plugin/dist/service/runtime-summary-service.d.ts +0 -2
  307. package/plugin/dist/service/runtime-summary-service.js +8 -5
  308. package/plugin/dist/service/workflow-watchdog.js +2 -1
  309. package/plugin/dist/types/event-types.d.ts +1 -1
  310. package/plugin/dist/utils/retry.js +7 -2
  311. package/plugin/dist/utils/session-key.js +4 -1
  312. package/plugin/scripts/sync-plugin.mjs +33 -22
  313. package/plugin/scripts/validate-live-path.ts +0 -18
  314. package/plugin/templates/langs/en/skills/pd-cli-operator/SKILL.md +20 -11
  315. package/plugin/templates/langs/en/skills/pd-runtime-v2/SKILL.md +10 -0
  316. package/plugin/templates/langs/zh/skills/pd-cli-operator/SKILL.md +20 -11
  317. package/plugin/templates/langs/zh/skills/pd-runtime-v2/SKILL.md +10 -0
  318. package/console/dist/server/config/feature-flags.d.ts +0 -25
  319. package/console/dist/server/config/feature-flags.js +0 -101
  320. package/core/dist/io.d.ts +0 -35
  321. package/core/dist/io.d.ts.map +0 -1
  322. package/core/dist/io.js +0 -95
  323. package/core/dist/io.js.map +0 -1
  324. package/pd-cli/dist/commands/central-sync.d.ts +0 -10
  325. package/pd-cli/dist/commands/central-sync.d.ts.map +0 -1
  326. package/pd-cli/dist/commands/central-sync.js +0 -32
  327. package/pd-cli/dist/commands/central-sync.js.map +0 -1
  328. package/pd-cli/dist/services/feature-flag-loader.d.ts +0 -6
  329. package/pd-cli/dist/services/feature-flag-loader.d.ts.map +0 -1
  330. package/pd-cli/dist/services/feature-flag-loader.js +0 -53
  331. package/pd-cli/dist/services/feature-flag-loader.js.map +0 -1
  332. package/plugin/dist/core/observability.d.ts +0 -40
  333. package/plugin/dist/core/observability.js +0 -164
  334. package/plugin/dist/hooks/subagent.d.ts +0 -9
  335. package/plugin/dist/hooks/subagent.js +0 -122
@@ -1,67 +1,4 @@
1
- /**
2
- * Required fields — every pain flag MUST have these.
3
- */
4
- export interface PainFlagData {
5
- /** What triggered this pain signal (e.g., tool_failure, human_intervention, intercept_extraction) */
6
- source: string;
7
- /** Pain score 0-100 */
8
- score: string;
9
- /** ISO 8601 timestamp */
10
- time: string;
11
- /** Human-readable reason / error description */
12
- reason: string;
13
- /** Session ID — identifies which conversation this happened in */
14
- session_id: string;
15
- /** Agent ID — identifies which agent (main, builder, diagnostician, etc.) */
16
- agent_id: string;
17
- /** Whether this involves risky operation ('true' / 'false') */
18
- is_risky: string;
19
- /** Correlation trace ID (for linking events across the pipeline) */
20
- trace_id: string;
21
- /** Preview of the text that triggered this pain */
22
- trigger_text_preview: string;
23
- /** Trajectory pain_events row ID (set by recordPainEvent) */
24
- pain_event_id?: string;
25
- }
26
- export interface PainFlagContractResult {
27
- status: 'missing' | 'valid' | 'invalid';
28
- format: 'missing' | 'empty' | 'kv' | 'json' | 'invalid_json';
29
- data: Record<string, string>;
30
- missingFields: string[];
31
- }
32
- /**
33
- * Builds legacy pain flag data for compatibility tests and historical readers.
34
- * Do not use this to create new Runtime V2 diagnosis requests.
35
- */
36
- export declare function buildPainFlag(input: {
37
- source: string;
38
- score: string;
39
- time?: string;
40
- reason: string;
41
- session_id?: string;
42
- agent_id?: string;
43
- is_risky?: boolean;
44
- trace_id?: string;
45
- trigger_text_preview?: string;
46
- pain_event_id?: string;
47
- }): PainFlagData;
48
- /**
49
- * Validates a pain flag read from disk.
50
- * Returns list of missing required fields — empty string means all present.
51
- */
52
- export declare function validatePainFlag(data: Record<string, string>): string[];
53
1
  export declare function computePainScore(rc: number, isSpiral: boolean, missingTestCommand: boolean, softScore: number, projectDir?: string): number;
54
- export declare function painSeverityLabel(painScore: number, isSpiral?: boolean, projectDir?: string): string;
55
- /**
56
- * Reads and validates the legacy pain flag file.
57
- *
58
- * - If file doesn't exist → returns {}
59
- * - If file is JSON format → converts to KV in memory only
60
- * - If file is KV format → validates required fields, logs warning if missing
61
- * - If file has unknown fields → silently ignores them (forward-compatible)
62
- */
63
- export declare function readPainFlagData(projectDir: string): Record<string, string>;
64
- export declare function readPainFlagContract(projectDir: string): PainFlagContractResult;
65
2
  /**
66
3
  * Track principle value metrics when a pain signal is written.
67
4
  * This is observation-only — it does NOT affect the pain flag write flow.
@@ -1,44 +1,5 @@
1
- import * as fs from 'fs';
2
- import { parseKvLines } from '../utils/io.js';
3
1
  import { resolvePdPath } from './paths.js';
4
2
  import { ConfigService } from './config-service.js';
5
- import { SystemLogger } from './system-logger.js';
6
- /**
7
- * Builds legacy pain flag data for compatibility tests and historical readers.
8
- * Do not use this to create new Runtime V2 diagnosis requests.
9
- */
10
- export function buildPainFlag(input) {
11
- // Omit optional fields when not provided — prevents writing empty lines to disk
12
- // which causes agent confusion (SKILL.md vs reality drift)
13
- return {
14
- source: input.source,
15
- score: input.score,
16
- time: input.time || new Date().toISOString(),
17
- reason: input.reason,
18
- session_id: input.session_id ?? '',
19
- agent_id: input.agent_id ?? '',
20
- is_risky: input.is_risky ? 'true' : 'false',
21
- trace_id: input.trace_id ?? '',
22
- trigger_text_preview: input.trigger_text_preview ?? '',
23
- pain_event_id: input.pain_event_id,
24
- };
25
- }
26
- /**
27
- * Validates a pain flag read from disk.
28
- * Returns list of missing required fields — empty string means all present.
29
- */
30
- export function validatePainFlag(data) {
31
- const missing = [];
32
- // Only source/score/time/reason are truly required — session_id/agent_id
33
- // may be empty in automated contexts (heartbeat, background workers)
34
- const required = ['source', 'score', 'time', 'reason'];
35
- for (const field of required) {
36
- if (!data[field] || data[field].trim() === '') {
37
- missing.push(field);
38
- }
39
- }
40
- return missing;
41
- }
42
3
  export function computePainScore(rc, isSpiral, missingTestCommand, softScore, projectDir) {
43
4
  let score = Math.max(0, softScore || 0);
44
5
  const stateDir = projectDir ? resolvePdPath(projectDir, 'STATE_DIR') : undefined;
@@ -59,134 +20,6 @@ export function computePainScore(rc, isSpiral, missingTestCommand, softScore, pr
59
20
  }
60
21
  return Math.min(100, score);
61
22
  }
62
- export function painSeverityLabel(painScore, isSpiral = false, projectDir) {
63
- if (isSpiral) {
64
- return "critical";
65
- }
66
- const stateDir = projectDir ? resolvePdPath(projectDir, 'STATE_DIR') : undefined;
67
- const config = stateDir ? ConfigService.get(stateDir) : null;
68
- const thresholds = config ? config.get('severity_thresholds') : {
69
- high: 70,
70
- medium: 40,
71
- low: 20
72
- };
73
- if (painScore >= thresholds.high) {
74
- return "high";
75
- }
76
- else if (painScore >= thresholds.medium) {
77
- return "medium";
78
- }
79
- else if (painScore >= thresholds.low) {
80
- return "low";
81
- }
82
- else {
83
- return "info";
84
- }
85
- }
86
- /**
87
- * Converts a JSON pain flag object to KV format.
88
- */
89
- function convertJsonToKv(json) {
90
- const kvData = {};
91
- const fieldMap = {
92
- source: 'source',
93
- score: 'score',
94
- time: 'time',
95
- timestamp: 'time',
96
- reason: 'reason',
97
- session_id: 'session_id',
98
- sessionId: 'session_id',
99
- agent_id: 'agent_id',
100
- agentId: 'agent_id',
101
- is_risky: 'is_risky',
102
- isRisky: 'is_risky',
103
- severity: 'severity',
104
- painId: 'pain_id',
105
- };
106
- for (const [jsonKey, kvKey] of Object.entries(fieldMap)) {
107
- if (json[jsonKey] !== undefined) {
108
- kvData[kvKey] = String(json[jsonKey]);
109
- }
110
- }
111
- for (const [key, value] of Object.entries(json)) {
112
- if (fieldMap[key] === undefined && value !== undefined && value !== null) {
113
- kvData[key] = String(value);
114
- }
115
- }
116
- return kvData;
117
- }
118
- /**
119
- * Reads and validates the legacy pain flag file.
120
- *
121
- * - If file doesn't exist → returns {}
122
- * - If file is JSON format → converts to KV in memory only
123
- * - If file is KV format → validates required fields, logs warning if missing
124
- * - If file has unknown fields → silently ignores them (forward-compatible)
125
- */
126
- export function readPainFlagData(projectDir) {
127
- const painFlagPath = resolvePdPath(projectDir, 'PAIN_FLAG');
128
- try {
129
- if (!fs.existsSync(painFlagPath)) {
130
- return {};
131
- }
132
- const content = fs.readFileSync(painFlagPath, "utf-8").trim();
133
- if (!content) {
134
- return {};
135
- }
136
- // Detect JSON format. Legacy compatibility only: parse in memory and do not
137
- // rewrite .pain_flag, because Runtime V2 must not create or repair this file.
138
- if (content.startsWith('{')) {
139
- let json;
140
- try {
141
- json = JSON.parse(content);
142
- }
143
- catch {
144
- SystemLogger.log(projectDir, 'PAIN_FLAG_CORRUPT', 'Pain flag file contains invalid JSON');
145
- return {};
146
- }
147
- const kvData = convertJsonToKv(json);
148
- SystemLogger.log(projectDir, 'PAIN_FLAG_LEGACY_JSON_READ', `Read legacy JSON pain flag in memory (${Object.keys(json).length} fields)`);
149
- return kvData;
150
- }
151
- // KV format — parse and validate
152
- const data = parseKvLines(content);
153
- const missing = validatePainFlag(data);
154
- if (missing.length > 0) {
155
- SystemLogger.log(projectDir, 'PAIN_FLAG_INCOMPLETE', `Pain flag missing required fields: ${missing.join(', ')}`);
156
- }
157
- return data;
158
- }
159
- catch (e) {
160
- SystemLogger.log(projectDir, 'PAIN_FLAG_READ_ERROR', `Failed to read pain flag: ${String(e)}`);
161
- return {};
162
- }
163
- }
164
- export function readPainFlagContract(projectDir) {
165
- const data = readPainFlagData(projectDir);
166
- if (Object.keys(data).length === 0) {
167
- const painFlagPath = resolvePdPath(projectDir, 'PAIN_FLAG');
168
- if (!fs.existsSync(painFlagPath)) {
169
- return { status: 'missing', format: 'missing', data: {}, missingFields: [] };
170
- }
171
- const raw = fs.readFileSync(painFlagPath, 'utf-8').trim();
172
- if (!raw) {
173
- return { status: 'missing', format: 'empty', data: {}, missingFields: [] };
174
- }
175
- return {
176
- status: 'invalid',
177
- format: raw.startsWith('{') ? 'invalid_json' : 'kv',
178
- data: {},
179
- missingFields: ['unparseable'],
180
- };
181
- }
182
- const missing = validatePainFlag(data);
183
- return {
184
- status: missing.length > 0 ? 'invalid' : 'valid',
185
- format: 'kv',
186
- data,
187
- missingFields: missing,
188
- };
189
- }
190
23
  /**
191
24
  * Track principle value metrics when a pain signal is written.
192
25
  * This is observation-only — it does NOT affect the pain flag write flow.
@@ -50,7 +50,6 @@ export declare const PD_FILES: {
50
50
  CURRENT_FOCUS: string;
51
51
  WEEK_STATE: string;
52
52
  THINKING_OS_CANDIDATES: string;
53
- SEMANTIC_PAIN: string;
54
53
  EVOLUTION_STREAM: string;
55
54
  EVOLUTION_LOCK: string;
56
55
  };
@@ -64,7 +64,8 @@ export const PD_FILES = {
64
64
  CURRENT_FOCUS: posixJoin(PD_DIRS.OKR, 'CURRENT_FOCUS.md'),
65
65
  WEEK_STATE: posixJoin(PD_DIRS.OKR, 'WEEK_STATE.json'),
66
66
  THINKING_OS_CANDIDATES: posixJoin(PD_DIRS.MEMORY, 'THINKING_OS_CANDIDATES.md'),
67
- SEMANTIC_PAIN: posixJoin(PD_DIRS.PAIN_SAMPLES, 'confusion_samples.md'),
67
+ // SEMANTIC_PAIN (confusion_samples.md) removed (PRI-451 Wave 1): the file
68
+ // had zero readers. The lifecycle write that populated it was also removed.
68
69
  EVOLUTION_STREAM: posixJoin(PD_DIRS.MEMORY, 'evolution.jsonl'),
69
70
  EVOLUTION_LOCK: posixJoin(PD_DIRS.LOCKS, 'evolution'),
70
71
  };
@@ -244,6 +244,8 @@ export class PrincipleCompiler {
244
244
  if (patterns.length === 0)
245
245
  return [];
246
246
  const pattern = patterns[0];
247
+ if (!pattern)
248
+ return [];
247
249
  // Skip replay when the pattern has no regex qualifier -- the generated template
248
250
  // blocks ALL calls to the tool, making it impossible to construct a passing
249
251
  // positive case. Replay is only meaningful when the template is selective.
@@ -30,7 +30,7 @@ export class ReplayEngine {
30
30
  }
31
31
  getLatestReport(implementationId) {
32
32
  const reports = this.listReports(implementationId);
33
- return reports.length > 0 ? reports[0] : null;
33
+ return reports[0] ?? null;
34
34
  }
35
35
  hasPassingReport(implementationId) {
36
36
  return this.listReports(implementationId).some((report) => report.overallDecision === 'pass');
@@ -188,7 +188,9 @@ export class RuleHost {
188
188
  }
189
189
  }
190
190
  else {
191
- validRows.push(group[0]);
191
+ const row = group[0];
192
+ if (row)
193
+ validRows.push(row);
192
194
  }
193
195
  }
194
196
  const loaded = [];
@@ -72,12 +72,9 @@ export const migration = {
72
72
  )`);
73
73
  db.exec(`CREATE INDEX IF NOT EXISTS idx_pain_events_session_id ON pain_events(session_id)`);
74
74
  db.exec(`CREATE INDEX IF NOT EXISTS idx_pain_events_created_at ON pain_events(created_at)`);
75
- // FTS5
76
- db.exec(`CREATE VIRTUAL TABLE IF NOT EXISTS pain_events_fts USING fts5(
77
- text,
78
- pain_event_id UNINDEXED,
79
- tokenize='porter unicode61'
80
- )`);
75
+ // pain_events_fts FTS5 virtual table removed (PRI-451 Wave 1): the only
76
+ // reader (searchPainEvents) was dead code. Existing DBs keep the orphan
77
+ // table harmlessly (CREATE was IF NOT EXISTS); new DBs simply don't create it.
81
78
  db.exec(`CREATE TABLE IF NOT EXISTS gate_blocks (
82
79
  id INTEGER PRIMARY KEY AUTOINCREMENT,
83
80
  session_id TEXT,
@@ -370,15 +370,10 @@ export const SCHEMAS = {
370
370
  FROM thinking_model_events GROUP BY date(created_at), model_id ORDER BY day ASC`,
371
371
  },
372
372
  },
373
- fts: {
374
- 'trajectory.pain_events_fts': {
375
- ddl: `CREATE VIRTUAL TABLE IF NOT EXISTS pain_events_fts USING fts5(
376
- text,
377
- pain_event_id UNINDEXED,
378
- tokenize='porter unicode61'
379
- )`,
380
- },
381
- },
373
+ // pain_events_fts FTS5 catalog entry removed (PRI-451 Wave 1): the only
374
+ // reader (searchPainEvents) was dead code. fts is now empty, matching the
375
+ // other DbType catalogs. Existing DBs keep the orphan table harmlessly.
376
+ fts: {},
382
377
  },
383
378
  // ========================================================================
384
379
  // central.db — Aggregated multi-workspace data
@@ -23,7 +23,10 @@ function extractTag(content, tagName) {
23
23
  const match = content.match(regex);
24
24
  if (!match)
25
25
  return '';
26
- return match[1].trim().replace(/\s+/g, ' ');
26
+ const raw = match[1];
27
+ if (!raw)
28
+ return '';
29
+ return raw.trim().replace(/\s+/g, ' ');
27
30
  }
28
31
  /**
29
32
  * Parse THINKING_OS.md content and extract all <directive> blocks.
@@ -35,14 +38,20 @@ export function parseThinkingOsMd(content) {
35
38
  const directiveRegex = /<directive\s+([^>]*)>([\s\S]*?)<\/directive>/gi;
36
39
  let _match = null;
37
40
  while ((_match = directiveRegex.exec(content)) !== null) {
38
- const [, attrs, body] = _match;
41
+ const attrs = _match[1];
42
+ const body = _match[2];
43
+ if (!attrs || !body)
44
+ continue;
39
45
  const idMatch = /id="([^"]+)"/i.exec(attrs);
40
46
  const nameMatch = /name="([^"]+)"/i.exec(attrs);
41
47
  if (!idMatch)
42
48
  continue;
49
+ const id = idMatch[1];
50
+ if (!id)
51
+ continue;
43
52
  const directive = {
44
- id: idMatch[1],
45
- name: nameMatch ? nameMatch[1] : '',
53
+ id,
54
+ name: nameMatch ? (nameMatch[1] ?? '') : '',
46
55
  trigger: extractTag(body, 'trigger'),
47
56
  must: extractTag(body, 'must'),
48
57
  forbidden: extractTag(body, 'forbidden'),
@@ -16,22 +16,6 @@ export declare class TrajectoryDatabase {
16
16
  recordUserTurn(input: TrajectoryUserTurnInput): number;
17
17
  recordToolCall(input: TrajectoryToolCallInput): number;
18
18
  recordPainEvent(input: TrajectoryPainEventInput): number;
19
- /**
20
- * Search pain_events using FTS5 full-text search (MEM-04).
21
- * Returns pain events matching the query, ordered by relevance.
22
- */
23
- searchPainEvents(query: string, limit?: number): {
24
- id: number;
25
- sessionId: string;
26
- source: string;
27
- score: number;
28
- reason: string | null;
29
- severity: string | null;
30
- origin: string | null;
31
- confidence: number | null;
32
- text: string | null;
33
- createdAt: string;
34
- }[];
35
19
  recordGateBlock(input: TrajectoryGateBlockInput): void;
36
20
  recordTrustChange(input: TrajectoryTrustChangeInput): void;
37
21
  recordPrincipleEvent(input: TrajectoryPrincipleEventInput): void;
@@ -170,60 +170,14 @@ export class TrajectoryDatabase {
170
170
  }
171
171
  }
172
172
  });
173
- // FTS indexing is best-effort — run outside the transaction so it cannot
174
- // roll back the committed pain event row (MEM-03, MEM-04).
175
- if (input.text && insertedId > 0) {
176
- try {
177
- this.db.prepare(`
178
- INSERT INTO pain_events_fts (text, pain_event_id) VALUES (?, ?)
179
- `).run(input.text, insertedId);
180
- }
181
- catch (err) {
182
- // Non-fatal: FTS index is for search convenience, not correctness.
183
- // Log but do not re-throw — the pain event itself is already committed.
184
- console.warn(`[trajectory] FTS index insert failed for pain_event ${insertedId}: ${String(err)}`);
185
- }
186
- }
173
+ // FTS5 index write removed (PRI-451 Wave 1): the only reader (searchPainEvents)
174
+ // was dead code removed in Wave 1.1. The pain event row itself is committed
175
+ // above; nothing reads the FTS index anymore.
187
176
  return insertedId;
188
177
  }
189
- /**
190
- * Search pain_events using FTS5 full-text search (MEM-04).
191
- * Returns pain events matching the query, ordered by relevance.
192
- */
193
- searchPainEvents(query, limit = 10) {
194
- if (!query || query.trim().length === 0) {
195
- return [];
196
- }
197
- // Escape FTS5 special characters and format query for porter tokenizer
198
- const ftsQuery = query.trim().split(/\s+/).map(term => `"${term.replace(/"/g, '""')}"`).join(' ');
199
- try {
200
- const results = this.db.prepare(`
201
- SELECT pe.*
202
- FROM pain_events_fts pf
203
- JOIN pain_events pe ON pe.id = pf.pain_event_id
204
- WHERE pain_events_fts MATCH ?
205
- ORDER BY bm25(pain_events_fts) DESC
206
- LIMIT ?
207
- `).all(ftsQuery, limit);
208
- return results.map(row => ({
209
- id: row.id,
210
- sessionId: row.session_id,
211
- source: row.source,
212
- score: row.score,
213
- reason: row.reason,
214
- severity: row.severity,
215
- origin: row.origin,
216
- confidence: row.confidence,
217
- text: row.text,
218
- createdAt: row.created_at,
219
- }));
220
- }
221
- catch (err) {
222
- // If FTS5 query fails (e.g., syntax error), return empty results
223
- console.warn(`[PD:TrajectoryDatabase] FTS5 search failed: ${String(err)}`);
224
- return [];
225
- }
226
- }
178
+ // searchPainEvents removed (PRI-451 Wave 1): dead code. Its only caller was
179
+ // processDetectionQueue (also removed). The FTS5 index write it read is
180
+ // removed in Wave 1.2.
227
181
  recordGateBlock(input) {
228
182
  this.withWrite(() => {
229
183
  this.db.prepare(`
@@ -1112,14 +1066,9 @@ export class TrajectoryDatabase {
1112
1066
  ON pain_events(canonical_pain_id)
1113
1067
  WHERE canonical_pain_id IS NOT NULL
1114
1068
  `);
1115
- // Create FTS5 virtual table for pain_events text search (MEM-04)
1116
- this.db.exec(`
1117
- CREATE VIRTUAL TABLE IF NOT EXISTS pain_events_fts USING fts5(
1118
- text,
1119
- pain_event_id UNINDEXED,
1120
- tokenize='porter unicode61'
1121
- )
1122
- `);
1069
+ // pain_events_fts FTS5 virtual table creation removed (PRI-451 Wave 1):
1070
+ // the only reader (searchPainEvents) was dead code. Existing DBs keep the
1071
+ // orphan table harmlessly (CREATE was IF NOT EXISTS); new DBs skip it.
1123
1072
  // V2 migration: Add V2 columns to evolution_tasks if they don't exist
1124
1073
  // SQLite does not support IF NOT EXISTS for ADD COLUMN, so we must check manually
1125
1074
  // before each ALTER to avoid "duplicate column name" errors on existing DBs
@@ -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)