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
@@ -87,7 +87,8 @@ export class WorkspaceConfigStore {
87
87
  }
88
88
  return parsed;
89
89
  }
90
- catch {
90
+ catch (e) {
91
+ console.warn('WorkspaceConfigStore: failed to parse workspaces.json, returning empty list:', e);
91
92
  return [];
92
93
  }
93
94
  }
@@ -13,7 +13,7 @@
13
13
  * - ERR-013: Object.hasOwn() for untrusted keys
14
14
  * - ERR-045: ANY-segment redaction for sensitive keys
15
15
  */
16
- import type { EffectivePdConfig, RedactedPdConfigSummary, InternalAgentName } from '@principles/core/runtime-v2';
16
+ import type { EffectivePdConfig, RedactedPdConfigSummary, InternalAgentName, FeatureFlagsResult } from '@principles/core/runtime-v2';
17
17
  export interface ConfigLoadResultOk {
18
18
  ok: true;
19
19
  effective: EffectivePdConfig;
@@ -76,6 +76,12 @@ export declare function validateBindingPayload(payload: unknown): {
76
76
  };
77
77
  export declare function getPdConfigPath(workspaceDir: string): string;
78
78
  export declare function loadPdConfig(workspaceDir: string): ConfigLoadResult;
79
+ /**
80
+ * Compute feature flags from the loaded PD config (PRI-460).
81
+ * Works with both ok and error results (uses defaults for errors).
82
+ * Replaces the legacy `loadWorkspaceFeatureFlags` + `buildFeedbackChannelFlags` path.
83
+ */
84
+ export declare function computeFlagsFromLoadResult(result: ConfigLoadResult): FeatureFlagsResult;
79
85
  export declare function getConfigSummary(workspaceDir: string): {
80
86
  summary: RedactedPdConfigSummary;
81
87
  errors?: {
@@ -132,4 +138,37 @@ export declare function getPrinciplesOutputLanguage(workspaceDir: string): Outpu
132
138
  * Safe partial write: preserves unknown sections, validates before write.
133
139
  */
134
140
  export declare function updatePrinciplesOutputLanguage(workspaceDir: string, payload: unknown): OutputLanguageResult;
141
+ export interface FeatureFlagUpdateResultOk {
142
+ ok: true;
143
+ feature: string;
144
+ enabled: boolean;
145
+ }
146
+ export interface FeatureFlagUpdateResultErr {
147
+ ok: false;
148
+ statusCode: number;
149
+ error: string;
150
+ message: string;
151
+ nextAction?: string;
152
+ }
153
+ export type FeatureFlagUpdateResult = FeatureFlagUpdateResultOk | FeatureFlagUpdateResultErr;
154
+ /**
155
+ * Update a feature flag's `enabled` field in .pd/config.yaml.
156
+ *
157
+ * Safe partial write: preserves unknown sections, validates before write.
158
+ * Follows the load → validate → merge → atomic write pattern of
159
+ * updateAgentBinding / updatePrinciplesOutputLanguage.
160
+ *
161
+ * Constraints (spec §13.4):
162
+ * - featureName must be in the registered flag set (DEFAULT_FEATURE_FLAGS)
163
+ * - Does NOT create a new `features:` section if absent (rejects)
164
+ * - Atomic write + validates merged yaml can be re-parsed by loadPdConfig
165
+ *
166
+ * ERR entries (spec §13.9):
167
+ * - ERR-001/ERR-005: enabled strictly typeof === 'boolean'; featureName
168
+ * strictly checked against whitelist
169
+ * - ERR-009: unknown featureName → ok:false with reason
170
+ * - ERR-013: Object.hasOwn for features section existence check
171
+ * - ERR-015/018/019: load-validate-merge-write-reload, no stale cache
172
+ */
173
+ export declare function updateFeatureFlag(workspaceDir: string, featureName: string, enabled: boolean): FeatureFlagUpdateResult;
135
174
  export declare function checkReadiness(workspaceDir: string, agentName: string, getEnvVar?: (name: string) => string | undefined): ReadinessResult | ReadinessError;
@@ -16,7 +16,7 @@
16
16
  import * as fs from 'fs';
17
17
  import * as path from 'path';
18
18
  import yaml from 'js-yaml';
19
- import { validatePdConfig, computeEffectivePdConfig, redactPdConfig, checkAgentRuntimeReadiness, resolveAgentRuntimeBinding, INTERNAL_AGENT_NAMES, } from '@principles/core/runtime-v2';
19
+ import { validatePdConfig, computeEffectivePdConfig, computeFeatureFlagsFromConfig, redactPdConfig, checkAgentRuntimeReadiness, resolveAgentRuntimeBinding, INTERNAL_AGENT_NAMES, } from '@principles/core/runtime-v2';
20
20
  // ── Constants ────────────────────────────────────────────────────────────────
21
21
  const PD_CONFIG_DIR = '.pd';
22
22
  const PD_CONFIG_FILENAME = 'config.yaml';
@@ -211,6 +211,16 @@ export function loadPdConfig(workspaceDir) {
211
211
  warnings: effective.warnings,
212
212
  };
213
213
  }
214
+ // ── Feature Flags from Config ────────────────────────────────────────────────
215
+ /**
216
+ * Compute feature flags from the loaded PD config (PRI-460).
217
+ * Works with both ok and error results (uses defaults for errors).
218
+ * Replaces the legacy `loadWorkspaceFeatureFlags` + `buildFeedbackChannelFlags` path.
219
+ */
220
+ export function computeFlagsFromLoadResult(result) {
221
+ const effective = result.ok ? result.effective : result.defaults;
222
+ return computeFeatureFlagsFromConfig(effective);
223
+ }
214
224
  // ── Get Redacted Summary ─────────────────────────────────────────────────────
215
225
  export function getConfigSummary(workspaceDir) {
216
226
  const result = loadPdConfig(workspaceDir);
@@ -596,6 +606,165 @@ export function updatePrinciplesOutputLanguage(workspaceDir, payload) {
596
606
  }
597
607
  return { ok: true, outputLanguage: outputLangRaw, source: 'user_config' };
598
608
  }
609
+ // ── Update Feature Flag (spec 2026-06-27 §13.4) ────────────────────────────
610
+ /**
611
+ * Whitelist of registered feature flag names. A PATCH request may only
612
+ * toggle flags that already exist in the registry. Built from the default
613
+ * effective config's computed flags — this is the authoritative source of
614
+ * registered flag IDs (avoids ambiguity between the array and Record
615
+ * forms of DEFAULT_FEATURE_FLAGS in the core barrel).
616
+ */
617
+ const _DEFAULT_FLAGS_RESULT = computeFeatureFlagsFromConfig(computeEffectivePdConfig(null));
618
+ const REGISTERED_FEATURE_FLAG_NAMES = new Set(Object.keys(_DEFAULT_FLAGS_RESULT.flags));
619
+ /** Map of flag ID → category, for preserving category when writing. */
620
+ const DEFAULT_FLAG_CATEGORY = new Map(Object.entries(_DEFAULT_FLAGS_RESULT.flags).map(([id, flag]) => [id, flag.category]));
621
+ /**
622
+ * Update a feature flag's `enabled` field in .pd/config.yaml.
623
+ *
624
+ * Safe partial write: preserves unknown sections, validates before write.
625
+ * Follows the load → validate → merge → atomic write pattern of
626
+ * updateAgentBinding / updatePrinciplesOutputLanguage.
627
+ *
628
+ * Constraints (spec §13.4):
629
+ * - featureName must be in the registered flag set (DEFAULT_FEATURE_FLAGS)
630
+ * - Does NOT create a new `features:` section if absent (rejects)
631
+ * - Atomic write + validates merged yaml can be re-parsed by loadPdConfig
632
+ *
633
+ * ERR entries (spec §13.9):
634
+ * - ERR-001/ERR-005: enabled strictly typeof === 'boolean'; featureName
635
+ * strictly checked against whitelist
636
+ * - ERR-009: unknown featureName → ok:false with reason
637
+ * - ERR-013: Object.hasOwn for features section existence check
638
+ * - ERR-015/018/019: load-validate-merge-write-reload, no stale cache
639
+ */
640
+ export function updateFeatureFlag(workspaceDir, featureName, enabled) {
641
+ // 1. Validate featureName against the registered whitelist
642
+ if (!REGISTERED_FEATURE_FLAG_NAMES.has(featureName)) {
643
+ return {
644
+ ok: false,
645
+ statusCode: 400,
646
+ error: 'unknown_feature',
647
+ message: `Unknown feature flag '${featureName}'. Registered flags: ${Array.from(REGISTERED_FEATURE_FLAG_NAMES).join(', ')}`,
648
+ nextAction: `Use one of: ${Array.from(REGISTERED_FEATURE_FLAG_NAMES).join(', ')}`,
649
+ };
650
+ }
651
+ // 2. Validate enabled is boolean (typeof check, no `as` — ERR-001)
652
+ if (typeof enabled !== 'boolean') {
653
+ return {
654
+ ok: false,
655
+ statusCode: 400,
656
+ error: 'bad_request',
657
+ message: `enabled must be a boolean. Got: ${typeof enabled}`,
658
+ nextAction: 'Send { enabled: true } or { enabled: false }',
659
+ };
660
+ }
661
+ // 3. Read raw config to preserve unknown sections + check features section
662
+ // Check features section BEFORE loadPdConfig malformed check: a config
663
+ // without a features section is rejected with 422 regardless of whether
664
+ // the rest is valid or malformed (spec §13.4: 不允许新增).
665
+ const configPath = getPdConfigPath(workspaceDir);
666
+ let rawConfig;
667
+ if (fs.existsSync(configPath)) {
668
+ let rawContent;
669
+ try {
670
+ rawContent = fs.readFileSync(configPath, 'utf8');
671
+ }
672
+ catch (err) {
673
+ const message = err instanceof Error ? err.message : String(err);
674
+ return { ok: false, statusCode: 500, error: 'read_error', message: `Failed to read config for update: ${message}` };
675
+ }
676
+ let rawParsed;
677
+ try {
678
+ rawParsed = yaml.load(rawContent, { schema: yaml.JSON_SCHEMA });
679
+ }
680
+ catch (err) {
681
+ // YAML syntax error = malformed config (409, not 500). Consistent with
682
+ // updateAgentBinding which treats loadPdConfig failures as conflict.
683
+ const message = err instanceof Error ? err.message : String(err);
684
+ return { ok: false, statusCode: 409, error: 'conflict', message: `Cannot update feature flag: existing .pd/config.yaml is malformed. YAML parse error: ${message}` };
685
+ }
686
+ if (isRecord(rawParsed)) {
687
+ rawConfig = { ...rawParsed };
688
+ }
689
+ else {
690
+ rawConfig = {};
691
+ }
692
+ }
693
+ else {
694
+ rawConfig = {};
695
+ }
696
+ // 4. Refuse to CREATE a features section if absent (spec §13.4: 不允许新增)
697
+ // Use Object.hasOwn for untrusted key check (ERR-013)
698
+ if (!Object.hasOwn(rawConfig, 'features') || !isRecord(rawConfig.features)) {
699
+ return {
700
+ ok: false,
701
+ statusCode: 422,
702
+ error: 'no_features_section',
703
+ message: `Cannot update feature flag: .pd/config.yaml has no 'features:' section. This API does not create new feature sections.`,
704
+ nextAction: 'Manually add a features: section to .pd/config.yaml first, or set the flag via yaml directly.',
705
+ };
706
+ }
707
+ // 5. Load existing config — if malformed, refuse to write
708
+ const loadResult = loadPdConfig(workspaceDir);
709
+ if (!loadResult.ok) {
710
+ return {
711
+ ok: false,
712
+ statusCode: 409,
713
+ error: 'conflict',
714
+ message: `Cannot update feature flag: existing .pd/config.yaml is malformed. Fix config errors first. Errors: ${loadResult.errors.map(e => e.reason).join('; ')}`,
715
+ };
716
+ }
717
+ // 6. Merge: update features[featureName].enabled, preserving other flags
718
+ const existingFeatures = { ...rawConfig.features };
719
+ const existingEntry = Object.hasOwn(existingFeatures, featureName)
720
+ ? existingFeatures[featureName]
721
+ : undefined;
722
+ // Preserve existing category if present; otherwise use the registered default
723
+ const category = (isRecord(existingEntry) && Object.hasOwn(existingEntry, 'category') && typeof existingEntry.category === 'string')
724
+ ? existingEntry.category
725
+ : (DEFAULT_FLAG_CATEGORY.get(featureName) ?? 'quiet');
726
+ existingFeatures[featureName] = { category, enabled };
727
+ rawConfig.features = existingFeatures;
728
+ // 7. Validate the updated config before writing
729
+ const validation = validatePdConfig(rawConfig);
730
+ if (!validation.ok) {
731
+ return {
732
+ ok: false,
733
+ statusCode: 400,
734
+ error: 'validation_error',
735
+ message: `Updated config would be invalid: ${validation.errors.map(e => e.reason).join('; ')}`,
736
+ nextAction: 'Fix config validation errors before retrying',
737
+ };
738
+ }
739
+ // 8. Atomic write
740
+ try {
741
+ writeConfigAtomic(configPath, rawConfig);
742
+ }
743
+ catch (err) {
744
+ const message = err instanceof Error ? err.message : String(err);
745
+ return { ok: false, statusCode: 500, error: 'write_error', message: `Failed to write config: ${message}`, nextAction: 'Check disk space and file permissions for .pd/config.yaml' };
746
+ }
747
+ // 9. Re-read to confirm actual persisted state (ERR-002: fail loud on re-read failure)
748
+ const confirmResult = loadPdConfig(workspaceDir);
749
+ if (!confirmResult.ok) {
750
+ return {
751
+ ok: false,
752
+ statusCode: 500,
753
+ error: 'confirm_read_failed',
754
+ message: `Write succeeded but re-read failed: config is now malformed`,
755
+ nextAction: 'Inspect .pd/config.yaml manually for corruption',
756
+ };
757
+ }
758
+ // Use computeFlagsFromLoadResult (not computeFeatureFlagsFromConfig) because
759
+ // confirmResult is a ConfigLoadResult, not an EffectivePdConfig.
760
+ const confirmFlags = computeFlagsFromLoadResult(confirmResult);
761
+ const confirmedEnabled = confirmFlags.flags[featureName]?.enabled === true;
762
+ return {
763
+ ok: true,
764
+ feature: featureName,
765
+ enabled: confirmedEnabled,
766
+ };
767
+ }
599
768
  // ── Check Readiness ──────────────────────────────────────────────────────────
600
769
  export function checkReadiness(workspaceDir, agentName, getEnvVar = (name) => process.env[name]) {
601
770
  // 1. Validate agent name
@@ -2,7 +2,7 @@ import * as http from 'http';
2
2
  import * as fs from 'fs';
3
3
  import * as path from 'path';
4
4
  import { fileURLToPath } from 'url';
5
- import { loadWorkspaceFeatureFlags, buildFeedbackChannelFlags, } from './config/feature-flags.js';
5
+ import { loadPdConfig, computeFlagsFromLoadResult } from './config/pd-config-store.js';
6
6
  import { AuthConfig } from './config/AuthConfig.js';
7
7
  import { WorkspaceConfigStore } from './config/WorkspaceConfigStore.js';
8
8
  import { WorkspaceService } from './models/WorkspaceService.js';
@@ -15,6 +15,8 @@ import { handleActivationsRoute, disposeActivationsModels } from './routes/activ
15
15
  import { handleApprovalsGroupedRoute, disposeApprovalsGroupedModels } from './routes/approvals-grouped.js';
16
16
  import { handleGovernanceRoute, disposeGovernanceModels } from './routes/governance.js';
17
17
  import { handleEvidenceChainRoute, disposeEvidenceChainModels } from './routes/evidence-chain.js';
18
+ import { handleIntentRoute, disposeIntentModels } from './routes/intent.js';
19
+ import { handleIntentDecisionsRoute, disposeIntentDecisionModels } from './routes/intent-decisions.js';
18
20
  import { createWorkspacesRoutes } from './routes/workspaces.js';
19
21
  import { handleUpdateRoute } from './routes/update.js';
20
22
  import { handleUpdateHistoryRoute } from './routes/update-history.js';
@@ -197,11 +199,15 @@ function asyncHandler(fn, timeoutMs = REQUEST_TIMEOUT_MS) {
197
199
  async function initServices(workspaceDir, authConfig) {
198
200
  const configStore = new WorkspaceConfigStore();
199
201
  const workspaceService = new WorkspaceService(configStore);
200
- // Load feature flags — fail-closed: on error, feedback_channel is disabled
201
- const flagLoadResult = loadWorkspaceFeatureFlags(workspaceDir);
202
- const feedbackFlags = buildFeedbackChannelFlags(flagLoadResult);
203
- if (!flagLoadResult.ok) {
204
- console.warn('[pd-console] Feature flag loading failed (feedback channel disabled):', flagLoadResult.reason);
202
+ // Load feature flags from canonical .pd/config.yaml — fail-closed: on error, feedback_channel uses defaults
203
+ const configResult = loadPdConfig(workspaceDir);
204
+ const pdFlags = computeFlagsFromLoadResult(configResult);
205
+ const feedbackChannelEnabled = pdFlags.flags.feedback_channel?.enabled ?? false;
206
+ const feedbackFlags = {
207
+ feedback_channel: { enabled: feedbackChannelEnabled },
208
+ };
209
+ if (!configResult.ok) {
210
+ console.warn('[pd-console] PD config loading failed (using defaults for feedback channel):', configResult.errors.map(e => e.reason).join('; '));
205
211
  }
206
212
  return {
207
213
  workspaceDir,
@@ -211,7 +217,7 @@ async function initServices(workspaceDir, authConfig) {
211
217
  feedbackFlags,
212
218
  };
213
219
  }
214
- async function closeServices(services) {
220
+ async function closeServices() {
215
221
  disposeFeedbackReportModels();
216
222
  disposeApprovalsModels();
217
223
  disposeApprovalsGroupedModels();
@@ -221,7 +227,8 @@ async function closeServices(services) {
221
227
  disposeActivationsModels();
222
228
  disposeGovernanceModels();
223
229
  disposeEvidenceChainModels();
224
- services.workspaceService.dispose();
230
+ disposeIntentModels();
231
+ disposeIntentDecisionModels();
225
232
  }
226
233
  // ── Route handler ───────────────────────────────────────────────────────────
227
234
  function handleRequest(services) {
@@ -290,7 +297,7 @@ function handleRequest(services) {
290
297
  asyncHandler(() => handleUpdateHistoryRoute(req, res, services.workspaceDir, ''))(req, res);
291
298
  return;
292
299
  }
293
- // Update routes: GET /api/update/check, POST /api/update/apply, GET /api/update/status, POST /api/update/rollback
300
+ // Update routes: GET /api/update/check, POST /api/update/apply, POST /api/update/rollback
294
301
  if (urlPath === '/api/update' || urlPath.startsWith('/api/update/')) {
295
302
  const subPath = urlPath.slice('/api/update'.length);
296
303
  const isApply = subPath === '/apply';
@@ -321,6 +328,17 @@ function handleRequest(services) {
321
328
  asyncHandler(() => handleGovernanceRoute(req, res, services.workspaceDir))(req, res);
322
329
  return;
323
330
  }
331
+ // PRI-466: GET /api/v1/intent
332
+ if (urlPath === '/api/v1/intent') {
333
+ asyncHandler(() => handleIntentRoute(req, res, services.workspaceDir))(req, res);
334
+ return;
335
+ }
336
+ // PRI-470: IntentDecisionRecord (POST/GET /api/v1/intent-decisions, /:id, /summary)
337
+ if (urlPath === '/api/v1/intent-decisions' || urlPath.startsWith('/api/v1/intent-decisions/')) {
338
+ const subPath = urlPath.slice('/api/v1/intent-decisions'.length);
339
+ asyncHandler(() => handleIntentDecisionsRoute(req, res, services.workspaceDir, subPath))(req, res);
340
+ return;
341
+ }
324
342
  // PRI-331: GET /api/v1/evidence-chain
325
343
  if (urlPath === '/api/v1/evidence-chain') {
326
344
  asyncHandler(() => handleEvidenceChainRoute(req, res, services.workspaceDir))(req, res);
@@ -355,7 +373,7 @@ export async function main() {
355
373
  const shutdown = async (signal) => {
356
374
  console.log(`[pd-console] Received ${signal}, shutting down...`);
357
375
  await new Promise((resolve) => { server.close(() => resolve()); });
358
- await closeServices(services);
376
+ await closeServices();
359
377
  process.exit(0);
360
378
  };
361
379
  process.on('SIGTERM', () => { void shutdown('SIGTERM'); });
@@ -1,7 +1,7 @@
1
1
  import * as fs from 'node:fs';
2
2
  import * as path from 'node:path';
3
3
  import { SqliteConnection, SqliteApprovalQueueStore, SqliteActivationStateStore, SqlitePIArtifactStore, ActivationDispatcher, PromptWriter, DeferArchiveWriter, RuleHostWriter, createProductionGateDeps, ApprovalCompletionService, ApprovalQueue, mapConfidenceToLabel, isArtifactRevisionOf, MVP_CHANNELS, } from '@principles/core/runtime-v2';
4
- import { loadWorkspaceFeatureFlags } from '../config/feature-flags.js';
4
+ import { loadPdConfig, computeFlagsFromLoadResult } from '../config/pd-config-store.js';
5
5
  const MVP_PROVEN_CHANNELS = new Set(MVP_CHANNELS);
6
6
  const EMPTY_STATS = { pending: 0, approved: 0, rejected: 0, cancelled: 0 };
7
7
  function isMissingTableError(err) {
@@ -216,17 +216,9 @@ export class ApprovalsConsoleModel {
216
216
  // Feature flag gate (Contract F): when story_a_approval_completion is disabled,
217
217
  // the new orchestrator is deactivated without damaging existing data.
218
218
  // The approval remains in 'approved' status; only activation is skipped.
219
- const flagResult = loadWorkspaceFeatureFlags(this.workspaceDir);
220
- if (!flagResult.ok) {
221
- return {
222
- decision: 'refused',
223
- reason: `feature_flag_load_failed: ${flagResult.reason}`,
224
- nextAction: 'fix feature flag config or manually dispatch via pd runtime activation dispatch',
225
- channel: existing.channel,
226
- riskLevel: existing.riskLevel,
227
- };
228
- }
229
- const completionFlag = flagResult.flags.flags.story_a_approval_completion;
219
+ const configResult = loadPdConfig(this.workspaceDir);
220
+ const pdFlags = computeFlagsFromLoadResult(configResult);
221
+ const completionFlag = pdFlags.flags.story_a_approval_completion;
230
222
  if (!completionFlag || !completionFlag.enabled) {
231
223
  // Flag disabled — return undefined so the caller knows activation was skipped.
232
224
  // The approval record itself is not rolled back (Contract F: no data damage).
@@ -22,10 +22,8 @@
22
22
  * - ERR-014/016/017: Evidence previews bounded via sanitizeString
23
23
  * - ERR-013: Use Object.hasOwn() for untrusted object keys
24
24
  */
25
- import { crossReferenceByTimestamp, resolveSummary } from '@principles/core/runtime-v2';
26
25
  import type { EvidenceChainState, EvidenceChainRecord, EvidenceChainResponse } from '@principles/core/runtime-v2';
27
26
  export type { EvidenceChainState, EvidenceChainRecord, EvidenceChainResponse, };
28
- export { crossReferenceByTimestamp, resolveSummary, };
29
27
  export declare class EvidenceChainConsoleModel {
30
28
  private readonly workspaceDir;
31
29
  constructor(workspaceDir: string);
@@ -22,11 +22,10 @@
22
22
  * - ERR-014/016/017: Evidence previews bounded via sanitizeString
23
23
  * - ERR-013: Use Object.hasOwn() for untrusted object keys
24
24
  */
25
- import { SqliteConnection, sanitizeString, assembleEvidenceChain, crossReferenceByTimestamp, resolveSummary, } from '@principles/core/runtime-v2';
25
+ import { SqliteConnection, sanitizeString, assembleEvidenceChain, } from '@principles/core/runtime-v2';
26
26
  import * as fs from 'node:fs';
27
27
  import * as path from 'node:path';
28
28
  import Database from 'better-sqlite3';
29
- export { crossReferenceByTimestamp, resolveSummary, };
30
29
  // ── Helpers ────────────────────────────────────────────────────────────────────
31
30
  function isRecord(value) {
32
31
  return typeof value === 'object' && value !== null && !Array.isArray(value);
@@ -180,6 +179,7 @@ export class EvidenceChainConsoleModel {
180
179
  let tasks = [];
181
180
  let dreamerTasks = [];
182
181
  let candidates = [];
182
+ let diagnosticArtifacts = [];
183
183
  let stateDbAvailable = false;
184
184
  if (fs.existsSync(stateDbPath)) {
185
185
  const conn = new SqliteConnection({ workspaceDir: this.workspaceDir, readonly: true });
@@ -230,6 +230,27 @@ export class EvidenceChainConsoleModel {
230
230
  throw colErr;
231
231
  }
232
232
  }
233
+ // PRI-469: Read diagnostician artifacts from the artifacts table.
234
+ // In production, DiagnosticianCommitter writes Stage C output (rootCause +
235
+ // intentTension) to artifacts.content_json with artifact_kind =
236
+ // 'diagnostician_output'. This is the canonical source for intentTension.
237
+ // The tasks.diagnostic_json column is kept as a fallback for test fixtures.
238
+ // Graceful degradation: if the artifacts table is missing (older workspace),
239
+ // we simply skip it — assembleEvidenceChain falls back to diagnostic_json.
240
+ try {
241
+ diagnosticArtifacts = db.prepare("SELECT task_id, content_json FROM artifacts WHERE artifact_kind = 'diagnostician_output' ORDER BY created_at DESC").all();
242
+ }
243
+ catch (artifactsErr) {
244
+ if (isMissingTableError(artifactsErr)) {
245
+ // Artifacts table not present in older workspaces — not an error,
246
+ // just no intentTension data available from artifacts.
247
+ }
248
+ else {
249
+ // ERR-002: degrade with reason for unexpected errors.
250
+ degradedReasons.push('Failed to read diagnostician artifacts table');
251
+ degradedNextActions.push('Check state database artifacts table integrity.');
252
+ }
253
+ }
233
254
  stateDbAvailable = true;
234
255
  }
235
256
  catch (err) {
@@ -272,6 +293,7 @@ export class EvidenceChainConsoleModel {
272
293
  stateDbAvailable,
273
294
  degradedReasons,
274
295
  degradedNextActions,
296
+ diagnosticArtifacts,
275
297
  });
276
298
  // ── 5. Sanitize strings in place ─────────────────────────────────
277
299
  for (const record of response.records) {
@@ -288,6 +310,18 @@ export class EvidenceChainConsoleModel {
288
310
  if (record.candidateSummary) {
289
311
  record.candidateSummary = sanitizeString(record.candidateSummary, this.workspaceDir);
290
312
  }
313
+ // PRI-469: Sanitize intentTension free-text fields.
314
+ // Enum fields (source, evidenceStrength, suggestedOwnerAction) and
315
+ // relatedIntentFields are controlled vocabularies validated by the core,
316
+ // so they don't need sanitization. The explanation, evidence items,
317
+ // and intentDocHash may contain user/system-generated text.
318
+ if (record.intentTension) {
319
+ record.intentTension.explanation = sanitizeString(record.intentTension.explanation, this.workspaceDir);
320
+ record.intentTension.evidence = record.intentTension.evidence.map((item) => sanitizeString(item, this.workspaceDir));
321
+ if (record.intentTension.intentDocHash) {
322
+ record.intentTension.intentDocHash = sanitizeString(record.intentTension.intentDocHash, this.workspaceDir);
323
+ }
324
+ }
291
325
  }
292
326
  return response;
293
327
  }
@@ -240,8 +240,9 @@ export class HealthCheckModel {
240
240
  lastPrincipleAdded = latestSignal?.updatedAt ?? null;
241
241
  }
242
242
  }
243
- catch {
244
- // Pruning not available — leave as null
243
+ catch (e) {
244
+ // Pruning not available — leave as null, but log for observability (ERR-002)
245
+ console.warn('HealthCheckModel.getPipelineTimestamps: pruning read failed, lastPrincipleAdded left null:', e);
245
246
  }
246
247
  return {
247
248
  lastPainSignal,
@@ -250,7 +251,8 @@ export class HealthCheckModel {
250
251
  lastPrincipleAdded,
251
252
  };
252
253
  }
253
- catch {
254
+ catch (e) {
255
+ console.warn('HealthCheckModel.getPipelineTimestamps: failed to read pipeline timestamps, returning all null:', e);
254
256
  return {
255
257
  lastPainSignal: null,
256
258
  lastTaskCreated: null,
@@ -0,0 +1,66 @@
1
+ /**
2
+ * IntentDecisionModel — Console model for IntentDecisionRecord (PRI-470).
3
+ *
4
+ * Holds the workspaceDir (like ApprovalsConsoleModel) and opens a per-request
5
+ * SqliteConnection inside each method: open → delegate to SqliteIntentDecisionStore
6
+ * → close. This keeps each operation isolated and safe across workspaces.
7
+ *
8
+ * Graceful degradation (SPEC §21.7 / ERR-002):
9
+ * - Missing state.db → reads return null/empty/zero summary; writes return a
10
+ * structured `not_initialized` result so the route can map to a clear HTTP
11
+ * error instead of silently creating a half-initialized workspace.
12
+ * - Missing intent_decisions table → reads degrade to empty; writes re-throw
13
+ * (the table is created by SqliteConnection.initSchema, so its absence
14
+ * signals a corrupted or pre-PD workspace that should not be written to).
15
+ *
16
+ * ERR checklist:
17
+ * - EP-01 / ERR-001, ERR-005: store rows validated via core type guards
18
+ * - EP-03 / ERR-002: every degraded path carries reason + nextAction
19
+ * - EP-09: model is a thin I/O adapter over the pure store contract
20
+ */
21
+ import type { IntentDecisionInput, IntentDecisionRecord, IntentDecisionSummary, FollowUpPatch } from '@principles/core/runtime-v2';
22
+ export type IntentDecisionRecordResultModel = {
23
+ ok: true;
24
+ record: IntentDecisionRecord;
25
+ created: boolean;
26
+ } | {
27
+ ok: false;
28
+ reason: string;
29
+ nextAction: string;
30
+ };
31
+ /**
32
+ * Result of a follow-up dispatch (PRI-471, SPEC §22.1.4).
33
+ *
34
+ * - ok:true + record — the existing record was updated with the follow-up
35
+ * field (e.g. `patchProposalId`, `resultingCandidateId`).
36
+ * - ok:false + reason 'decision_not_found' — no IntentDecisionRecord with
37
+ * the given id exists; the route maps this to 404.
38
+ * - ok:false + reason 'state_db_not_found' / 'intent_decisions_table_missing'
39
+ * — same degradation as the record() path.
40
+ */
41
+ export type FollowUpDispatchResultModel = {
42
+ ok: true;
43
+ record: IntentDecisionRecord;
44
+ } | {
45
+ ok: false;
46
+ reason: 'decision_not_found' | 'state_db_not_found' | 'intent_decisions_table_missing';
47
+ nextAction: string;
48
+ };
49
+ export declare class IntentDecisionModel {
50
+ private readonly workspaceDir;
51
+ constructor(workspaceDir: string);
52
+ record(input: IntentDecisionInput): Promise<IntentDecisionRecordResultModel>;
53
+ getById(id: string): Promise<IntentDecisionRecord | null>;
54
+ listByPainId(painId: string): Promise<IntentDecisionRecord[]>;
55
+ listByTaskId(taskId: string): Promise<IntentDecisionRecord[]>;
56
+ getSummary(): Promise<IntentDecisionSummary>;
57
+ /**
58
+ * Update follow-up action fields on an existing IntentDecisionRecord
59
+ * (PRI-471, SPEC §22.1.4).
60
+ *
61
+ * Called by the follow-up route after the Owner decision has been
62
+ * persisted. Only fields present in `patch` are written; the rest stay
63
+ * unchanged. Returns the updated record or a structured failure.
64
+ */
65
+ updateFollowUp(id: string, patch: FollowUpPatch): Promise<FollowUpDispatchResultModel>;
66
+ }