create-principles-disciple 1.92.0 → 1.94.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (335) hide show
  1. package/console/dist/server/config/AuthConfig.js +6 -0
  2. package/console/dist/server/config/pd-config-store.d.ts +7 -1
  3. package/console/dist/server/config/pd-config-store.js +11 -1
  4. package/console/dist/server/index.js +41 -22
  5. package/console/dist/server/models/ApprovalsConsoleModel.js +4 -12
  6. package/console/dist/server/models/ApprovalsGroupedConsoleModel.js +6 -3
  7. package/console/dist/server/models/ConsoleLifecycleDatasource.js +1 -1
  8. package/console/dist/server/routes/activations.js +4 -0
  9. package/console/dist/server/routes/approvals.js +24 -4
  10. package/console/dist/server/routes/feedback-reports.js +7 -5
  11. package/console/dist/server/routes/lifecycle.js +6 -1
  12. package/console/dist/server/routes/principles.js +10 -2
  13. package/console/dist/server/routes/workspaces.js +4 -0
  14. package/console/dist/ui/components/ui/charts.js +4 -1
  15. package/console/dist/ui/components/ui/markdown.js +9 -5
  16. package/console/dist/ui/utils/enum-labels.js +4 -1
  17. package/console/dist/web/assets/app.js +5 -2
  18. package/core/dist/index.d.ts +2 -3
  19. package/core/dist/index.d.ts.map +1 -1
  20. package/core/dist/index.js +1 -3
  21. package/core/dist/index.js.map +1 -1
  22. package/core/dist/pain-signal.d.ts +11 -71
  23. package/core/dist/pain-signal.d.ts.map +1 -1
  24. package/core/dist/pain-signal.js +10 -120
  25. package/core/dist/pain-signal.js.map +1 -1
  26. package/core/dist/principle-tree-ledger.d.ts +4 -87
  27. package/core/dist/principle-tree-ledger.d.ts.map +1 -1
  28. package/core/dist/principle-tree-ledger.js +51 -148
  29. package/core/dist/principle-tree-ledger.js.map +1 -1
  30. package/core/dist/prompt-builder/__tests__/model-config.test.d.ts +2 -0
  31. package/core/dist/prompt-builder/__tests__/model-config.test.d.ts.map +1 -0
  32. package/core/dist/prompt-builder/__tests__/model-config.test.js +158 -0
  33. package/core/dist/prompt-builder/__tests__/model-config.test.js.map +1 -0
  34. package/core/dist/prompt-builder/__tests__/xml-escape.test.d.ts +2 -0
  35. package/core/dist/prompt-builder/__tests__/xml-escape.test.d.ts.map +1 -0
  36. package/core/dist/prompt-builder/__tests__/xml-escape.test.js +42 -0
  37. package/core/dist/prompt-builder/__tests__/xml-escape.test.js.map +1 -0
  38. package/core/dist/prompt-builder/index.d.ts +3 -0
  39. package/core/dist/prompt-builder/index.d.ts.map +1 -1
  40. package/core/dist/prompt-builder/index.js +2 -0
  41. package/core/dist/prompt-builder/index.js.map +1 -1
  42. package/core/dist/prompt-builder/model-config.d.ts +42 -0
  43. package/core/dist/prompt-builder/model-config.d.ts.map +1 -0
  44. package/core/dist/prompt-builder/model-config.js +84 -0
  45. package/core/dist/prompt-builder/model-config.js.map +1 -0
  46. package/core/dist/prompt-builder/xml-escape.d.ts +12 -0
  47. package/core/dist/prompt-builder/xml-escape.d.ts.map +1 -0
  48. package/core/dist/prompt-builder/xml-escape.js +19 -0
  49. package/core/dist/prompt-builder/xml-escape.js.map +1 -0
  50. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js +265 -20
  51. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
  52. package/core/dist/runtime-v2/__tests__/barrel-io-cleanup.test.d.ts +12 -0
  53. package/core/dist/runtime-v2/__tests__/barrel-io-cleanup.test.d.ts.map +1 -0
  54. package/core/dist/runtime-v2/__tests__/barrel-io-cleanup.test.js +46 -0
  55. package/core/dist/runtime-v2/__tests__/barrel-io-cleanup.test.js.map +1 -0
  56. package/core/dist/runtime-v2/__tests__/io-deletion.test.d.ts +12 -0
  57. package/core/dist/runtime-v2/__tests__/io-deletion.test.d.ts.map +1 -0
  58. package/core/dist/runtime-v2/__tests__/io-deletion.test.js +92 -0
  59. package/core/dist/runtime-v2/__tests__/io-deletion.test.js.map +1 -0
  60. package/core/dist/runtime-v2/__tests__/ledger-codec.test.d.ts +2 -0
  61. package/core/dist/runtime-v2/__tests__/ledger-codec.test.d.ts.map +1 -0
  62. package/core/dist/runtime-v2/__tests__/ledger-codec.test.js +429 -0
  63. package/core/dist/runtime-v2/__tests__/ledger-codec.test.js.map +1 -0
  64. package/core/dist/runtime-v2/__tests__/ledger-store.test.d.ts +2 -0
  65. package/core/dist/runtime-v2/__tests__/ledger-store.test.d.ts.map +1 -0
  66. package/core/dist/runtime-v2/__tests__/ledger-store.test.js +65 -0
  67. package/core/dist/runtime-v2/__tests__/ledger-store.test.js.map +1 -0
  68. package/core/dist/runtime-v2/__tests__/pain-signal-bridge-result-shaping.test.d.ts +2 -0
  69. package/core/dist/runtime-v2/__tests__/pain-signal-bridge-result-shaping.test.d.ts.map +1 -0
  70. package/core/dist/runtime-v2/__tests__/pain-signal-bridge-result-shaping.test.js +395 -0
  71. package/core/dist/runtime-v2/__tests__/pain-signal-bridge-result-shaping.test.js.map +1 -0
  72. package/core/dist/runtime-v2/__tests__/pain-signal-observability.test.js +146 -0
  73. package/core/dist/runtime-v2/__tests__/pain-signal-observability.test.js.map +1 -1
  74. package/core/dist/runtime-v2/__tests__/pain-signal-unification.test.d.ts +2 -0
  75. package/core/dist/runtime-v2/__tests__/pain-signal-unification.test.d.ts.map +1 -0
  76. package/core/dist/runtime-v2/__tests__/pain-signal-unification.test.js +150 -0
  77. package/core/dist/runtime-v2/__tests__/pain-signal-unification.test.js.map +1 -0
  78. package/core/dist/runtime-v2/adapter/__tests__/test-double-runtime-adapter.test.js +199 -0
  79. package/core/dist/runtime-v2/adapter/__tests__/test-double-runtime-adapter.test.js.map +1 -1
  80. package/core/dist/runtime-v2/bridge-result-shaper.d.ts +53 -0
  81. package/core/dist/runtime-v2/bridge-result-shaper.d.ts.map +1 -0
  82. package/core/dist/runtime-v2/bridge-result-shaper.js +117 -0
  83. package/core/dist/runtime-v2/bridge-result-shaper.js.map +1 -0
  84. package/core/dist/runtime-v2/detection/__tests__/detection-funnel-policy.test.d.ts +13 -0
  85. package/core/dist/runtime-v2/detection/__tests__/detection-funnel-policy.test.d.ts.map +1 -0
  86. package/core/dist/runtime-v2/detection/__tests__/detection-funnel-policy.test.js +111 -0
  87. package/core/dist/runtime-v2/detection/__tests__/detection-funnel-policy.test.js.map +1 -0
  88. package/core/dist/runtime-v2/detection/detection-funnel-policy.d.ts +103 -0
  89. package/core/dist/runtime-v2/detection/detection-funnel-policy.d.ts.map +1 -0
  90. package/core/dist/runtime-v2/detection/detection-funnel-policy.js +135 -0
  91. package/core/dist/runtime-v2/detection/detection-funnel-policy.js.map +1 -0
  92. package/core/dist/runtime-v2/detection/index.d.ts +10 -0
  93. package/core/dist/runtime-v2/detection/index.d.ts.map +1 -0
  94. package/core/dist/runtime-v2/detection/index.js +9 -0
  95. package/core/dist/runtime-v2/detection/index.js.map +1 -0
  96. package/core/dist/runtime-v2/diagnostician/__tests__/diag-rootcause-output.test.js +156 -0
  97. package/core/dist/runtime-v2/diagnostician/__tests__/diag-rootcause-output.test.js.map +1 -1
  98. package/core/dist/runtime-v2/evidence-triage/__tests__/observation-resolver.test.d.ts +12 -0
  99. package/core/dist/runtime-v2/evidence-triage/__tests__/observation-resolver.test.d.ts.map +1 -0
  100. package/core/dist/runtime-v2/evidence-triage/__tests__/observation-resolver.test.js +181 -0
  101. package/core/dist/runtime-v2/evidence-triage/__tests__/observation-resolver.test.js.map +1 -0
  102. package/core/dist/runtime-v2/evidence-triage/__tests__/triage-policy.test.js +104 -1
  103. package/core/dist/runtime-v2/evidence-triage/__tests__/triage-policy.test.js.map +1 -1
  104. package/core/dist/runtime-v2/evidence-triage/index.d.ts +3 -0
  105. package/core/dist/runtime-v2/evidence-triage/index.d.ts.map +1 -1
  106. package/core/dist/runtime-v2/evidence-triage/index.js +3 -0
  107. package/core/dist/runtime-v2/evidence-triage/index.js.map +1 -1
  108. package/core/dist/runtime-v2/evidence-triage/observation-resolver.d.ts +128 -0
  109. package/core/dist/runtime-v2/evidence-triage/observation-resolver.d.ts.map +1 -0
  110. package/core/dist/runtime-v2/evidence-triage/observation-resolver.js +203 -0
  111. package/core/dist/runtime-v2/evidence-triage/observation-resolver.js.map +1 -0
  112. package/core/dist/runtime-v2/evidence-triage/triage-policy.d.ts +4 -0
  113. package/core/dist/runtime-v2/evidence-triage/triage-policy.d.ts.map +1 -1
  114. package/core/dist/runtime-v2/evidence-triage/triage-policy.js +66 -9
  115. package/core/dist/runtime-v2/evidence-triage/triage-policy.js.map +1 -1
  116. package/core/dist/runtime-v2/evidence-triage/types.d.ts +14 -0
  117. package/core/dist/runtime-v2/evidence-triage/types.d.ts.map +1 -1
  118. package/core/dist/runtime-v2/evidence-triage/types.js.map +1 -1
  119. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js +33 -4
  120. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js.map +1 -1
  121. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
  122. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js +9 -2
  123. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
  124. package/core/dist/runtime-v2/feedback/__tests__/redact-sensitive.test.d.ts +15 -0
  125. package/core/dist/runtime-v2/feedback/__tests__/redact-sensitive.test.d.ts.map +1 -0
  126. package/core/dist/runtime-v2/feedback/__tests__/redact-sensitive.test.js +450 -0
  127. package/core/dist/runtime-v2/feedback/__tests__/redact-sensitive.test.js.map +1 -0
  128. package/core/dist/runtime-v2/feedback/__tests__/render-github-url.test.d.ts +13 -0
  129. package/core/dist/runtime-v2/feedback/__tests__/render-github-url.test.d.ts.map +1 -0
  130. package/core/dist/runtime-v2/feedback/__tests__/render-github-url.test.js +243 -0
  131. package/core/dist/runtime-v2/feedback/__tests__/render-github-url.test.js.map +1 -0
  132. package/core/dist/runtime-v2/feedback/__tests__/safe-stringify.test.d.ts +12 -0
  133. package/core/dist/runtime-v2/feedback/__tests__/safe-stringify.test.d.ts.map +1 -0
  134. package/core/dist/runtime-v2/feedback/__tests__/safe-stringify.test.js +172 -0
  135. package/core/dist/runtime-v2/feedback/__tests__/safe-stringify.test.js.map +1 -0
  136. package/core/dist/runtime-v2/index.d.ts +9 -6
  137. package/core/dist/runtime-v2/index.d.ts.map +1 -1
  138. package/core/dist/runtime-v2/index.js +8 -4
  139. package/core/dist/runtime-v2/index.js.map +1 -1
  140. package/core/dist/runtime-v2/internalization/__tests__/c2-live-runner-chain.test.d.ts +2 -0
  141. package/core/dist/runtime-v2/internalization/__tests__/c2-live-runner-chain.test.d.ts.map +1 -0
  142. package/core/dist/runtime-v2/internalization/__tests__/c2-live-runner-chain.test.js +306 -0
  143. package/core/dist/runtime-v2/internalization/__tests__/c2-live-runner-chain.test.js.map +1 -0
  144. package/core/dist/runtime-v2/internalization/index.d.ts +0 -16
  145. package/core/dist/runtime-v2/internalization/index.d.ts.map +1 -1
  146. package/core/dist/runtime-v2/internalization/index.js +0 -8
  147. package/core/dist/runtime-v2/internalization/index.js.map +1 -1
  148. package/core/dist/runtime-v2/pain-gate/__tests__/pain-diagnostic-gate-policy.test.d.ts +15 -0
  149. package/core/dist/runtime-v2/pain-gate/__tests__/pain-diagnostic-gate-policy.test.d.ts.map +1 -0
  150. package/core/dist/runtime-v2/pain-gate/__tests__/pain-diagnostic-gate-policy.test.js +179 -0
  151. package/core/dist/runtime-v2/pain-gate/__tests__/pain-diagnostic-gate-policy.test.js.map +1 -0
  152. package/core/dist/runtime-v2/pain-gate/index.d.ts +10 -0
  153. package/core/dist/runtime-v2/pain-gate/index.d.ts.map +1 -0
  154. package/core/dist/runtime-v2/pain-gate/index.js +9 -0
  155. package/core/dist/runtime-v2/pain-gate/index.js.map +1 -0
  156. package/core/dist/runtime-v2/pain-gate/pain-diagnostic-gate-policy.d.ts +121 -0
  157. package/core/dist/runtime-v2/pain-gate/pain-diagnostic-gate-policy.d.ts.map +1 -0
  158. package/core/dist/runtime-v2/pain-gate/pain-diagnostic-gate-policy.js +157 -0
  159. package/core/dist/runtime-v2/pain-gate/pain-diagnostic-gate-policy.js.map +1 -0
  160. package/core/dist/runtime-v2/pain-signal-bridge.d.ts.map +1 -1
  161. package/core/dist/runtime-v2/pain-signal-bridge.js +14 -88
  162. package/core/dist/runtime-v2/pain-signal-bridge.js.map +1 -1
  163. package/core/dist/runtime-v2/pain-signal-observability.d.ts.map +1 -1
  164. package/core/dist/runtime-v2/pain-signal-observability.js +15 -5
  165. package/core/dist/runtime-v2/pain-signal-observability.js.map +1 -1
  166. package/core/dist/runtime-v2/principle-tree/ledger-codec.d.ts +30 -0
  167. package/core/dist/runtime-v2/principle-tree/ledger-codec.d.ts.map +1 -0
  168. package/core/dist/runtime-v2/principle-tree/ledger-codec.js +154 -0
  169. package/core/dist/runtime-v2/principle-tree/ledger-codec.js.map +1 -0
  170. package/core/dist/runtime-v2/types/event-types.d.ts +0 -27
  171. package/core/dist/runtime-v2/types/event-types.d.ts.map +1 -1
  172. package/core/dist/runtime-v2/types/event-types.js +2 -17
  173. package/core/dist/runtime-v2/types/event-types.js.map +1 -1
  174. package/core/dist/runtime-v2/types/index.d.ts +4 -2
  175. package/core/dist/runtime-v2/types/index.d.ts.map +1 -1
  176. package/core/dist/runtime-v2/types/index.js +4 -1
  177. package/core/dist/runtime-v2/types/index.js.map +1 -1
  178. package/core/dist/runtime-v2/types/ledger-store.d.ts +101 -0
  179. package/core/dist/runtime-v2/types/ledger-store.d.ts.map +1 -0
  180. package/core/dist/runtime-v2/types/ledger-store.js +15 -0
  181. package/core/dist/runtime-v2/types/ledger-store.js.map +1 -0
  182. package/core/dist/runtime-v2/types/pain-signal.d.ts +7 -5
  183. package/core/dist/runtime-v2/types/pain-signal.d.ts.map +1 -1
  184. package/core/dist/runtime-v2/types/pain-signal.js +25 -5
  185. package/core/dist/runtime-v2/types/pain-signal.js.map +1 -1
  186. package/core/package.json +3 -3
  187. package/dist/installer.d.ts.map +1 -1
  188. package/dist/installer.js +9 -3
  189. package/dist/installer.js.map +1 -1
  190. package/dist/mvp-config.d.ts +0 -10
  191. package/dist/mvp-config.d.ts.map +1 -1
  192. package/dist/mvp-config.js +0 -64
  193. package/dist/mvp-config.js.map +1 -1
  194. package/dist/utils/env.d.ts.map +1 -1
  195. package/dist/utils/env.js +10 -4
  196. package/dist/utils/env.js.map +1 -1
  197. package/package.json +1 -1
  198. package/pd-cli/dist/commands/__tests__/legacy-cleanup.test.js +11 -3
  199. package/pd-cli/dist/commands/__tests__/legacy-cleanup.test.js.map +1 -1
  200. package/pd-cli/dist/commands/candidate.d.ts.map +1 -1
  201. package/pd-cli/dist/commands/candidate.js +2 -1
  202. package/pd-cli/dist/commands/candidate.js.map +1 -1
  203. package/pd-cli/dist/commands/health.d.ts.map +1 -1
  204. package/pd-cli/dist/commands/health.js +2 -1
  205. package/pd-cli/dist/commands/health.js.map +1 -1
  206. package/pd-cli/dist/commands/mvp-smoke.js +1 -1
  207. package/pd-cli/dist/commands/mvp-smoke.js.map +1 -1
  208. package/pd-cli/dist/commands/rulecode.js +1 -1
  209. package/pd-cli/dist/commands/rulecode.js.map +1 -1
  210. package/pd-cli/dist/commands/runtime-canary.d.ts.map +1 -1
  211. package/pd-cli/dist/commands/runtime-canary.js +10 -11
  212. package/pd-cli/dist/commands/runtime-canary.js.map +1 -1
  213. package/pd-cli/dist/commands/runtime-internalization-integrity.d.ts.map +1 -1
  214. package/pd-cli/dist/commands/runtime-internalization-integrity.js +3 -1
  215. package/pd-cli/dist/commands/runtime-internalization-integrity.js.map +1 -1
  216. package/pd-cli/dist/commands/runtime-internalization-queue.d.ts.map +1 -1
  217. package/pd-cli/dist/commands/runtime-internalization-queue.js +13 -16
  218. package/pd-cli/dist/commands/runtime-internalization-queue.js.map +1 -1
  219. package/pd-cli/dist/commands/runtime-internalization-run-once.d.ts.map +1 -1
  220. package/pd-cli/dist/commands/runtime-internalization-run-once.js +3 -0
  221. package/pd-cli/dist/commands/runtime-internalization-run-once.js.map +1 -1
  222. package/pd-cli/dist/commands/runtime-internalization-run-rulehost.d.ts.map +1 -1
  223. package/pd-cli/dist/commands/runtime-internalization-run-rulehost.js +61 -7
  224. package/pd-cli/dist/commands/runtime-internalization-run-rulehost.js.map +1 -1
  225. package/pd-cli/dist/commands/runtime-uat.d.ts.map +1 -1
  226. package/pd-cli/dist/commands/runtime-uat.js +4 -1
  227. package/pd-cli/dist/commands/runtime-uat.js.map +1 -1
  228. package/pd-cli/dist/commands/runtime.js +1 -1
  229. package/pd-cli/dist/commands/runtime.js.map +1 -1
  230. package/pd-cli/dist/index.js +67 -34
  231. package/pd-cli/dist/index.js.map +1 -1
  232. package/pd-cli/dist/legacy/session-history-import.js +7 -5
  233. package/pd-cli/dist/legacy/session-history-import.js.map +1 -1
  234. package/pd-cli/dist/services/__tests__/rulehost-readiness.test.d.ts +2 -0
  235. package/pd-cli/dist/services/__tests__/rulehost-readiness.test.d.ts.map +1 -0
  236. package/pd-cli/dist/services/__tests__/rulehost-readiness.test.js +314 -0
  237. package/pd-cli/dist/services/__tests__/rulehost-readiness.test.js.map +1 -0
  238. package/pd-cli/dist/services/__tests__/runtime-adapter-resolver.test.js +33 -14
  239. package/pd-cli/dist/services/__tests__/runtime-adapter-resolver.test.js.map +1 -1
  240. package/pd-cli/dist/services/pain-flood-simulation-runner.d.ts.map +1 -1
  241. package/pd-cli/dist/services/pain-flood-simulation-runner.js +6 -2
  242. package/pd-cli/dist/services/pain-flood-simulation-runner.js.map +1 -1
  243. package/pd-cli/dist/services/rulehost-readiness.d.ts +62 -0
  244. package/pd-cli/dist/services/rulehost-readiness.d.ts.map +1 -0
  245. package/pd-cli/dist/services/rulehost-readiness.js +214 -0
  246. package/pd-cli/dist/services/rulehost-readiness.js.map +1 -0
  247. package/pd-cli/dist/services/runtime-adapter-resolver.d.ts +1 -1
  248. package/pd-cli/dist/services/runtime-adapter-resolver.d.ts.map +1 -1
  249. package/pd-cli/dist/services/runtime-adapter-resolver.js +9 -7
  250. package/pd-cli/dist/services/runtime-adapter-resolver.js.map +1 -1
  251. package/plugin/dist/commands/capabilities.js +3 -2
  252. package/plugin/dist/commands/disable-impl.js +1 -1
  253. package/plugin/dist/commands/evolution-status.js +0 -2
  254. package/plugin/dist/commands/focus.js +10 -2
  255. package/plugin/dist/commands/rollback-impl.js +1 -1
  256. package/plugin/dist/commands/thinking-os.js +5 -1
  257. package/plugin/dist/core/correction-cue-learner.js +2 -0
  258. package/plugin/dist/core/detection-funnel.d.ts +25 -11
  259. package/plugin/dist/core/detection-funnel.js +32 -80
  260. package/plugin/dist/core/event-log.d.ts +1 -3
  261. package/plugin/dist/core/event-log.js +27 -31
  262. package/plugin/dist/core/evolution-reducer.d.ts +0 -8
  263. package/plugin/dist/core/evolution-reducer.js +9 -19
  264. package/plugin/dist/core/focus-history.js +1 -1
  265. package/plugin/dist/core/hygiene/tracker.js +3 -3
  266. package/plugin/dist/core/pain-diagnostic-gate.d.ts +37 -28
  267. package/plugin/dist/core/pain-diagnostic-gate.js +53 -89
  268. package/plugin/dist/core/pain.d.ts +0 -63
  269. package/plugin/dist/core/pain.js +0 -167
  270. package/plugin/dist/core/paths.d.ts +0 -1
  271. package/plugin/dist/core/paths.js +2 -1
  272. package/plugin/dist/core/principle-compiler/compiler.js +2 -0
  273. package/plugin/dist/core/replay-engine.js +1 -1
  274. package/plugin/dist/core/rule-host.js +3 -1
  275. package/plugin/dist/core/schema/migrations/001-init-trajectory.js +3 -6
  276. package/plugin/dist/core/schema/schema-definitions.js +4 -9
  277. package/plugin/dist/core/thinking-os-parser.js +13 -4
  278. package/plugin/dist/core/trajectory.d.ts +0 -16
  279. package/plugin/dist/core/trajectory.js +9 -60
  280. package/plugin/dist/hooks/after-tool-call-helpers.d.ts +4 -1
  281. package/plugin/dist/hooks/after-tool-call-helpers.js +13 -17
  282. package/plugin/dist/hooks/gate-block-helper.js +57 -17
  283. package/plugin/dist/hooks/lifecycle.js +3 -6
  284. package/plugin/dist/hooks/llm.js +66 -26
  285. package/plugin/dist/hooks/pain.d.ts +3 -1
  286. package/plugin/dist/hooks/pain.js +119 -49
  287. package/plugin/dist/hooks/prompt-helpers.d.ts +87 -0
  288. package/plugin/dist/hooks/prompt-helpers.js +251 -0
  289. package/plugin/dist/hooks/prompt-types.d.ts +66 -0
  290. package/plugin/dist/hooks/prompt-types.js +12 -0
  291. package/plugin/dist/hooks/prompt.d.ts +7 -38
  292. package/plugin/dist/hooks/prompt.js +361 -325
  293. package/plugin/dist/hooks/raw-observation-adapter.d.ts +9 -50
  294. package/plugin/dist/hooks/raw-observation-adapter.js +9 -164
  295. package/plugin/dist/hooks/raw-observation-types.d.ts +6 -57
  296. package/plugin/dist/hooks/raw-observation-types.js +5 -9
  297. package/plugin/dist/hooks/trajectory-collector.d.ts +20 -4
  298. package/plugin/dist/hooks/trajectory-collector.js +95 -156
  299. package/plugin/dist/hooks/triage-adapter.js +6 -26
  300. package/plugin/dist/hooks/trigger-cooldown-tracker.d.ts +12 -0
  301. package/plugin/dist/hooks/trigger-cooldown-tracker.js +25 -0
  302. package/plugin/dist/index.js +7 -2
  303. package/plugin/dist/openclaw-sdk.d.ts +4 -1
  304. package/plugin/dist/service/evolution-worker.js +8 -62
  305. package/plugin/dist/service/internalization-auto-consumer-service.js +2 -1
  306. package/plugin/dist/service/runtime-summary-service.d.ts +0 -2
  307. package/plugin/dist/service/runtime-summary-service.js +8 -5
  308. package/plugin/dist/service/workflow-watchdog.js +2 -1
  309. package/plugin/dist/types/event-types.d.ts +1 -1
  310. package/plugin/dist/utils/retry.js +7 -2
  311. package/plugin/dist/utils/session-key.js +4 -1
  312. package/plugin/scripts/sync-plugin.mjs +33 -22
  313. package/plugin/scripts/validate-live-path.ts +0 -18
  314. package/plugin/templates/langs/en/skills/pd-cli-operator/SKILL.md +20 -11
  315. package/plugin/templates/langs/en/skills/pd-runtime-v2/SKILL.md +10 -0
  316. package/plugin/templates/langs/zh/skills/pd-cli-operator/SKILL.md +20 -11
  317. package/plugin/templates/langs/zh/skills/pd-runtime-v2/SKILL.md +10 -0
  318. package/console/dist/server/config/feature-flags.d.ts +0 -25
  319. package/console/dist/server/config/feature-flags.js +0 -101
  320. package/core/dist/io.d.ts +0 -35
  321. package/core/dist/io.d.ts.map +0 -1
  322. package/core/dist/io.js +0 -95
  323. package/core/dist/io.js.map +0 -1
  324. package/pd-cli/dist/commands/central-sync.d.ts +0 -10
  325. package/pd-cli/dist/commands/central-sync.d.ts.map +0 -1
  326. package/pd-cli/dist/commands/central-sync.js +0 -32
  327. package/pd-cli/dist/commands/central-sync.js.map +0 -1
  328. package/pd-cli/dist/services/feature-flag-loader.d.ts +0 -6
  329. package/pd-cli/dist/services/feature-flag-loader.d.ts.map +0 -1
  330. package/pd-cli/dist/services/feature-flag-loader.js +0 -53
  331. package/pd-cli/dist/services/feature-flag-loader.js.map +0 -1
  332. package/plugin/dist/core/observability.d.ts +0 -40
  333. package/plugin/dist/core/observability.js +0 -164
  334. package/plugin/dist/hooks/subagent.d.ts +0 -9
  335. package/plugin/dist/hooks/subagent.js +0 -122
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Model configuration validation and resolution.
3
+ *
4
+ * Pure logic — no I/O, no side effects (except optional logger callback).
5
+ *
6
+ * Extracted from openclaw-plugin/src/hooks/prompt.ts (PRI-444) so that model
7
+ * config validation can be unit-tested in core without mocking plugin I/O.
8
+ */
9
+ const MODEL_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]\/[a-zA-Z0-9._-]+$/;
10
+ function describeModelConfigType(value) {
11
+ if (value === null)
12
+ return 'null';
13
+ if (Array.isArray(value))
14
+ return 'array';
15
+ return typeof value;
16
+ }
17
+ /**
18
+ * Validate model format: must be "provider/model".
19
+ *
20
+ * provider: e.g., "openai", "anthropic" — the API provider name
21
+ * model: e.g., "gpt-4", "claude-3-opus" — the specific model name
22
+ */
23
+ export function isValidModelFormat(model) {
24
+ return MODEL_PATTERN.test(model);
25
+ }
26
+ /**
27
+ * Resolve model configuration for OpenClaw agents, supporting string and object formats.
28
+ *
29
+ * @param modelConfig - Model config: string (e.g. "provider/model") or { primary, fallbacks } object
30
+ * @param logger - Optional logger for validation warnings
31
+ * @returns Resolved model string, or null if config is missing/invalid
32
+ */
33
+ export function resolveModelFromConfig(modelConfig, logger) {
34
+ if (modelConfig === null || modelConfig === undefined) {
35
+ logger?.warn?.(`[PD:Prompt] Missing model config.`);
36
+ return null;
37
+ }
38
+ // Case 1: modelConfig is a string like "provider/model"
39
+ if (typeof modelConfig === 'string') {
40
+ const trimmed = modelConfig.trim();
41
+ if (!trimmed) {
42
+ logger?.warn?.(`[PD:Prompt] Empty model string.`);
43
+ return null;
44
+ }
45
+ if (!isValidModelFormat(trimmed)) {
46
+ logger?.warn?.(`[PD:Prompt] Invalid model format: "${trimmed}". Expected "provider/model" format.`);
47
+ return null;
48
+ }
49
+ return trimmed;
50
+ }
51
+ // Case 2: modelConfig is an object { primary, fallbacks } like { primary: "provider/model", fallbacks: [...] }
52
+ if (typeof modelConfig === 'object' && modelConfig !== null && !Array.isArray(modelConfig)) {
53
+ if (Object.hasOwn(modelConfig, 'primary')) {
54
+ const primaryDescriptor = Object.getOwnPropertyDescriptor(modelConfig, 'primary');
55
+ if (!primaryDescriptor)
56
+ return null;
57
+ const primary = primaryDescriptor.value;
58
+ if (typeof primary !== 'string') {
59
+ logger?.warn?.(`[PD:Prompt] Invalid primary model type: ${describeModelConfigType(primary)}. Expected string.`);
60
+ return null;
61
+ }
62
+ const trimmed = primary.trim();
63
+ if (!trimmed) {
64
+ logger?.warn?.(`[PD:Prompt] Empty primary model string.`);
65
+ return null;
66
+ }
67
+ if (!isValidModelFormat(trimmed)) {
68
+ logger?.warn?.(`[PD:Prompt] Invalid primary model format: "${trimmed}". Expected "provider/model" format.`);
69
+ return null;
70
+ }
71
+ return trimmed;
72
+ }
73
+ logger?.warn?.(`[PD:Prompt] Missing primary model in object config.`);
74
+ return null;
75
+ }
76
+ // Case 3: Array format not supported
77
+ if (Array.isArray(modelConfig)) {
78
+ logger?.warn?.(`[PD:Prompt] Array model config not supported. Expected "provider/model" string or { primary: "..." } object.`);
79
+ return null;
80
+ }
81
+ logger?.warn?.(`[PD:Prompt] Unsupported model config type: ${describeModelConfigType(modelConfig)}.`);
82
+ return null;
83
+ }
84
+ //# sourceMappingURL=model-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-config.js","sourceRoot":"","sources":["../../src/prompt-builder/model-config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAsBH,MAAM,aAAa,GAAG,wDAAwD,CAAC;AAE/E,SAAS,uBAAuB,CAAC,KAAc;IAC7C,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IAClC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IACzC,OAAO,OAAO,KAAK,CAAC;AACtB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,OAAO,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CACpC,WAAoB,EACpB,MAAmB;IAEnB,IAAI,WAAW,KAAK,IAAI,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QACtD,MAAM,EAAE,IAAI,EAAE,CAAC,mCAAmC,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,wDAAwD;IACxD,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,EAAE,IAAI,EAAE,CAAC,iCAAiC,CAAC,CAAC;YAClD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;YACjC,MAAM,EAAE,IAAI,EAAE,CAAC,sCAAsC,OAAO,sCAAsC,CAAC,CAAC;YACpG,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,+GAA+G;IAC/G,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QAC3F,IAAI,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE,CAAC;YAC1C,MAAM,iBAAiB,GAAG,MAAM,CAAC,wBAAwB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;YAClF,IAAI,CAAC,iBAAiB;gBAAE,OAAO,IAAI,CAAC;YACpC,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,CAAC;YACxC,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAChC,MAAM,EAAE,IAAI,EAAE,CAAC,2CAA2C,uBAAuB,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;gBAChH,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;YAC/B,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,EAAE,IAAI,EAAE,CAAC,yCAAyC,CAAC,CAAC;gBAC1D,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;gBACjC,MAAM,EAAE,IAAI,EAAE,CAAC,8CAA8C,OAAO,sCAAsC,CAAC,CAAC;gBAC5G,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,MAAM,EAAE,IAAI,EAAE,CAAC,qDAAqD,CAAC,CAAC;QACtE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qCAAqC;IACrC,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/B,MAAM,EAAE,IAAI,EAAE,CAAC,8GAA8G,CAAC,CAAC;QAC/H,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,CAAC,8CAA8C,uBAAuB,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACtG,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Escape special XML characters in a string.
3
+ *
4
+ * Pure logic — no I/O, no side effects.
5
+ *
6
+ * Used by prompt injection to safely embed user/principle text into XML-style
7
+ * prompt markers (e.g. `<directive id="...">...</directive>`). Also accepted
8
+ * as a callback by `trimToBudget` and `renderPrinciplesToDirectives` in
9
+ * `runtime-v2/activation/prompt-activation-reader-contract.ts`.
10
+ */
11
+ export declare function escapeXml(input: string): string;
12
+ //# sourceMappingURL=xml-escape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xml-escape.d.ts","sourceRoot":"","sources":["../../src/prompt-builder/xml-escape.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAO/C"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Escape special XML characters in a string.
3
+ *
4
+ * Pure logic — no I/O, no side effects.
5
+ *
6
+ * Used by prompt injection to safely embed user/principle text into XML-style
7
+ * prompt markers (e.g. `<directive id="...">...</directive>`). Also accepted
8
+ * as a callback by `trimToBudget` and `renderPrinciplesToDirectives` in
9
+ * `runtime-v2/activation/prompt-activation-reader-contract.ts`.
10
+ */
11
+ export function escapeXml(input) {
12
+ return input
13
+ .replace(/&/g, '&amp;')
14
+ .replace(/</g, '&lt;')
15
+ .replace(/>/g, '&gt;')
16
+ .replace(/"/g, '&quot;')
17
+ .replace(/'/g, '&apos;');
18
+ }
19
+ //# sourceMappingURL=xml-escape.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xml-escape.js","sourceRoot":"","sources":["../../src/prompt-builder/xml-escape.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC"}
@@ -5,6 +5,8 @@
5
5
  * Add entries here whenever a new service/read-model boundary is established.
6
6
  */
7
7
  import { describe, it, expect, beforeAll } from 'vitest';
8
+ import * as fsSync from 'fs';
9
+ import * as pathSync from 'path';
8
10
  // ── Source-file existence ──────────────────────────────────────────────────
9
11
  const REQUIRED_SOURCE_FILES = [
10
12
  'pain-to-principle-service.ts',
@@ -193,6 +195,12 @@ const REQUIRED_SOURCE_FILES = [
193
195
  'activation/approval-completion-service.ts',
194
196
  // PRI-431: L2 principle reader (pure logic, extracted from pd-cli + plugin duplicates)
195
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',
196
204
  ];
197
205
  // ── PRI-212: Plugin core anti-growth guard ────────────────────────────────────
198
206
  //
@@ -245,6 +253,9 @@ const KNOWN_PLUGIN_CORE_FILES = new Set([
245
253
  'schema/migration-runner.ts',
246
254
  'rule-host.ts',
247
255
  'principle-training-state.ts',
256
+ // PRI-446: now a thin adapter delegating pure decision logic to
257
+ // runtime-v2/pain-gate/pain-diagnostic-gate-policy.ts. Kept here because it
258
+ // owns the cooldown Map + SystemLogger + Date.now side effects.
248
259
  'pain-diagnostic-gate.ts',
249
260
  'hygiene/tracker.ts',
250
261
  'schema/migrations/002-init-central.ts',
@@ -287,6 +298,9 @@ const KNOWN_PLUGIN_CORE_FILES = new Set([
287
298
  'dictionary.ts',
288
299
  'thinking-os-parser.ts',
289
300
  'system-logger.ts',
301
+ // PRI-446: now a thin shell wiring DetectionFunnelCore (core runtime-v2/detection)
302
+ // with crypto.createHash + PainDictionary. Kept here because it owns the
303
+ // crypto + dictionary I/O boundary.
290
304
  'detection-funnel.ts',
291
305
  'risk-calculator.ts',
292
306
  'migration.ts',
@@ -359,6 +373,9 @@ describe('PRI-212 plugin core anti-growth guard', () => {
359
373
  // model-training-registry.ts, model-deployment-registry.ts,
360
374
  // shadow-observation-registry.ts (98 → 93)
361
375
  // PRI-449: Removed external-training-contract.ts (93 → 92)
376
+ // PRI-446: pain-diagnostic-gate.ts and detection-funnel.ts remain at 92 —
377
+ // they are now thin adapters delegating pure logic to core, but still live
378
+ // in plugin src/core/ and own I/O side effects, so they stay classified.
362
379
  expect(KNOWN_PLUGIN_CORE_FILES.size).toBe(92);
363
380
  });
364
381
  });
@@ -595,6 +612,30 @@ describe('PRI-42 internalization boundary', () => {
595
612
  expect(src).not.toContain('../../../openclaw-plugin');
596
613
  }
597
614
  });
615
+ it('PRI-446: pain-gate has zero openclaw-plugin imports', async () => {
616
+ const { existsSync, readdirSync, readFileSync } = await import('node:fs');
617
+ const { resolve, join } = await import('node:path');
618
+ const dir = resolve(__dirname, '..', 'pain-gate');
619
+ expect(existsSync(dir)).toBe(true);
620
+ const files = readdirSync(dir).filter((f) => f.endsWith('.ts') && !f.endsWith('.test.ts'));
621
+ for (const file of files) {
622
+ const src = readFileSync(join(dir, file), 'utf-8');
623
+ expect(src).not.toContain('openclaw-plugin');
624
+ expect(src).not.toContain('../../../openclaw-plugin');
625
+ }
626
+ });
627
+ it('PRI-446: detection has zero openclaw-plugin imports', async () => {
628
+ const { existsSync, readdirSync, readFileSync } = await import('node:fs');
629
+ const { resolve, join } = await import('node:path');
630
+ const dir = resolve(__dirname, '..', 'detection');
631
+ expect(existsSync(dir)).toBe(true);
632
+ const files = readdirSync(dir).filter((f) => f.endsWith('.ts') && !f.endsWith('.test.ts'));
633
+ for (const file of files) {
634
+ const src = readFileSync(join(dir, file), 'utf-8');
635
+ expect(src).not.toContain('openclaw-plugin');
636
+ expect(src).not.toContain('../../../openclaw-plugin');
637
+ }
638
+ });
598
639
  it('plugin does not re-define RuleHost contract types locally', async () => {
599
640
  const { existsSync, readFileSync } = await import('node:fs');
600
641
  const { resolve } = await import('node:path');
@@ -1596,6 +1637,16 @@ describe('PRI-75/PRI-74/PRI-81 prompt-builder core boundary', () => {
1596
1637
  // Must NOT have the old multi-line fallback block with attitudeDirective interpolation
1597
1638
  expect(src).not.toMatch(/## 【CONTEXT SECTIONS】\n\n\[WARNING: Context sections stripped/);
1598
1639
  });
1640
+ it('plugin prompt-helpers.ts imports escapeXml from core, not reimplemented', async () => {
1641
+ const { readFileSync } = await import('node:fs');
1642
+ const { resolve } = await import('node:path');
1643
+ const src = readFileSync(resolve(__dirname, '../../../../openclaw-plugin/src/hooks/prompt-helpers.ts'), 'utf-8');
1644
+ // Must import escapeXml from core
1645
+ expect(src).toContain('@principles/core/prompt-builder');
1646
+ expect(src).toMatch(/import\s*\{[^}]*escapeXml[^}]*\}\s*from\s*['"]@principles\/core\/prompt-builder['"]/);
1647
+ // Must NOT reimplement escapeXml inline
1648
+ expect(src).not.toMatch(/\b(function\s+escapeXml\s*\(|const\s+escapeXml\s*=\s*(?:async\s*)?(?:\([^)]*\)|[a-zA-Z_$][\w$]*)\s*=>)/);
1649
+ });
1599
1650
  it('plugin empathy-keyword-matcher.ts is a thin adapter (re-exports from core)', async () => {
1600
1651
  const { readFileSync } = await import('node:fs');
1601
1652
  const { resolve } = await import('node:path');
@@ -1753,6 +1804,19 @@ describe('PRI-111 ArtificerRunner boundary', () => {
1753
1804
  expect(src).toContain('ArtificerRuleOutputSchema');
1754
1805
  });
1755
1806
  });
1807
+ // ── PRI-458: PhilosopherRunner barrel boundary (MVP-Quiet) ─────────────────────
1808
+ describe('PRI-458 PhilosopherRunner barrel boundary', () => {
1809
+ it('BARREL_EXPORTS: internalization/index.ts does NOT export PhilosopherRunner (PRI-458 MVP-Quiet)', async () => {
1810
+ // PRI-458: PhilosopherRunner is de-surfaced from the internal barrel (MVP-Quiet).
1811
+ // It remains in runtime-v2/index.ts (public barrel) because rulehost-pipeline-runner.ts
1812
+ // imports it from there (EP-02 exception).
1813
+ const { readFileSync } = await import('node:fs');
1814
+ const { resolve } = await import('node:path');
1815
+ const src = readFileSync(resolve(__dirname, '..', 'internalization', 'index.ts'), 'utf-8');
1816
+ expect(src).not.toContain("from './philosopher-runner.js'");
1817
+ expect(src).not.toContain("from './philosopher-output.js'");
1818
+ });
1819
+ });
1756
1820
  // ── PRI-EVAL: EvaluatorRunner boundary guards ──────────────────────────────────
1757
1821
  describe('PRI-EVAL EvaluatorRunner boundary', () => {
1758
1822
  it('evaluator source files exist in internalization directory', async () => {
@@ -1793,13 +1857,17 @@ describe('PRI-EVAL EvaluatorRunner boundary', () => {
1793
1857
  expect(src).not.toContain('node:fs');
1794
1858
  expect(src).not.toContain('node:cron');
1795
1859
  });
1796
- it('BARREL_EXPORTS: internalization/index.ts exports EvaluatorRunner and EvaluatorOutput', async () => {
1860
+ it('BARREL_EXPORTS: internalization/index.ts does NOT export EvaluatorRunner (PRI-458 MVP-Quiet)', async () => {
1861
+ // PRI-458: EvaluatorRunner is de-surfaced from the internal barrel (MVP-Quiet).
1862
+ // It remains in runtime-v2/index.ts (public barrel) because rulehost-pipeline-runner.ts
1863
+ // imports it from there (EP-02 exception). These negative assertions lock the boundary:
1864
+ // if someone re-aggregates the evaluator exports into this barrel, the test will fail.
1797
1865
  const { readFileSync } = await import('node:fs');
1798
1866
  const { resolve } = await import('node:path');
1799
1867
  const src = readFileSync(resolve(__dirname, '..', 'internalization', 'index.ts'), 'utf-8');
1800
- expect(src).toContain('EvaluatorRunner');
1801
- expect(src).toContain('EvaluatorOutput');
1802
- expect(src).toContain('DefaultEvaluatorValidator');
1868
+ expect(src).not.toContain("from './evaluator-runner.js'");
1869
+ expect(src).not.toContain("from './evaluator-output.js'");
1870
+ expect(src).not.toContain("from './evaluator-prompt-builder.js'");
1803
1871
  });
1804
1872
  it('SCHEMA_REGISTRY: pi-ai-runtime-adapter.ts registers evaluator-output-v1 schema', async () => {
1805
1873
  const { readFileSync } = await import('node:fs');
@@ -1849,13 +1917,16 @@ describe('PRI-RR RolloutReviewerRunner boundary', () => {
1849
1917
  expect(src).not.toContain('node:fs');
1850
1918
  expect(src).not.toContain('node:cron');
1851
1919
  });
1852
- it('BARREL_EXPORTS: internalization/index.ts exports RolloutReviewerRunner and RolloutReviewerOutput', async () => {
1920
+ it('BARREL_EXPORTS: internalization/index.ts does NOT export RolloutReviewerRunner (PRI-458 MVP-Quiet)', async () => {
1921
+ // PRI-458: RolloutReviewerRunner is de-surfaced from the internal barrel (MVP-Quiet).
1922
+ // It remains in runtime-v2/index.ts (public barrel) because runtime-internalization-run-once.ts
1923
+ // imports it from there and package.json has no deep import path available (EP-02 exception).
1853
1924
  const { readFileSync } = await import('node:fs');
1854
1925
  const { resolve } = await import('node:path');
1855
1926
  const src = readFileSync(resolve(__dirname, '..', 'internalization', 'index.ts'), 'utf-8');
1856
- expect(src).toContain('RolloutReviewerRunner');
1857
- expect(src).toContain('RolloutReviewerOutput');
1858
- expect(src).toContain('DefaultRolloutReviewerValidator');
1927
+ expect(src).not.toContain("from './rollout-reviewer-runner.js'");
1928
+ expect(src).not.toContain("from './rollout-reviewer-output.js'");
1929
+ expect(src).not.toContain("from './rollout-reviewer-prompt-builder.js'");
1859
1930
  });
1860
1931
  it('SCHEMA_REGISTRY: pi-ai-runtime-adapter.ts registers rollout-reviewer-output-v1 schema', async () => {
1861
1932
  const { readFileSync } = await import('node:fs');
@@ -2125,12 +2196,14 @@ describe('PRI-117 Nocturnal god-class freeze', () => {
2125
2196
  expect(src).not.toContain('invokeStubScribe');
2126
2197
  }
2127
2198
  });
2128
- it('RUNTIME_V2_USES_PEER_RUNNERS: DreamerRunner/PhilosopherRunner/ScribeRunner are the canonical entry points', async () => {
2199
+ it('RUNTIME_V2_USES_PEER_RUNNERS: DreamerRunner/ScribeRunner/ArtificerRunner are the canonical MVP-Core entry points', async () => {
2200
+ // PRI-458: narrowed to MVP-Core runners only. PhilosopherRunner (MVP-Quiet)
2201
+ // remains in runtime-v2/index.ts for rulehost-pipeline-runner.ts compatibility
2202
+ // but is no longer asserted as a canonical entry point.
2129
2203
  const { readFileSync } = await import('node:fs');
2130
2204
  const { resolve } = await import('node:path');
2131
2205
  const src = readFileSync(resolve(__dirname, '..', 'index.ts'), 'utf-8');
2132
2206
  expect(src).toContain('DreamerRunner');
2133
- expect(src).toContain('PhilosopherRunner');
2134
2207
  expect(src).toContain('ScribeRunner');
2135
2208
  expect(src).toContain('ArtificerRunner');
2136
2209
  });
@@ -2427,7 +2500,8 @@ describe('PRI-139 L1 Hard Cap & LRU Eviction', () => {
2427
2500
  it('LedgerPrinciple includes lastTriggeredAt field', async () => {
2428
2501
  const { readFileSync } = await import('node:fs');
2429
2502
  const { resolve } = await import('node:path');
2430
- const src = readFileSync(resolve(__dirname, '..', '..', 'principle-tree-ledger.ts'), 'utf-8');
2503
+ // PRI-443: type moved to pure module
2504
+ const src = readFileSync(resolve(__dirname, '..', 'types', 'ledger-store.ts'), 'utf-8');
2431
2505
  expect(src).toContain('lastTriggeredAt');
2432
2506
  });
2433
2507
  it('PruningHealthSummary includes activeL1Count and l1Cap fields', async () => {
@@ -2875,7 +2949,7 @@ describe('PRI-225: No unsafe type assertions on untrusted metadata arrays', () =
2875
2949
  // ── PRI-239: Feature flag registry architecture boundary ──────────────────
2876
2950
  //
2877
2951
  // Core: packages/principles-core/src/runtime-v2/feature-flags/feature-flag-contract.ts
2878
- // I/O Loader: packages/pd-cli/src/services/feature-flag-loader.ts
2952
+ // I/O Loader: packages/pd-cli/src/services/pd-config-loader.ts (PRI-460: replaced feature-flag-loader.ts)
2879
2953
  // CLI Command: packages/pd-cli/src/commands/runtime-features.ts
2880
2954
  // Consumption: packages/pd-cli/src/commands/runtime-canary.ts (GFI check)
2881
2955
  describe('PRI-239: Feature flag registry architecture boundary', () => {
@@ -2897,10 +2971,10 @@ describe('PRI-239: Feature flag registry architecture boundary', () => {
2897
2971
  expect(src).not.toContain('InternalizationOrchestrator');
2898
2972
  expect(src).not.toContain('SqliteConnection');
2899
2973
  });
2900
- it('IO_LOADER_OUTSIDE_CORE: I/O loader exists at pd-cli/src/services/feature-flag-loader.ts', async () => {
2974
+ it('IO_LOADER_OUTSIDE_CORE: I/O loader exists at pd-cli/src/services/pd-config-loader.ts', async () => {
2901
2975
  const { existsSync } = await import('node:fs');
2902
2976
  const { resolve } = await import('node:path');
2903
- expect(existsSync(resolve(__dirname, '../../../../pd-cli/src/services/feature-flag-loader.ts'))).toBe(true);
2977
+ expect(existsSync(resolve(__dirname, '../../../../pd-cli/src/services/pd-config-loader.ts'))).toBe(true);
2904
2978
  });
2905
2979
  it('CLI_COMMAND_OUTSIDE_CORE: CLI command exists at pd-cli/src/commands/runtime-features.ts', async () => {
2906
2980
  const { existsSync } = await import('node:fs');
@@ -2915,12 +2989,12 @@ describe('PRI-239: Feature flag registry architecture boundary', () => {
2915
2989
  expect(src).not.toContain('nocturnal-arbiter');
2916
2990
  expect(src).not.toContain('nocturnal-service');
2917
2991
  });
2918
- it('CONSUMPTION_WIRED: runtime-canary.ts imports feature flag loader', async () => {
2992
+ it('CONSUMPTION_WIRED: runtime-canary.ts imports canonical PD config loader', async () => {
2919
2993
  const { readFileSync } = await import('node:fs');
2920
2994
  const { resolve } = await import('node:path');
2921
2995
  const src = readFileSync(resolve(__dirname, '../../../../pd-cli/src/commands/runtime-canary.ts'), 'utf-8');
2922
- expect(src).toContain('feature-flag-loader');
2923
- expect(src).toContain('loadEffectiveFeatureFlags');
2996
+ expect(src).toContain('pd-config-loader');
2997
+ expect(src).toContain('loadPdConfig');
2924
2998
  });
2925
2999
  });
2926
3000
  describe('PRI-304: PD-Owned Config Contract barrel exports and purity', () => {
@@ -3022,11 +3096,18 @@ describe('PRI-416: type single-ownership guards', () => {
3022
3096
  });
3023
3097
  it('HybridLedgerStore is defined exactly once in core/src/', () => {
3024
3098
  const hits = findDefinitions(/export\s+interface\s+HybridLedgerStore\s*\{/);
3025
- expect(hits).toEqual(['principle-tree-ledger.ts']);
3099
+ expect(hits).toEqual(['runtime-v2/types/ledger-store.ts']);
3026
3100
  });
3027
- it('atomicWriteFileSync is defined exactly once in core/src/', () => {
3101
+ it('atomicWriteFileSync is NOT exported from any core/src/ file (PRI-443 Phase 4)', () => {
3102
+ // After PRI-443 Phase 4, atomicWriteFileSync is inlined as a PRIVATE helper
3103
+ // inside principle-tree-ledger.ts. It must NOT be exported from core.
3028
3104
  const hits = findDefinitions(/export\s+function\s+atomicWriteFileSync\s*\(/);
3029
- expect(hits).toEqual(['io.ts']);
3105
+ expect(hits).toEqual([]);
3106
+ });
3107
+ it('atomicWriteFileSync is defined exactly once as a private function in principle-tree-ledger.ts (PRI-443 Phase 4)', () => {
3108
+ // The function is now a private (non-exported) helper inlined in principle-tree-ledger.ts
3109
+ const hits = findDefinitions(/function\s+atomicWriteFileSync\s*\(/);
3110
+ expect(hits).toEqual(['principle-tree-ledger.ts']);
3030
3111
  });
3031
3112
  });
3032
3113
  // ── PRI-416: Barrel Cap Guards ────────────────────────────────────────────────
@@ -3054,4 +3135,168 @@ describe('PRI-416: barrel cap guards', () => {
3054
3135
  expect(exportLines.length).toBeLessThanOrEqual(BARREL_MAX_EXPORT_LINES);
3055
3136
  });
3056
3137
  });
3138
+ // ── PRI-443: Pure module boundary guards ──────────────────────────────────────
3139
+ //
3140
+ // Phases 1-3 extracted pure types/codecs/schema out of I/O modules. These guards
3141
+ // ensure those pure modules never regress to importing fs/path, and that the
3142
+ // runtime-v2 barrel never re-exports I/O functions from principle-tree-ledger.
3143
+ describe('PRI-443: pure module boundary guards', () => {
3144
+ const FORBIDDEN_PURE_IMPORTS = [
3145
+ "from 'fs'",
3146
+ 'from "fs"',
3147
+ "from 'node:fs'",
3148
+ 'from "node:fs"',
3149
+ "from 'path'",
3150
+ 'from "path"',
3151
+ "from 'node:path'",
3152
+ 'from "node:path"',
3153
+ ];
3154
+ async function readSrc(relPath) {
3155
+ const fsMod = await import('fs'); // eslint-disable-line @typescript-eslint/consistent-type-imports
3156
+ const pathMod = await import('path'); // eslint-disable-line @typescript-eslint/consistent-type-imports
3157
+ const full = pathMod.resolve(__dirname, '..', relPath);
3158
+ return fsMod.readFileSync(full, 'utf-8');
3159
+ }
3160
+ it('runtime-v2/types/ledger-store.ts has zero fs/path imports (pure types module)', async () => {
3161
+ const src = await readSrc('types/ledger-store.ts');
3162
+ for (const pat of FORBIDDEN_PURE_IMPORTS) {
3163
+ expect(src).not.toContain(pat);
3164
+ }
3165
+ });
3166
+ it('runtime-v2/principle-tree/ledger-codec.ts has zero fs/path imports (pure codec module)', async () => {
3167
+ const src = await readSrc('principle-tree/ledger-codec.ts');
3168
+ for (const pat of FORBIDDEN_PURE_IMPORTS) {
3169
+ expect(src).not.toContain(pat);
3170
+ }
3171
+ });
3172
+ it('runtime-v2/types/pain-signal.ts has zero fs/path imports (pure schema module)', async () => {
3173
+ const src = await readSrc('types/pain-signal.ts');
3174
+ for (const pat of FORBIDDEN_PURE_IMPORTS) {
3175
+ expect(src).not.toContain(pat);
3176
+ }
3177
+ });
3178
+ it('runtime-v2/index.ts barrel does NOT export I/O functions from principle-tree-ledger', async () => {
3179
+ const src = await readSrc('index.ts');
3180
+ // I/O functions must not be re-exported through the pure-types barrel.
3181
+ expect(src).not.toMatch(/export\s+\{[^}]*\bloadLedger\b[^}]*\}\s*from\s*['"]\.\.\/principle-tree-ledger/);
3182
+ expect(src).not.toMatch(/export\s+\{[^}]*\bsaveLedger\b[^}]*\}\s*from\s*['"]\.\.\/principle-tree-ledger/);
3183
+ expect(src).not.toMatch(/export\s+\{[^}]*\bgetLedgerFilePathPublic\b[^}]*\}\s*from\s*['"]\.\.\/principle-tree-ledger/);
3184
+ expect(src).not.toMatch(/export\s+\{[^}]*\bupdatePrinciple\b[^}]*\}\s*from\s*['"]\.\.\/principle-tree-ledger/);
3185
+ expect(src).not.toMatch(/export\s+\{[^}]*\batomicWriteFileSync\b[^}]*\}\s*from\s*['"]\.\.\/principle-tree-ledger/);
3186
+ });
3187
+ it('runtime-v2/index.ts barrel re-exports LedgerTreeStore type from pure types module, not from principle-tree-ledger', async () => {
3188
+ const src = await readSrc('index.ts');
3189
+ // The type must come from the pure types module (./types/ledger-store.js),
3190
+ // NOT from the I/O module (../principle-tree-ledger.js).
3191
+ expect(src).toMatch(/export\s+type\s+\{\s*LedgerTreeStore\s*\}\s*from\s*['"]\.\/types\/ledger-store\.js['"]/);
3192
+ expect(src).not.toMatch(/export\s+type\s+\{\s*LedgerTreeStore\s*\}\s*from\s*['"]\.\.\/principle-tree-ledger\.js['"]/);
3193
+ });
3194
+ });
3195
+ // ── PRI-450: Core I/O whitelist guard ──────────────────────────────────────────
3196
+ //
3197
+ // Scans all production (.ts, non-test) files under packages/principles-core/src/
3198
+ // for fs/path imports and verifies they match an explicit whitelist. Any new file
3199
+ // that needs I/O must be added to ALLOWED_IO_FILES here — otherwise CI fails.
3200
+ // This forces developers to explain "why does this file need I/O?" in their PR.
3201
+ describe('PRI-450: core I/O whitelist guard', () => {
3202
+ // Whitelist of production files allowed to import fs/path.
3203
+ // Paths are relative to packages/principles-core/src/.
3204
+ const ALLOWED_IO_FILES = new Set([
3205
+ 'principle-tree-ledger.ts',
3206
+ 'evolution-store.ts',
3207
+ 'trajectory-store.ts',
3208
+ 'workflow-funnel-loader.ts',
3209
+ 'runtime-v2/store/sqlite-connection.ts',
3210
+ 'runtime-v2/store/runtime-state-manager.ts',
3211
+ 'runtime-v2/adapter/openclaw-cli-runtime-adapter.ts',
3212
+ 'runtime-v2/candidate-audit.ts',
3213
+ 'runtime-v2/pain-signal-observability.ts',
3214
+ 'runtime-v2/internalization-chain-integrity-read-model.ts',
3215
+ 'runtime-v2/internalization-integrity-remediation.ts',
3216
+ 'runtime-v2/operator-health-read-model.ts',
3217
+ 'runtime-v2/pain-chain-read-model.ts',
3218
+ 'runtime-v2/pruning-read-model.ts',
3219
+ 'runtime-v2/pruning-review-log.ts',
3220
+ 'runtime-v2/schema-conformance-read-model.ts',
3221
+ ]);
3222
+ // Extract all import module paths from source code.
3223
+ // Handles: import ... from 'mod', import 'mod' (side-effect), and multiline imports.
3224
+ // Reuses the same pattern proven in the PRI-215 extractImportModulePaths helper.
3225
+ function extractImportPaths(src) {
3226
+ const paths = [];
3227
+ for (const m of src.matchAll(/import\s+[\s\S]*?from\s+['"]([^'"]+)['"]/g)) {
3228
+ if (m[1] != null)
3229
+ paths.push(m[1]);
3230
+ }
3231
+ for (const m of src.matchAll(/import\s+['"]([^'"]+)['"]/g)) {
3232
+ if (m[1] != null && !paths.includes(m[1]))
3233
+ paths.push(m[1]);
3234
+ }
3235
+ return paths;
3236
+ }
3237
+ // Check if any import path references fs or path (including sub-paths like fs/promises).
3238
+ function importsFsOrPath(src) {
3239
+ const paths = extractImportPaths(src);
3240
+ return paths.some((p) => p === 'fs' || p.startsWith('fs/') ||
3241
+ p === 'node:fs' || p.startsWith('node:fs/') ||
3242
+ p === 'path' || p.startsWith('path/') ||
3243
+ p === 'node:path' || p.startsWith('node:path/'));
3244
+ }
3245
+ function collectTsFiles(dir, acc) {
3246
+ const entries = fsSync.readdirSync(dir, { withFileTypes: true });
3247
+ for (const entry of entries) {
3248
+ const fullPath = pathSync.join(dir, entry.name);
3249
+ if (entry.isDirectory()) {
3250
+ collectTsFiles(fullPath, acc);
3251
+ }
3252
+ else if (entry.isFile() &&
3253
+ entry.name.endsWith('.ts') &&
3254
+ !entry.name.endsWith('.test.ts') &&
3255
+ !entry.name.endsWith('.spec.ts')) {
3256
+ acc.push(fullPath);
3257
+ }
3258
+ }
3259
+ }
3260
+ it('core/src/ production files: only whitelisted files import fs/path', () => {
3261
+ const coreSrcDir = pathSync.resolve(__dirname, '..', '..');
3262
+ const allFiles = [];
3263
+ collectTsFiles(coreSrcDir, allFiles);
3264
+ const violations = [];
3265
+ for (const filePath of allFiles) {
3266
+ const content = fsSync.readFileSync(filePath, 'utf-8');
3267
+ if (importsFsOrPath(content)) {
3268
+ const relPath = pathSync.relative(coreSrcDir, filePath).replace(/\\/g, '/');
3269
+ if (!ALLOWED_IO_FILES.has(relPath)) {
3270
+ violations.push(relPath);
3271
+ }
3272
+ }
3273
+ }
3274
+ expect(violations).toEqual([]);
3275
+ });
3276
+ it('ALLOWED_IO_FILES whitelist entries all exist on disk', () => {
3277
+ const coreSrcDir = pathSync.resolve(__dirname, '..', '..');
3278
+ const missing = [];
3279
+ for (const relPath of ALLOWED_IO_FILES) {
3280
+ const fullPath = pathSync.join(coreSrcDir, ...relPath.split('/'));
3281
+ if (!fsSync.existsSync(fullPath)) {
3282
+ missing.push(relPath);
3283
+ }
3284
+ }
3285
+ expect(missing).toEqual([]);
3286
+ });
3287
+ it('importsFsOrPath detects sub-path imports (fs/promises) and side-effect imports', () => {
3288
+ // Sub-path import
3289
+ expect(importsFsOrPath(`import { mkdir } from 'node:fs/promises';`)).toBe(true);
3290
+ expect(importsFsOrPath(`import { posix } from 'path/posix';`)).toBe(true);
3291
+ // Side-effect import
3292
+ expect(importsFsOrPath(`import 'fs';`)).toBe(true);
3293
+ expect(importsFsOrPath(`import "node:path";`)).toBe(true);
3294
+ // Standard import
3295
+ expect(importsFsOrPath(`import * as fs from 'fs';`)).toBe(true);
3296
+ expect(importsFsOrPath(`import { resolve } from 'node:path';`)).toBe(true);
3297
+ // Non-fs/path imports
3298
+ expect(importsFsOrPath(`import { foo } from 'bar';`)).toBe(false);
3299
+ expect(importsFsOrPath(``)).toBe(false);
3300
+ });
3301
+ });
3057
3302
  //# sourceMappingURL=architecture-regression.test.js.map