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
@@ -195,6 +195,16 @@ const REQUIRED_SOURCE_FILES = [
195
195
  'activation/approval-completion-service.ts',
196
196
  // PRI-431: L2 principle reader (pure logic, extracted from pd-cli + plugin duplicates)
197
197
  'build-l2-principle-reader.ts',
198
+ // PRI-446: pure logic migrated from openclaw-plugin into core
199
+ 'evidence-triage/observation-resolver.ts',
200
+ 'pain-gate/pain-diagnostic-gate-policy.ts',
201
+ 'pain-gate/index.ts',
202
+ 'detection/detection-funnel-policy.ts',
203
+ 'detection/index.ts',
204
+ // PRI-470: IntentDecisionRecord durable store + types (SPEC §21.7)
205
+ 'intent/intent-decision-record.ts',
206
+ 'store/intent/sqlite-intent-decision-store.ts',
207
+ 'store/intent/index.ts',
198
208
  ];
199
209
  // ── PRI-212: Plugin core anti-growth guard ────────────────────────────────────
200
210
  //
@@ -247,6 +257,9 @@ const KNOWN_PLUGIN_CORE_FILES = new Set([
247
257
  'schema/migration-runner.ts',
248
258
  'rule-host.ts',
249
259
  'principle-training-state.ts',
260
+ // PRI-446: now a thin adapter delegating pure decision logic to
261
+ // runtime-v2/pain-gate/pain-diagnostic-gate-policy.ts. Kept here because it
262
+ // owns the cooldown Map + SystemLogger + Date.now side effects.
250
263
  'pain-diagnostic-gate.ts',
251
264
  'hygiene/tracker.ts',
252
265
  'schema/migrations/002-init-central.ts',
@@ -289,6 +302,9 @@ const KNOWN_PLUGIN_CORE_FILES = new Set([
289
302
  'dictionary.ts',
290
303
  'thinking-os-parser.ts',
291
304
  'system-logger.ts',
305
+ // PRI-446: now a thin shell wiring DetectionFunnelCore (core runtime-v2/detection)
306
+ // with crypto.createHash + PainDictionary. Kept here because it owns the
307
+ // crypto + dictionary I/O boundary.
292
308
  'detection-funnel.ts',
293
309
  'risk-calculator.ts',
294
310
  'migration.ts',
@@ -298,6 +314,10 @@ const KNOWN_PLUGIN_CORE_FILES = new Set([
298
314
  'empathy-keyword-matcher.ts',
299
315
  'pain-lifecycle.ts',
300
316
  'session-tracker.ts',
317
+ // PRI-459: now a thin re-export adapter over @principles/core/principle-tree-ledger.
318
+ // Kept in the plugin baseline so existing relative imports (./principle-tree-ledger.js)
319
+ // still resolve. No parsing/serialization/mutation logic may live here — enforced by
320
+ // tests/ledger-schema-diff.test.ts.
301
321
  'principle-tree-ledger.ts',
302
322
  'evolution-logger.ts',
303
323
  'evolution-engine.ts',
@@ -309,6 +329,13 @@ const KNOWN_PLUGIN_CORE_FILES = new Set([
309
329
  'pd-config-loader.ts',
310
330
  // PRI-346: Pure function for checking conversation access config (extracted for circular import avoidance)
311
331
  'config-health.ts',
332
+ // PRI-467: Plugin I/O boundary — reads .principles/INTENT.md with TTL+mtime cache,
333
+ // delegates parsing/validation/hashing to @principles/core. Never throws.
334
+ 'intent-doc-reader.ts',
335
+ // PRI-468: Plugin adapter implementing core IntentDocReader port — pure type
336
+ // mapping from safeReadIntentDoc result to the core-owned IntentDocReadResult.
337
+ // No new I/O; delegates to intent-doc-reader.ts above.
338
+ 'intent-doc-reader-adapter.ts',
312
339
  // ── Test Files ──────────────────────────────────────────────────────────
313
340
  '__tests__/focus-history.test.ts',
314
341
  'principle-compiler/__tests__/compiler-replay-gate.test.ts',
@@ -350,7 +377,7 @@ describe('PRI-212 plugin core anti-growth guard', () => {
350
377
  expect.fail(msg);
351
378
  }
352
379
  });
353
- it('known baseline count is self-consistent (97 files)', async () => {
380
+ it('known baseline count is self-consistent (93 files)', async () => {
354
381
  // Sanity check: if the baseline grows, update this number.
355
382
  // Prevents accidental baseline bloat from going unnoticed.
356
383
  // See docs/reviews/plugin-core-inventory-2026-05.md §7
@@ -361,7 +388,14 @@ describe('PRI-212 plugin core anti-growth guard', () => {
361
388
  // model-training-registry.ts, model-deployment-registry.ts,
362
389
  // shadow-observation-registry.ts (98 → 93)
363
390
  // PRI-449: Removed external-training-contract.ts (93 → 92)
364
- expect(KNOWN_PLUGIN_CORE_FILES.size).toBe(92);
391
+ // PRI-446: pain-diagnostic-gate.ts and detection-funnel.ts remain at 92 —
392
+ // they are now thin adapters delegating pure logic to core, but still live
393
+ // in plugin src/core/ and own I/O side effects, so they stay classified.
394
+ // PRI-467: Added intent-doc-reader.ts (92 → 93) — plugin I/O boundary for
395
+ // reading .principles/INTENT.md with TTL+mtime cache for prompt injection.
396
+ // PRI-468: Added intent-doc-reader-adapter.ts (93 → 94) — plugin adapter
397
+ // implementing core IntentDocReader port (pure type mapping, no new I/O).
398
+ expect(KNOWN_PLUGIN_CORE_FILES.size).toBe(94);
365
399
  });
366
400
  });
367
401
  const REQUIRED_TEST_FILES = [
@@ -441,6 +475,11 @@ const REQUIRED_TEST_FILES = [
441
475
  '../internalization/__tests__/diag-chain-e2e.test.ts',
442
476
  // PRI-431
443
477
  'build-l2-principle-reader.test.ts',
478
+ // PRI-469
479
+ 'evidence-chain-intent-tension.test.ts',
480
+ // PRI-470: IntentDecisionRecord types + SQLite store
481
+ '../intent/__tests__/intent-decision-record.test.ts',
482
+ '../store/intent/__tests__/sqlite-intent-decision-store.test.ts',
444
483
  ];
445
484
  const REQUIRED_DOC_FILES = [];
446
485
  for (const file of REQUIRED_SOURCE_FILES) {
@@ -506,6 +545,8 @@ describe('runtime-v2 public API (index.ts barrel)', () => {
506
545
  'buildL2PrincipleReaderFromLedger',
507
546
  // LLM output hardening — shared utility
508
547
  'stripFabricatedCorePrincipleIds',
548
+ // PRI-470: IntentDecisionRecord durable SQLite store
549
+ 'SqliteIntentDecisionStore',
509
550
  ];
510
551
  for (const name of REQUIRED_EXPORTS) {
511
552
  it(`exports ${name}`, async () => {
@@ -597,6 +638,30 @@ describe('PRI-42 internalization boundary', () => {
597
638
  expect(src).not.toContain('../../../openclaw-plugin');
598
639
  }
599
640
  });
641
+ it('PRI-446: pain-gate has zero openclaw-plugin imports', async () => {
642
+ const { existsSync, readdirSync, readFileSync } = await import('node:fs');
643
+ const { resolve, join } = await import('node:path');
644
+ const dir = resolve(__dirname, '..', 'pain-gate');
645
+ expect(existsSync(dir)).toBe(true);
646
+ const files = readdirSync(dir).filter((f) => f.endsWith('.ts') && !f.endsWith('.test.ts'));
647
+ for (const file of files) {
648
+ const src = readFileSync(join(dir, file), 'utf-8');
649
+ expect(src).not.toContain('openclaw-plugin');
650
+ expect(src).not.toContain('../../../openclaw-plugin');
651
+ }
652
+ });
653
+ it('PRI-446: detection has zero openclaw-plugin imports', async () => {
654
+ const { existsSync, readdirSync, readFileSync } = await import('node:fs');
655
+ const { resolve, join } = await import('node:path');
656
+ const dir = resolve(__dirname, '..', 'detection');
657
+ expect(existsSync(dir)).toBe(true);
658
+ const files = readdirSync(dir).filter((f) => f.endsWith('.ts') && !f.endsWith('.test.ts'));
659
+ for (const file of files) {
660
+ const src = readFileSync(join(dir, file), 'utf-8');
661
+ expect(src).not.toContain('openclaw-plugin');
662
+ expect(src).not.toContain('../../../openclaw-plugin');
663
+ }
664
+ });
600
665
  it('plugin does not re-define RuleHost contract types locally', async () => {
601
666
  const { existsSync, readFileSync } = await import('node:fs');
602
667
  const { resolve } = await import('node:path');
@@ -1598,6 +1663,16 @@ describe('PRI-75/PRI-74/PRI-81 prompt-builder core boundary', () => {
1598
1663
  // Must NOT have the old multi-line fallback block with attitudeDirective interpolation
1599
1664
  expect(src).not.toMatch(/## 【CONTEXT SECTIONS】\n\n\[WARNING: Context sections stripped/);
1600
1665
  });
1666
+ it('plugin prompt-helpers.ts imports escapeXml from core, not reimplemented', async () => {
1667
+ const { readFileSync } = await import('node:fs');
1668
+ const { resolve } = await import('node:path');
1669
+ const src = readFileSync(resolve(__dirname, '../../../../openclaw-plugin/src/hooks/prompt-helpers.ts'), 'utf-8');
1670
+ // Must import escapeXml from core
1671
+ expect(src).toContain('@principles/core/prompt-builder');
1672
+ expect(src).toMatch(/import\s*\{[^}]*escapeXml[^}]*\}\s*from\s*['"]@principles\/core\/prompt-builder['"]/);
1673
+ // Must NOT reimplement escapeXml inline
1674
+ expect(src).not.toMatch(/\b(function\s+escapeXml\s*\(|const\s+escapeXml\s*=\s*(?:async\s*)?(?:\([^)]*\)|[a-zA-Z_$][\w$]*)\s*=>)/);
1675
+ });
1601
1676
  it('plugin empathy-keyword-matcher.ts is a thin adapter (re-exports from core)', async () => {
1602
1677
  const { readFileSync } = await import('node:fs');
1603
1678
  const { resolve } = await import('node:path');
@@ -1755,6 +1830,19 @@ describe('PRI-111 ArtificerRunner boundary', () => {
1755
1830
  expect(src).toContain('ArtificerRuleOutputSchema');
1756
1831
  });
1757
1832
  });
1833
+ // ── PRI-458: PhilosopherRunner barrel boundary (MVP-Quiet) ─────────────────────
1834
+ describe('PRI-458 PhilosopherRunner barrel boundary', () => {
1835
+ it('BARREL_EXPORTS: internalization/index.ts does NOT export PhilosopherRunner (PRI-458 MVP-Quiet)', async () => {
1836
+ // PRI-458: PhilosopherRunner is de-surfaced from the internal barrel (MVP-Quiet).
1837
+ // It remains in runtime-v2/index.ts (public barrel) because rulehost-pipeline-runner.ts
1838
+ // imports it from there (EP-02 exception).
1839
+ const { readFileSync } = await import('node:fs');
1840
+ const { resolve } = await import('node:path');
1841
+ const src = readFileSync(resolve(__dirname, '..', 'internalization', 'index.ts'), 'utf-8');
1842
+ expect(src).not.toContain("from './philosopher-runner.js'");
1843
+ expect(src).not.toContain("from './philosopher-output.js'");
1844
+ });
1845
+ });
1758
1846
  // ── PRI-EVAL: EvaluatorRunner boundary guards ──────────────────────────────────
1759
1847
  describe('PRI-EVAL EvaluatorRunner boundary', () => {
1760
1848
  it('evaluator source files exist in internalization directory', async () => {
@@ -1795,13 +1883,17 @@ describe('PRI-EVAL EvaluatorRunner boundary', () => {
1795
1883
  expect(src).not.toContain('node:fs');
1796
1884
  expect(src).not.toContain('node:cron');
1797
1885
  });
1798
- it('BARREL_EXPORTS: internalization/index.ts exports EvaluatorRunner and EvaluatorOutput', async () => {
1886
+ it('BARREL_EXPORTS: internalization/index.ts does NOT export EvaluatorRunner (PRI-458 MVP-Quiet)', async () => {
1887
+ // PRI-458: EvaluatorRunner is de-surfaced from the internal barrel (MVP-Quiet).
1888
+ // It remains in runtime-v2/index.ts (public barrel) because rulehost-pipeline-runner.ts
1889
+ // imports it from there (EP-02 exception). These negative assertions lock the boundary:
1890
+ // if someone re-aggregates the evaluator exports into this barrel, the test will fail.
1799
1891
  const { readFileSync } = await import('node:fs');
1800
1892
  const { resolve } = await import('node:path');
1801
1893
  const src = readFileSync(resolve(__dirname, '..', 'internalization', 'index.ts'), 'utf-8');
1802
- expect(src).toContain('EvaluatorRunner');
1803
- expect(src).toContain('EvaluatorOutput');
1804
- expect(src).toContain('DefaultEvaluatorValidator');
1894
+ expect(src).not.toContain("from './evaluator-runner.js'");
1895
+ expect(src).not.toContain("from './evaluator-output.js'");
1896
+ expect(src).not.toContain("from './evaluator-prompt-builder.js'");
1805
1897
  });
1806
1898
  it('SCHEMA_REGISTRY: pi-ai-runtime-adapter.ts registers evaluator-output-v1 schema', async () => {
1807
1899
  const { readFileSync } = await import('node:fs');
@@ -1851,13 +1943,16 @@ describe('PRI-RR RolloutReviewerRunner boundary', () => {
1851
1943
  expect(src).not.toContain('node:fs');
1852
1944
  expect(src).not.toContain('node:cron');
1853
1945
  });
1854
- it('BARREL_EXPORTS: internalization/index.ts exports RolloutReviewerRunner and RolloutReviewerOutput', async () => {
1946
+ it('BARREL_EXPORTS: internalization/index.ts does NOT export RolloutReviewerRunner (PRI-458 MVP-Quiet)', async () => {
1947
+ // PRI-458: RolloutReviewerRunner is de-surfaced from the internal barrel (MVP-Quiet).
1948
+ // It remains in runtime-v2/index.ts (public barrel) because runtime-internalization-run-once.ts
1949
+ // imports it from there and package.json has no deep import path available (EP-02 exception).
1855
1950
  const { readFileSync } = await import('node:fs');
1856
1951
  const { resolve } = await import('node:path');
1857
1952
  const src = readFileSync(resolve(__dirname, '..', 'internalization', 'index.ts'), 'utf-8');
1858
- expect(src).toContain('RolloutReviewerRunner');
1859
- expect(src).toContain('RolloutReviewerOutput');
1860
- expect(src).toContain('DefaultRolloutReviewerValidator');
1953
+ expect(src).not.toContain("from './rollout-reviewer-runner.js'");
1954
+ expect(src).not.toContain("from './rollout-reviewer-output.js'");
1955
+ expect(src).not.toContain("from './rollout-reviewer-prompt-builder.js'");
1861
1956
  });
1862
1957
  it('SCHEMA_REGISTRY: pi-ai-runtime-adapter.ts registers rollout-reviewer-output-v1 schema', async () => {
1863
1958
  const { readFileSync } = await import('node:fs');
@@ -2127,12 +2222,14 @@ describe('PRI-117 Nocturnal god-class freeze', () => {
2127
2222
  expect(src).not.toContain('invokeStubScribe');
2128
2223
  }
2129
2224
  });
2130
- it('RUNTIME_V2_USES_PEER_RUNNERS: DreamerRunner/PhilosopherRunner/ScribeRunner are the canonical entry points', async () => {
2225
+ it('RUNTIME_V2_USES_PEER_RUNNERS: DreamerRunner/ScribeRunner/ArtificerRunner are the canonical MVP-Core entry points', async () => {
2226
+ // PRI-458: narrowed to MVP-Core runners only. PhilosopherRunner (MVP-Quiet)
2227
+ // remains in runtime-v2/index.ts for rulehost-pipeline-runner.ts compatibility
2228
+ // but is no longer asserted as a canonical entry point.
2131
2229
  const { readFileSync } = await import('node:fs');
2132
2230
  const { resolve } = await import('node:path');
2133
2231
  const src = readFileSync(resolve(__dirname, '..', 'index.ts'), 'utf-8');
2134
2232
  expect(src).toContain('DreamerRunner');
2135
- expect(src).toContain('PhilosopherRunner');
2136
2233
  expect(src).toContain('ScribeRunner');
2137
2234
  expect(src).toContain('ArtificerRunner');
2138
2235
  });
@@ -2878,7 +2975,7 @@ describe('PRI-225: No unsafe type assertions on untrusted metadata arrays', () =
2878
2975
  // ── PRI-239: Feature flag registry architecture boundary ──────────────────
2879
2976
  //
2880
2977
  // Core: packages/principles-core/src/runtime-v2/feature-flags/feature-flag-contract.ts
2881
- // I/O Loader: packages/pd-cli/src/services/feature-flag-loader.ts
2978
+ // I/O Loader: packages/pd-cli/src/services/pd-config-loader.ts (PRI-460: replaced feature-flag-loader.ts)
2882
2979
  // CLI Command: packages/pd-cli/src/commands/runtime-features.ts
2883
2980
  // Consumption: packages/pd-cli/src/commands/runtime-canary.ts (GFI check)
2884
2981
  describe('PRI-239: Feature flag registry architecture boundary', () => {
@@ -2900,10 +2997,10 @@ describe('PRI-239: Feature flag registry architecture boundary', () => {
2900
2997
  expect(src).not.toContain('InternalizationOrchestrator');
2901
2998
  expect(src).not.toContain('SqliteConnection');
2902
2999
  });
2903
- it('IO_LOADER_OUTSIDE_CORE: I/O loader exists at pd-cli/src/services/feature-flag-loader.ts', async () => {
3000
+ it('IO_LOADER_OUTSIDE_CORE: I/O loader exists at pd-cli/src/services/pd-config-loader.ts', async () => {
2904
3001
  const { existsSync } = await import('node:fs');
2905
3002
  const { resolve } = await import('node:path');
2906
- expect(existsSync(resolve(__dirname, '../../../../pd-cli/src/services/feature-flag-loader.ts'))).toBe(true);
3003
+ expect(existsSync(resolve(__dirname, '../../../../pd-cli/src/services/pd-config-loader.ts'))).toBe(true);
2907
3004
  });
2908
3005
  it('CLI_COMMAND_OUTSIDE_CORE: CLI command exists at pd-cli/src/commands/runtime-features.ts', async () => {
2909
3006
  const { existsSync } = await import('node:fs');
@@ -2918,12 +3015,12 @@ describe('PRI-239: Feature flag registry architecture boundary', () => {
2918
3015
  expect(src).not.toContain('nocturnal-arbiter');
2919
3016
  expect(src).not.toContain('nocturnal-service');
2920
3017
  });
2921
- it('CONSUMPTION_WIRED: runtime-canary.ts imports feature flag loader', async () => {
3018
+ it('CONSUMPTION_WIRED: runtime-canary.ts imports canonical PD config loader', async () => {
2922
3019
  const { readFileSync } = await import('node:fs');
2923
3020
  const { resolve } = await import('node:path');
2924
3021
  const src = readFileSync(resolve(__dirname, '../../../../pd-cli/src/commands/runtime-canary.ts'), 'utf-8');
2925
- expect(src).toContain('feature-flag-loader');
2926
- expect(src).toContain('loadEffectiveFeatureFlags');
3022
+ expect(src).toContain('pd-config-loader');
3023
+ expect(src).toContain('loadPdConfig');
2927
3024
  });
2928
3025
  });
2929
3026
  describe('PRI-304: PD-Owned Config Contract barrel exports and purity', () => {
@@ -3121,33 +3218,31 @@ describe('PRI-443: pure module boundary guards', () => {
3121
3218
  expect(src).not.toMatch(/export\s+type\s+\{\s*LedgerTreeStore\s*\}\s*from\s*['"]\.\.\/principle-tree-ledger\.js['"]/);
3122
3219
  });
3123
3220
  });
3124
- // ── PRI-450: Core I/O whitelist guard ──────────────────────────────────────────
3125
- //
3126
- // Scans all production (.ts, non-test) files under packages/principles-core/src/
3127
- // for fs/path imports and verifies they match an explicit whitelist. Any new file
3128
- // that needs I/O must be added to ALLOWED_IO_FILES here — otherwise CI fails.
3129
- // This forces developers to explain "why does this file need I/O?" in their PR.
3130
- describe('PRI-450: core I/O whitelist guard', () => {
3131
- // Whitelist of production files allowed to import fs/path.
3132
- // Paths are relative to packages/principles-core/src/.
3133
- const ALLOWED_IO_FILES = new Set([
3134
- 'principle-tree-ledger.ts',
3135
- 'evolution-store.ts',
3136
- 'trajectory-store.ts',
3137
- 'workflow-funnel-loader.ts',
3138
- 'runtime-v2/store/sqlite-connection.ts',
3139
- 'runtime-v2/store/runtime-state-manager.ts',
3140
- 'runtime-v2/adapter/openclaw-cli-runtime-adapter.ts',
3141
- 'runtime-v2/candidate-audit.ts',
3142
- 'runtime-v2/pain-signal-observability.ts',
3143
- 'runtime-v2/internalization-chain-integrity-read-model.ts',
3144
- 'runtime-v2/internalization-integrity-remediation.ts',
3145
- 'runtime-v2/operator-health-read-model.ts',
3146
- 'runtime-v2/pain-chain-read-model.ts',
3147
- 'runtime-v2/pruning-read-model.ts',
3148
- 'runtime-v2/pruning-review-log.ts',
3149
- 'runtime-v2/schema-conformance-read-model.ts',
3150
- ]);
3221
+ describe('PRI-450 / PRI-462: core I/O seam registry guard', () => {
3222
+ // Registry lives at packages/principles-core/io-seam-registry.json
3223
+ // (3 levels up from __tests__: __tests__ → runtime-v2 → src → principles-core)
3224
+ const registryPath = pathSync.resolve(__dirname, '..', '..', '..', 'io-seam-registry.json');
3225
+ const registryRaw = fsSync.readFileSync(registryPath, 'utf-8');
3226
+ const registry = JSON.parse(registryRaw);
3227
+ // Runtime-validate the registry shape (Runtime Contract Rule 1+2: treat
3228
+ // parsed JSON as unknown, validate with typeof/Array.isArray before access).
3229
+ // `as` is used only for type narrowing AFTER runtime checks, not to bypass them.
3230
+ function isValidRegistry(v) {
3231
+ if (typeof v !== 'object' || v === null || !Object.hasOwn(v, 'seams'))
3232
+ return false;
3233
+ const { seams } = v;
3234
+ if (!Array.isArray(seams))
3235
+ return false;
3236
+ return seams.every((s) => typeof s === 'object' && s !== null &&
3237
+ typeof s.name === 'string' &&
3238
+ typeof s.description === 'string' &&
3239
+ Array.isArray(s.files) &&
3240
+ s.files.every((f) => typeof f === 'string'));
3241
+ }
3242
+ // Flatten all registry files into a Set (relative to packages/principles-core/src/).
3243
+ const ALLOWED_IO_FILES = new Set(isValidRegistry(registry)
3244
+ ? registry.seams.flatMap((s) => s.files)
3245
+ : []);
3151
3246
  // Extract all import module paths from source code.
3152
3247
  // Handles: import ... from 'mod', import 'mod' (side-effect), and multiline imports.
3153
3248
  // Reuses the same pattern proven in the PRI-215 extractImportModulePaths helper.
@@ -3186,7 +3281,52 @@ describe('PRI-450: core I/O whitelist guard', () => {
3186
3281
  }
3187
3282
  }
3188
3283
  }
3189
- it('core/src/ production files: only whitelisted files import fs/path', () => {
3284
+ // ── Registry validity (PRI-462) ───────────────────────────────────────────
3285
+ it('io-seam-registry.json is valid: seams array with name/description/files', () => {
3286
+ expect(isValidRegistry(registry)).toBe(true);
3287
+ if (!isValidRegistry(registry))
3288
+ return; // type narrowing
3289
+ expect(registry.seams.length).toBeGreaterThan(0);
3290
+ for (const seam of registry.seams) {
3291
+ expect(seam.name.length).toBeGreaterThan(0);
3292
+ expect(seam.description.length).toBeGreaterThan(0);
3293
+ expect(seam.files.length).toBeGreaterThan(0);
3294
+ }
3295
+ });
3296
+ it('registry has no duplicate files across seams', () => {
3297
+ if (!isValidRegistry(registry)) {
3298
+ // isValidRegistry test above will fail with details; skip here.
3299
+ expect(isValidRegistry(registry)).toBe(true);
3300
+ return;
3301
+ }
3302
+ const seen = new Set();
3303
+ const dupes = [];
3304
+ for (const seam of registry.seams) {
3305
+ for (const f of seam.files) {
3306
+ if (seen.has(f))
3307
+ dupes.push(f);
3308
+ seen.add(f);
3309
+ }
3310
+ }
3311
+ expect(dupes).toEqual([]);
3312
+ });
3313
+ it('every seam description explains why the I/O is allowed (non-trivial)', () => {
3314
+ if (!isValidRegistry(registry)) {
3315
+ expect(isValidRegistry(registry)).toBe(true);
3316
+ return;
3317
+ }
3318
+ const weak = [];
3319
+ for (const seam of registry.seams) {
3320
+ // Description must be at least 20 chars — a single word like "legacy" is
3321
+ // not an explanation. This forces maintainers to write a real rationale.
3322
+ if (seam.description.trim().length < 20) {
3323
+ weak.push(`${seam.name}: "${seam.description}"`);
3324
+ }
3325
+ }
3326
+ expect(weak).toEqual([]);
3327
+ });
3328
+ // ── Registry ↔ production files (PRI-450, EP-02) ──────────────────────────
3329
+ it('core/src/ production files: only registry-listed files import fs/path', () => {
3190
3330
  const coreSrcDir = pathSync.resolve(__dirname, '..', '..');
3191
3331
  const allFiles = [];
3192
3332
  collectTsFiles(coreSrcDir, allFiles);
@@ -3200,9 +3340,13 @@ describe('PRI-450: core I/O whitelist guard', () => {
3200
3340
  }
3201
3341
  }
3202
3342
  }
3203
- expect(violations).toEqual([]);
3343
+ if (violations.length > 0) {
3344
+ throw new Error(`Found ${violations.length} file(s) importing fs/path that are NOT in io-seam-registry.json.\n` +
3345
+ `Add them to the appropriate seam in packages/principles-core/io-seam-registry.json.\n` +
3346
+ `Violations:\n ` + violations.join('\n '));
3347
+ }
3204
3348
  });
3205
- it('ALLOWED_IO_FILES whitelist entries all exist on disk', () => {
3349
+ it('registry-listed files all exist on disk', () => {
3206
3350
  const coreSrcDir = pathSync.resolve(__dirname, '..', '..');
3207
3351
  const missing = [];
3208
3352
  for (const relPath of ALLOWED_IO_FILES) {
@@ -3213,6 +3357,19 @@ describe('PRI-450: core I/O whitelist guard', () => {
3213
3357
  }
3214
3358
  expect(missing).toEqual([]);
3215
3359
  });
3360
+ // ── Registry ↔ ESLint exemption (PRI-462, EP-06 single source of truth) ───
3361
+ //
3362
+ // ESLint's no-restricted-imports exemption list must be DERIVED from the
3363
+ // registry, not hand-maintained. This test verifies eslint.config.js
3364
+ // references the registry file, proving the two stay in sync.
3365
+ it('eslint.config.js derives fs/path exemption from the registry (no shadow list)', () => {
3366
+ const eslintPath = pathSync.resolve(__dirname, '..', '..', '..', '..', '..', 'eslint.config.js');
3367
+ const eslintSrc = fsSync.readFileSync(eslintPath, 'utf-8');
3368
+ // The eslint config must read the registry JSON — if this reference is
3369
+ // removed, someone has reintroduced a hand-maintained shadow list.
3370
+ expect(eslintSrc).toContain('io-seam-registry.json');
3371
+ });
3372
+ // ── Helper unit tests ─────────────────────────────────────────────────────
3216
3373
  it('importsFsOrPath detects sub-path imports (fs/promises) and side-effect imports', () => {
3217
3374
  // Sub-path import
3218
3375
  expect(importsFsOrPath(`import { mkdir } from 'node:fs/promises';`)).toBe(true);