create-principles-disciple 1.144.27 → 1.145.1

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 (347) hide show
  1. package/LICENSE +73 -21
  2. package/NOTICE +2 -0
  3. package/README.md +1 -1
  4. package/_release/product-identity.json +2 -2
  5. package/codex-adapter/dist/index.d.ts +2 -2
  6. package/codex-adapter/dist/index.js +1 -1
  7. package/codex-adapter/dist/ingestion/admission.js +16 -0
  8. package/codex-adapter/dist/ingestion/codex-version.d.ts +10 -4
  9. package/codex-adapter/dist/ingestion/codex-version.js +10 -4
  10. package/codex-adapter/dist/ingestion/explicit-owner-statement.d.ts +48 -0
  11. package/codex-adapter/dist/ingestion/explicit-owner-statement.js +123 -0
  12. package/codex-adapter/dist/ingestion/ingestion.js +50 -1
  13. package/codex-adapter/dist/pd-hook.js +66 -3
  14. package/codex-adapter/dist/worker/workspace-worker.d.ts +14 -0
  15. package/codex-adapter/dist/worker/workspace-worker.js +194 -11
  16. package/codex-adapter/package.json +6 -4
  17. package/console/dist/server/models/ApprovalsConsoleModel.d.ts +2 -2
  18. package/console/dist/server/models/ApprovalsConsoleModel.js +1 -1
  19. package/console/dist/server/models/ApprovalsGroupedConsoleModel.js +1 -1
  20. package/console/dist/server/models/PrinciplesConsoleModel.d.ts +26 -1
  21. package/console/dist/server/models/PrinciplesConsoleModel.js +18 -1
  22. package/console/dist/server/routes/activations.js +4 -4
  23. package/console/dist/server/routes/approvals.js +2 -2
  24. package/console/dist/server/routes/failed-tasks.d.ts +9 -0
  25. package/console/dist/server/routes/failed-tasks.js +116 -7
  26. package/console/dist/server/routes/principles.js +73 -1
  27. package/console/dist/shared/prompt-injection-contract.d.ts +1 -1
  28. package/console/dist/ui/api.d.ts +5 -5
  29. package/console/dist/ui/i18n/en.json +13 -2
  30. package/console/dist/ui/i18n/zh-CN.json +13 -2
  31. package/console/dist/ui/pages/activation/ActivationPage.js +2 -1
  32. package/console/dist/ui/pages/failed-tasks/FailedTasksPage.js +42 -4
  33. package/console/dist/ui/pages/focus/FocusPage.js +3 -3
  34. package/console/dist/ui/pages/principles/PrinciplesPage.js +7 -2
  35. package/console/dist/ui/utils/validators.d.ts +6 -2
  36. package/console/dist/ui/utils/validators.js +19 -4
  37. package/console/dist/web/assets/app.css +26 -0
  38. package/console/dist/web/assets/app.js +24 -24
  39. package/console/package.json +6 -5
  40. package/core/dist/host/host-installer.d.ts +3 -1
  41. package/core/dist/host/host-installer.d.ts.map +1 -1
  42. package/core/dist/host/host-installer.js.map +1 -1
  43. package/core/dist/runtime-v2/admission-gate.d.ts +8 -0
  44. package/core/dist/runtime-v2/admission-gate.d.ts.map +1 -1
  45. package/core/dist/runtime-v2/admission-gate.js +3 -2
  46. package/core/dist/runtime-v2/admission-gate.js.map +1 -1
  47. package/core/dist/runtime-v2/config/pd-config-defaults.d.ts.map +1 -1
  48. package/core/dist/runtime-v2/config/pd-config-defaults.js +16 -1
  49. package/core/dist/runtime-v2/config/pd-config-defaults.js.map +1 -1
  50. package/core/dist/runtime-v2/context-payload.d.ts +43 -3
  51. package/core/dist/runtime-v2/context-payload.d.ts.map +1 -1
  52. package/core/dist/runtime-v2/context-payload.js +15 -1
  53. package/core/dist/runtime-v2/context-payload.js.map +1 -1
  54. package/core/dist/runtime-v2/evidence-guards.d.ts +6 -0
  55. package/core/dist/runtime-v2/evidence-guards.d.ts.map +1 -1
  56. package/core/dist/runtime-v2/evidence-guards.js +11 -0
  57. package/core/dist/runtime-v2/evidence-guards.js.map +1 -1
  58. package/core/dist/runtime-v2/evolution/evolution-types.d.ts +4 -4
  59. package/core/dist/runtime-v2/evolution/evolution-types.d.ts.map +1 -1
  60. package/core/dist/runtime-v2/evolution/evolution-types.js +1 -1
  61. package/core/dist/runtime-v2/evolution/evolution-types.js.map +1 -1
  62. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
  63. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js +6 -0
  64. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
  65. package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.d.ts.map +1 -1
  66. package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.js +8 -0
  67. package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.js.map +1 -1
  68. package/core/dist/runtime-v2/index.d.ts +5 -2
  69. package/core/dist/runtime-v2/index.d.ts.map +1 -1
  70. package/core/dist/runtime-v2/index.js +3 -1
  71. package/core/dist/runtime-v2/index.js.map +1 -1
  72. package/core/dist/runtime-v2/internalization/evaluator-output.d.ts +11 -0
  73. package/core/dist/runtime-v2/internalization/evaluator-output.d.ts.map +1 -1
  74. package/core/dist/runtime-v2/internalization/evaluator-output.js +10 -0
  75. package/core/dist/runtime-v2/internalization/evaluator-output.js.map +1 -1
  76. package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.d.ts +3 -3
  77. package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.d.ts.map +1 -1
  78. package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.js +49 -5
  79. package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.js.map +1 -1
  80. package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts.map +1 -1
  81. package/core/dist/runtime-v2/internalization/evaluator-runner.js +13 -16
  82. package/core/dist/runtime-v2/internalization/evaluator-runner.js.map +1 -1
  83. package/core/dist/runtime-v2/internalization/owner-decision-review.d.ts.map +1 -1
  84. package/core/dist/runtime-v2/internalization/owner-decision-review.js +5 -1
  85. package/core/dist/runtime-v2/internalization/owner-decision-review.js.map +1 -1
  86. package/core/dist/runtime-v2/internalization/owner-review.d.ts +2 -2
  87. package/core/dist/runtime-v2/internalization/owner-review.js +2 -2
  88. package/core/dist/runtime-v2/internalization/scribe-output.d.ts +12 -0
  89. package/core/dist/runtime-v2/internalization/scribe-output.d.ts.map +1 -1
  90. package/core/dist/runtime-v2/internalization/scribe-output.js +20 -0
  91. package/core/dist/runtime-v2/internalization/scribe-output.js.map +1 -1
  92. package/core/dist/runtime-v2/internalization/scribe-prompt-builder.d.ts +32 -1
  93. package/core/dist/runtime-v2/internalization/scribe-prompt-builder.d.ts.map +1 -1
  94. package/core/dist/runtime-v2/internalization/scribe-prompt-builder.js +38 -1
  95. package/core/dist/runtime-v2/internalization/scribe-prompt-builder.js.map +1 -1
  96. package/core/dist/runtime-v2/internalization-queue-read-model.d.ts +6 -0
  97. package/core/dist/runtime-v2/internalization-queue-read-model.d.ts.map +1 -1
  98. package/core/dist/runtime-v2/internalization-queue-read-model.js +8 -1
  99. package/core/dist/runtime-v2/internalization-queue-read-model.js.map +1 -1
  100. package/core/dist/runtime-v2/intervention-evidence-normalizer.d.ts.map +1 -1
  101. package/core/dist/runtime-v2/intervention-evidence-normalizer.js +10 -3
  102. package/core/dist/runtime-v2/intervention-evidence-normalizer.js.map +1 -1
  103. package/core/dist/runtime-v2/pain-ingress.d.ts +1 -1
  104. package/core/dist/runtime-v2/pain-ingress.d.ts.map +1 -1
  105. package/core/dist/runtime-v2/pain-signal-bridge.d.ts +68 -2
  106. package/core/dist/runtime-v2/pain-signal-bridge.d.ts.map +1 -1
  107. package/core/dist/runtime-v2/pain-signal-bridge.js +541 -18
  108. package/core/dist/runtime-v2/pain-signal-bridge.js.map +1 -1
  109. package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts.map +1 -1
  110. package/core/dist/runtime-v2/pain-signal-runtime-factory.js +4 -0
  111. package/core/dist/runtime-v2/pain-signal-runtime-factory.js.map +1 -1
  112. package/core/dist/runtime-v2/product-telemetry/snapshot-contract.d.ts +2 -2
  113. package/core/dist/runtime-v2/product-telemetry/snapshot-contract.d.ts.map +1 -1
  114. package/core/dist/runtime-v2/product-telemetry/snapshot-contract.js +2 -2
  115. package/core/dist/runtime-v2/product-telemetry/snapshot-contract.js.map +1 -1
  116. package/core/dist/runtime-v2/store/candidate/admission-document.d.ts +90 -0
  117. package/core/dist/runtime-v2/store/candidate/admission-document.d.ts.map +1 -0
  118. package/core/dist/runtime-v2/store/candidate/admission-document.js +142 -0
  119. package/core/dist/runtime-v2/store/candidate/admission-document.js.map +1 -0
  120. package/core/dist/runtime-v2/store/candidate/candidate-store.d.ts +53 -0
  121. package/core/dist/runtime-v2/store/candidate/candidate-store.d.ts.map +1 -1
  122. package/core/dist/runtime-v2/store/candidate/memory-candidate-store.d.ts +35 -0
  123. package/core/dist/runtime-v2/store/candidate/memory-candidate-store.d.ts.map +1 -1
  124. package/core/dist/runtime-v2/store/candidate/memory-candidate-store.js +48 -0
  125. package/core/dist/runtime-v2/store/candidate/memory-candidate-store.js.map +1 -1
  126. package/core/dist/runtime-v2/store/candidate/sqlite-candidate-store.d.ts +44 -0
  127. package/core/dist/runtime-v2/store/candidate/sqlite-candidate-store.d.ts.map +1 -1
  128. package/core/dist/runtime-v2/store/candidate/sqlite-candidate-store.js +136 -0
  129. package/core/dist/runtime-v2/store/candidate/sqlite-candidate-store.js.map +1 -1
  130. package/core/dist/runtime-v2/store/context/sqlite-context-assembler.js.map +1 -1
  131. package/core/dist/runtime-v2/store/intervention-evidence-schema.js +1 -1
  132. package/core/dist/runtime-v2/store/runtime-state-manager.d.ts +65 -0
  133. package/core/dist/runtime-v2/store/runtime-state-manager.d.ts.map +1 -1
  134. package/core/dist/runtime-v2/store/runtime-state-manager.js +46 -0
  135. package/core/dist/runtime-v2/store/runtime-state-manager.js.map +1 -1
  136. package/core/dist/runtime-v2/store/sqlite-connection.d.ts.map +1 -1
  137. package/core/dist/runtime-v2/store/sqlite-connection.js +42 -0
  138. package/core/dist/runtime-v2/store/sqlite-connection.js.map +1 -1
  139. package/core/dist/runtime-v2/store/sqlite-intervention-evidence-store.d.ts +1 -1
  140. package/core/dist/runtime-v2/store/sqlite-intervention-evidence-store.d.ts.map +1 -1
  141. package/core/dist/runtime-v2/store/sqlite-intervention-evidence-store.js.map +1 -1
  142. package/core/dist/runtime-v2/store/task/sqlite-family-reopen.d.ts +19 -0
  143. package/core/dist/runtime-v2/store/task/sqlite-family-reopen.d.ts.map +1 -0
  144. package/core/dist/runtime-v2/store/task/sqlite-family-reopen.js +36 -0
  145. package/core/dist/runtime-v2/store/task/sqlite-family-reopen.js.map +1 -0
  146. package/core/dist/runtime-v2/store/task/sqlite-task-store.d.ts +23 -0
  147. package/core/dist/runtime-v2/store/task/sqlite-task-store.d.ts.map +1 -1
  148. package/core/dist/runtime-v2/store/task/sqlite-task-store.js +50 -0
  149. package/core/dist/runtime-v2/store/task/sqlite-task-store.js.map +1 -1
  150. package/core/dist/runtime-v2/task-status.d.ts +3 -1
  151. package/core/dist/runtime-v2/task-status.d.ts.map +1 -1
  152. package/core/dist/runtime-v2/task-status.js +1 -1
  153. package/core/dist/runtime-v2/task-status.js.map +1 -1
  154. package/core/dist/runtime-v2/trajectory-schema.d.ts.map +1 -1
  155. package/core/dist/runtime-v2/trajectory-schema.js +11 -0
  156. package/core/dist/runtime-v2/trajectory-schema.js.map +1 -1
  157. package/core/dist/runtime-v2/types/event-types.d.ts +2 -2
  158. package/core/dist/runtime-v2/types/event-types.d.ts.map +1 -1
  159. package/core/dist/runtime-v2/types/event-types.js +1 -1
  160. package/core/dist/runtime-v2/types/event-types.js.map +1 -1
  161. package/core/dist/runtime-v2/types/evidence-chain-contract.d.ts +1 -1
  162. package/core/dist/runtime-v2/types/evidence-chain-contract.d.ts.map +1 -1
  163. package/core/dist/runtime-v2/types/evidence-chain-contract.js +2 -2
  164. package/core/dist/runtime-v2/types/evidence-chain-contract.js.map +1 -1
  165. package/core/dist/runtime-v2/types/intervention-evidence-contract.d.ts +3 -3
  166. package/core/dist/runtime-v2/types/intervention-evidence-contract.d.ts.map +1 -1
  167. package/core/dist/runtime-v2/types/intervention-evidence-contract.js +1 -0
  168. package/core/dist/runtime-v2/types/intervention-evidence-contract.js.map +1 -1
  169. package/core/dist/telemetry-event.d.ts +2 -2
  170. package/core/dist/telemetry-event.d.ts.map +1 -1
  171. package/core/dist/telemetry-event.js +4 -0
  172. package/core/dist/telemetry-event.js.map +1 -1
  173. package/core/dist/trajectory-types.d.ts +2 -2
  174. package/core/dist/trajectory-types.d.ts.map +1 -1
  175. package/core/package.json +7 -5
  176. package/dist/index.d.ts.map +1 -1
  177. package/dist/index.js +84 -8
  178. package/dist/index.js.map +1 -1
  179. package/dist/installer.d.ts +42 -11
  180. package/dist/installer.d.ts.map +1 -1
  181. package/dist/installer.js +140 -36
  182. package/dist/installer.js.map +1 -1
  183. package/dist/installers/index.d.ts +18 -7
  184. package/dist/installers/index.d.ts.map +1 -1
  185. package/dist/installers/index.js +13 -4
  186. package/dist/installers/index.js.map +1 -1
  187. package/dist/installers/workbuddy-host-installer.d.ts +246 -0
  188. package/dist/installers/workbuddy-host-installer.d.ts.map +1 -0
  189. package/dist/installers/workbuddy-host-installer.js +1419 -0
  190. package/dist/installers/workbuddy-host-installer.js.map +1 -0
  191. package/dist/mvp-config.d.ts +24 -0
  192. package/dist/mvp-config.d.ts.map +1 -1
  193. package/dist/mvp-config.js +36 -0
  194. package/dist/mvp-config.js.map +1 -1
  195. package/dist/prompts.d.ts +13 -0
  196. package/dist/prompts.d.ts.map +1 -1
  197. package/dist/prompts.js +45 -8
  198. package/dist/prompts.js.map +1 -1
  199. package/dist/uninstaller.d.ts +1 -1
  200. package/dist/uninstaller.d.ts.map +1 -1
  201. package/dist/uninstaller.js +29 -4
  202. package/dist/uninstaller.js.map +1 -1
  203. package/host-runtime/dist/governance-signal-admission.d.ts +63 -0
  204. package/host-runtime/dist/governance-signal-admission.js +322 -53
  205. package/host-runtime/dist/host-liveness-contract.js +7 -1
  206. package/host-runtime/dist/index.d.ts +1 -0
  207. package/host-runtime/dist/index.js +5 -1
  208. package/host-runtime/dist/internalization-consumer-cycle.d.ts +12 -0
  209. package/host-runtime/dist/internalization-consumer-cycle.js +43 -1
  210. package/host-runtime/dist/intervention-evidence-ingress.d.ts +1 -1
  211. package/host-runtime/dist/product-telemetry/service.js +1 -1
  212. package/host-runtime/dist/production-pain-evidence.d.ts +59 -1
  213. package/host-runtime/dist/production-pain-evidence.js +200 -17
  214. package/host-runtime/dist/prompt-activation-deliverability.js +5 -4
  215. package/host-runtime/dist/prompt-injection-event-evidence.d.ts +1 -1
  216. package/host-runtime/dist/prompt-injection-event-evidence.js +5 -1
  217. package/host-runtime/dist/prompt-injection-projection.d.ts +14 -5
  218. package/host-runtime/dist/prompt-injection-projection.js +30 -16
  219. package/host-runtime/dist/workbuddy-worker-status.d.ts +24 -0
  220. package/host-runtime/dist/workbuddy-worker-status.js +52 -0
  221. package/host-runtime/package.json +7 -5
  222. package/install-layout/dist/index.d.ts +18 -1
  223. package/install-layout/dist/index.js +15 -2
  224. package/install-layout/package.json +5 -3
  225. package/package.json +9 -7
  226. package/pd-cli/dist/commands/candidate.d.ts.map +1 -1
  227. package/pd-cli/dist/commands/candidate.js +44 -4
  228. package/pd-cli/dist/commands/candidate.js.map +1 -1
  229. package/pd-cli/dist/commands/codex-worker.d.ts.map +1 -1
  230. package/pd-cli/dist/commands/codex-worker.js +30 -1
  231. package/pd-cli/dist/commands/codex-worker.js.map +1 -1
  232. package/pd-cli/dist/commands/config-doctor.d.ts.map +1 -1
  233. package/pd-cli/dist/commands/config-doctor.js +19 -4
  234. package/pd-cli/dist/commands/config-doctor.js.map +1 -1
  235. package/pd-cli/dist/commands/diagnose.d.ts.map +1 -1
  236. package/pd-cli/dist/commands/diagnose.js +4 -1
  237. package/pd-cli/dist/commands/diagnose.js.map +1 -1
  238. package/pd-cli/dist/commands/health-codex-install.d.ts +85 -0
  239. package/pd-cli/dist/commands/health-codex-install.d.ts.map +1 -0
  240. package/pd-cli/dist/commands/health-codex-install.js +207 -0
  241. package/pd-cli/dist/commands/health-codex-install.js.map +1 -0
  242. package/pd-cli/dist/commands/health-codex.d.ts.map +1 -1
  243. package/pd-cli/dist/commands/health-codex.js +78 -0
  244. package/pd-cli/dist/commands/health-codex.js.map +1 -1
  245. package/pd-cli/dist/commands/pain-list.d.ts +3 -2
  246. package/pd-cli/dist/commands/pain-list.d.ts.map +1 -1
  247. package/pd-cli/dist/commands/pain-list.js +10 -10
  248. package/pd-cli/dist/commands/pain-list.js.map +1 -1
  249. package/pd-cli/dist/commands/pain-record.d.ts +2 -0
  250. package/pd-cli/dist/commands/pain-record.d.ts.map +1 -1
  251. package/pd-cli/dist/commands/pain-record.js +36 -0
  252. package/pd-cli/dist/commands/pain-record.js.map +1 -1
  253. package/pd-cli/dist/commands/pain-retry.d.ts +6 -0
  254. package/pd-cli/dist/commands/pain-retry.d.ts.map +1 -1
  255. package/pd-cli/dist/commands/pain-retry.js +152 -5
  256. package/pd-cli/dist/commands/pain-retry.js.map +1 -1
  257. package/pd-cli/dist/commands/runtime-activation.d.ts +1 -1
  258. package/pd-cli/dist/commands/runtime-activation.d.ts.map +1 -1
  259. package/pd-cli/dist/commands/runtime-activation.js +3 -3
  260. package/pd-cli/dist/commands/runtime-activation.js.map +1 -1
  261. package/pd-cli/dist/commands/workbuddy-worker.d.ts +19 -0
  262. package/pd-cli/dist/commands/workbuddy-worker.d.ts.map +1 -0
  263. package/pd-cli/dist/commands/workbuddy-worker.js +168 -0
  264. package/pd-cli/dist/commands/workbuddy-worker.js.map +1 -0
  265. package/pd-cli/dist/index.js +29 -1
  266. package/pd-cli/dist/index.js.map +1 -1
  267. package/pd-cli/dist/resolve-workspace.d.ts +14 -2
  268. package/pd-cli/dist/resolve-workspace.d.ts.map +1 -1
  269. package/pd-cli/dist/resolve-workspace.js +88 -21
  270. package/pd-cli/dist/resolve-workspace.js.map +1 -1
  271. package/pd-cli/dist/services/admission-write-gate.d.ts +24 -0
  272. package/pd-cli/dist/services/admission-write-gate.d.ts.map +1 -0
  273. package/pd-cli/dist/services/admission-write-gate.js +41 -0
  274. package/pd-cli/dist/services/admission-write-gate.js.map +1 -0
  275. package/pd-cli/dist/services/pd-config-loader.d.ts +39 -7
  276. package/pd-cli/dist/services/pd-config-loader.d.ts.map +1 -1
  277. package/pd-cli/dist/services/pd-config-loader.js +111 -18
  278. package/pd-cli/dist/services/pd-config-loader.js.map +1 -1
  279. package/pd-cli/dist/services/rulehost-pipeline-runner.d.ts +10 -0
  280. package/pd-cli/dist/services/rulehost-pipeline-runner.d.ts.map +1 -1
  281. package/pd-cli/dist/services/rulehost-pipeline-runner.js +59 -4
  282. package/pd-cli/dist/services/rulehost-pipeline-runner.js.map +1 -1
  283. package/pd-cli/package.json +8 -5
  284. package/plugin/dist/bundle.js +564 -509
  285. package/plugin/dist/governance-audit.js +1 -1
  286. package/plugin/dist/openclaw.plugin.json +1 -1
  287. package/plugin/dist/rulehost-evidence.js +1 -1
  288. package/plugin/openclaw.plugin.json +1 -1
  289. package/plugin/package.json +7 -5
  290. package/release-manager/dist/index.d.ts.map +1 -1
  291. package/release-manager/dist/index.js +84 -8
  292. package/release-manager/dist/index.js.map +1 -1
  293. package/release-manager/dist/installer.d.ts +42 -11
  294. package/release-manager/dist/installer.d.ts.map +1 -1
  295. package/release-manager/dist/installer.js +140 -36
  296. package/release-manager/dist/installer.js.map +1 -1
  297. package/release-manager/dist/installers/index.d.ts +18 -7
  298. package/release-manager/dist/installers/index.d.ts.map +1 -1
  299. package/release-manager/dist/installers/index.js +13 -4
  300. package/release-manager/dist/installers/index.js.map +1 -1
  301. package/release-manager/dist/installers/workbuddy-host-installer.d.ts +246 -0
  302. package/release-manager/dist/installers/workbuddy-host-installer.d.ts.map +1 -0
  303. package/release-manager/dist/installers/workbuddy-host-installer.js +1419 -0
  304. package/release-manager/dist/installers/workbuddy-host-installer.js.map +1 -0
  305. package/release-manager/dist/mvp-config.d.ts +24 -0
  306. package/release-manager/dist/mvp-config.d.ts.map +1 -1
  307. package/release-manager/dist/mvp-config.js +36 -0
  308. package/release-manager/dist/mvp-config.js.map +1 -1
  309. package/release-manager/dist/prompts.d.ts +13 -0
  310. package/release-manager/dist/prompts.d.ts.map +1 -1
  311. package/release-manager/dist/prompts.js +45 -8
  312. package/release-manager/dist/prompts.js.map +1 -1
  313. package/release-manager/dist/uninstaller.d.ts +1 -1
  314. package/release-manager/dist/uninstaller.d.ts.map +1 -1
  315. package/release-manager/dist/uninstaller.js +29 -4
  316. package/release-manager/dist/uninstaller.js.map +1 -1
  317. package/release-manager/package.json +8 -6
  318. package/workbuddy-adapter/dist/codec/index.d.ts +2 -0
  319. package/workbuddy-adapter/dist/codec/index.js +2 -0
  320. package/workbuddy-adapter/dist/codec/input-decoder.d.ts +30 -0
  321. package/workbuddy-adapter/dist/codec/input-decoder.js +232 -0
  322. package/workbuddy-adapter/dist/codec/output-encoder.d.ts +62 -0
  323. package/workbuddy-adapter/dist/codec/output-encoder.js +75 -0
  324. package/workbuddy-adapter/dist/host-adapter.d.ts +33 -0
  325. package/workbuddy-adapter/dist/host-adapter.js +23 -0
  326. package/workbuddy-adapter/dist/index.d.ts +16 -0
  327. package/workbuddy-adapter/dist/index.js +16 -0
  328. package/workbuddy-adapter/dist/pd-hook.d.ts +17 -0
  329. package/workbuddy-adapter/dist/pd-hook.js +505 -0
  330. package/workbuddy-adapter/dist/tool-semantics.d.ts +22 -0
  331. package/workbuddy-adapter/dist/tool-semantics.js +33 -0
  332. package/workbuddy-adapter/dist/workbuddy-evidence-recorder.d.ts +50 -0
  333. package/workbuddy-adapter/dist/workbuddy-evidence-recorder.js +238 -0
  334. package/workbuddy-adapter/dist/worker/workspace-worker.d.ts +41 -0
  335. package/workbuddy-adapter/dist/worker/workspace-worker.js +219 -0
  336. package/workbuddy-adapter/dist/workspace-resolution.d.ts +15 -0
  337. package/workbuddy-adapter/dist/workspace-resolution.js +53 -0
  338. package/workbuddy-adapter/package.json +64 -0
  339. package/workbuddy-adapter/plugin/.codebuddy-plugin/plugin.json +6 -0
  340. package/workbuddy-adapter/plugin/hooks/hooks.json +62 -0
  341. package/workbuddy-adapter/plugin/scripts/wrapper.cjs +79 -0
  342. package/console/dist/ui/utils/navigation.d.ts +0 -9
  343. package/console/dist/ui/utils/navigation.js +0 -7
  344. package/core/dist/runtime-v2/internalization/dimension-coverage-policy.d.ts +0 -54
  345. package/core/dist/runtime-v2/internalization/dimension-coverage-policy.d.ts.map +0 -1
  346. package/core/dist/runtime-v2/internalization/dimension-coverage-policy.js +0 -70
  347. package/core/dist/runtime-v2/internalization/dimension-coverage-policy.js.map +0 -1
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @principles/workbuddy-adapter — the WorkBuddy host adapter for Principles
3
+ * Disciple (ADR-0020 third host, SPEC workbuddy-host-adapter v0.3.0).
4
+ *
5
+ * Public surface mirrors the codex-adapter layout: the HostAdapter
6
+ * implementation, the codec, the governance-workspace resolution, the tool
7
+ * semantic declaration, and the evidence recorder. The process entry lives
8
+ * at ./pd-hook (spawned per hook event by plugin/scripts/wrapper.cjs).
9
+ */
10
+ export { WorkBuddyHooksHostAdapter } from './host-adapter.js';
11
+ export { decodeWorkbuddyInput, normalizeWorkbuddyToolResponse, encodeWorkbuddyOutput, workbuddyOutputFieldsAreWhitelisted, WorkBuddyDecoderError, WorkBuddyEncoderError, WORKBUDDY_EVENT_PRE_TOOL_USE, WORKBUDDY_EVENT_POST_TOOL_USE, WORKBUDDY_EVENT_POST_TOOL_USE_FAILURE, WORKBUDDY_EVENT_USER_PROMPT_SUBMIT, WORKBUDDY_EVENT_SESSION_START, type WorkBuddyHookOutput, } from './codec/index.js';
12
+ export { resolveWorkbuddyWorkspace, type WorkbuddyWorkspaceResolution, } from './workspace-resolution.js';
13
+ export { WORKBUDDY_TOOL_SEMANTICS, WORKBUDDY_TOOL_SEMANTIC_MAPPINGS, } from './tool-semantics.js';
14
+ export { recordWorkbuddyPromptDeliveryEvidence, recordWorkbuddyDenyEvidence, workbuddyCapabilityDeclarations, WORKBUDDY_EVIDENCE_ADAPTER_VERSION, } from './workbuddy-evidence-recorder.js';
15
+ export { processWorkbuddyHookInvocation, annotateContextWarnings, type WorkBuddyPdHookResult, } from './pd-hook.js';
16
+ export { runWorkbuddyWorkspaceWorkerCycle, type WorkbuddyWorkerCycleResult, type WorkbuddyWorkerCycleOptions, type WorkbuddyWorkerCycleStepReport, type WorkbuddyWorkerMode, } from './worker/workspace-worker.js';
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @principles/workbuddy-adapter — the WorkBuddy host adapter for Principles
3
+ * Disciple (ADR-0020 third host, SPEC workbuddy-host-adapter v0.3.0).
4
+ *
5
+ * Public surface mirrors the codex-adapter layout: the HostAdapter
6
+ * implementation, the codec, the governance-workspace resolution, the tool
7
+ * semantic declaration, and the evidence recorder. The process entry lives
8
+ * at ./pd-hook (spawned per hook event by plugin/scripts/wrapper.cjs).
9
+ */
10
+ export { WorkBuddyHooksHostAdapter } from './host-adapter.js';
11
+ export { decodeWorkbuddyInput, normalizeWorkbuddyToolResponse, encodeWorkbuddyOutput, workbuddyOutputFieldsAreWhitelisted, WorkBuddyDecoderError, WorkBuddyEncoderError, WORKBUDDY_EVENT_PRE_TOOL_USE, WORKBUDDY_EVENT_POST_TOOL_USE, WORKBUDDY_EVENT_POST_TOOL_USE_FAILURE, WORKBUDDY_EVENT_USER_PROMPT_SUBMIT, WORKBUDDY_EVENT_SESSION_START, } from './codec/index.js';
12
+ export { resolveWorkbuddyWorkspace, } from './workspace-resolution.js';
13
+ export { WORKBUDDY_TOOL_SEMANTICS, WORKBUDDY_TOOL_SEMANTIC_MAPPINGS, } from './tool-semantics.js';
14
+ export { recordWorkbuddyPromptDeliveryEvidence, recordWorkbuddyDenyEvidence, workbuddyCapabilityDeclarations, WORKBUDDY_EVIDENCE_ADAPTER_VERSION, } from './workbuddy-evidence-recorder.js';
15
+ export { processWorkbuddyHookInvocation, annotateContextWarnings, } from './pd-hook.js';
16
+ export { runWorkbuddyWorkspaceWorkerCycle, } from './worker/workspace-worker.js';
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ import { type WorkBuddyHookOutput } from './codec/index.js';
3
+ type EnvMap = Record<string, string | undefined>;
4
+ export interface WorkBuddyPdHookResult {
5
+ stdout: WorkBuddyHookOutput | null;
6
+ exitCode: number;
7
+ stderr: string[];
8
+ }
9
+ /** Evidence context the emitters need (subprocess-local, best-effort). */
10
+ export interface WorkbuddyEvidenceContext {
11
+ workspaceDir: string;
12
+ evidenceEnabled: boolean;
13
+ warn: (diagnosticLine: string) => void;
14
+ }
15
+ export declare function annotateContextWarnings(warnings: readonly string[]): string[];
16
+ export declare function processWorkbuddyHookInvocation(rawStdin: string, channelEventName: string | undefined, _env?: EnvMap): Promise<WorkBuddyPdHookResult>;
17
+ export {};
@@ -0,0 +1,505 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * WorkBuddy pd-hook — the process entry WorkBuddy invokes per hook event
4
+ * (through plugin/scripts/wrapper.cjs, which forwards stdin/stdout/exit code).
5
+ *
6
+ * FAILURE POLICY (SPEC §4.4 / OD-01, frozen by Phase 0 probe P02):
7
+ * WorkBuddy exit codes have PER-EVENT effects, so unlike the Codex belt
8
+ * ("always exit 0") the channel matters:
9
+ *
10
+ * flag-off / uninitialized / degraded workspace
11
+ * → EMPTY stdout + exit 0 + observable stderr skip/degrade record
12
+ * (rc-9; never escalated to blocking — the Owner has not opted in);
13
+ * PreToolUse INSIDE the supported governance path whose decode/dispatch/
14
+ * encode/serialization fails
15
+ * → exit 2 + bounded stderr + EMPTY stdout (P02 verified exit 2 blocks
16
+ * the tool even when stdout is closed);
17
+ * UserPromptSubmit ANY failure
18
+ * → EMPTY stdout + exit 0 + degraded stderr (P02: exit 2 would CLEAR the
19
+ * user's prompt — protecting the prompt outranks reporting);
20
+ * PostToolUse ANY failure
21
+ * → EMPTY stdout + exit 0 + evidence-degradation stderr (the tool already
22
+ * ran; nothing can be blocked, so blocking language is never used);
23
+ * SessionStart ANY failure
24
+ * → EMPTY stdout + exit 0 + status stderr (non-blocking for the session).
25
+ *
26
+ * An ALREADY-COMPUTED deny always survives evidence-write failure (encode
27
+ * first, record evidence after — P02: deny is the real blocking signal).
28
+ *
29
+ * OUTPUT: stdout carries AT MOST ONE JSON document (the whitelisted
30
+ * hookSpecificOutput) and ONLY when there is something whitelisted to say —
31
+ * the host injects any raw stdout text into model-visible context (P04), so
32
+ * neutral means EMPTY stdout, never `{}`. Diagnostics go to stderr only.
33
+ */
34
+ import { readFileSync, realpathSync } from 'node:fs';
35
+ import os from 'node:os';
36
+ import path from 'node:path';
37
+ import process from 'node:process';
38
+ import { pathToFileURL, fileURLToPath } from 'node:url';
39
+ import { appendEventLogLine, redactTelemetryString, isRuleHostEvaluatedEventData } from '@principles/core/runtime-v2';
40
+ import { createProductionHostRuntime, loadPdConfigForPlugin } from '@principles/host-runtime';
41
+ import { computeFeatureFlagsFromConfig } from '@principles/core/runtime-v2';
42
+ import { WorkBuddyHooksHostAdapter } from './host-adapter.js';
43
+ import { WORKBUDDY_TOOL_SEMANTICS } from './tool-semantics.js';
44
+ import { resolveWorkbuddyWorkspace } from './workspace-resolution.js';
45
+ import { WorkBuddyDecoderError, WorkBuddyEncoderError, isWorkBuddyHookOutput, WORKBUDDY_EVENT_PRE_TOOL_USE } from './codec/index.js';
46
+ import { recordWorkbuddyPromptDeliveryEvidence, recordWorkbuddyDenyEvidence } from './workbuddy-evidence-recorder.js';
47
+ const MAX_DIAGNOSTIC = 500;
48
+ function bound(text) {
49
+ return text.replace(/\s+/g, ' ').trim().slice(0, MAX_DIAGNOSTIC);
50
+ }
51
+ /** rc-8/rc-9: bounded, single-line, machine-greppable diagnostic on stderr. */
52
+ function diagnostic(status, reason, nextAction) {
53
+ return `[PD] status=${status} reason=${bound(reason)} nextAction=${bound(nextAction)}`;
54
+ }
55
+ function errorMessage(error) {
56
+ return error instanceof Error ? error.message.slice(0, MAX_DIAGNOSTIC) : 'unknown_error';
57
+ }
58
+ function redactStringFields(data) {
59
+ // rc-8: telemetry redacted field by field (same policy as the Codex emitter).
60
+ const redacted = {};
61
+ for (const [key, value] of Object.entries(data)) {
62
+ redacted[key] = typeof value === 'string' ? redactTelemetryString(value) : value;
63
+ }
64
+ return redacted;
65
+ }
66
+ /**
67
+ * Event emitter for the WorkBuddy subprocess: writes the same
68
+ * `events_<date>.jsonl` line shape as the Codex/OpenClaw paths through the
69
+ * core writer, so the WorkBuddy host path carries the host's natural ids
70
+ * (generation_id → runId/turnId, call_id → toolCallId).
71
+ */
72
+ function workbuddyEventEmitter(stateDir, evidence) {
73
+ return {
74
+ recordRuntimeV2ActivationsInjected(data) {
75
+ appendEventLogLine(stateDir, {
76
+ ts: new Date().toISOString(),
77
+ type: 'runtime_v2_prompt_activations_injected',
78
+ category: 'injected',
79
+ sessionId: data.sessionId,
80
+ data,
81
+ });
82
+ // Delivery evidence AFTER the durable source line exists; degrades to a
83
+ // bounded diagnostic and never affects the hook result.
84
+ if (evidence) {
85
+ try {
86
+ const injected = data.principleIds
87
+ .map((principleId, index) => ({
88
+ principleId,
89
+ activationId: data.activationIds[index] ?? '',
90
+ artifactId: data.artifactIds[index],
91
+ }))
92
+ .filter((entry) => entry.activationId.length > 0);
93
+ recordWorkbuddyPromptDeliveryEvidence({
94
+ workspaceDir: evidence.workspaceDir,
95
+ sessionId: data.sessionId,
96
+ ...(data.runId ? { turnId: data.runId } : {}),
97
+ injected,
98
+ evidenceEnabled: evidence.evidenceEnabled,
99
+ warn: evidence.warn,
100
+ });
101
+ }
102
+ catch (error) {
103
+ evidence.warn(diagnostic('degraded', `workbuddy_evidence_delivery_failed:${errorMessage(error)}`, 'The raw injected event is durable; replay is safe. The hook result is unaffected.'));
104
+ }
105
+ }
106
+ },
107
+ recordToolCall(sessionId, data) {
108
+ appendEventLogLine(stateDir, {
109
+ ts: new Date().toISOString(),
110
+ type: 'tool_call',
111
+ category: data.error || (data.exitCode !== undefined && data.exitCode !== 0) ? 'failure' : 'success',
112
+ sessionId,
113
+ data: redactStringFields(data),
114
+ });
115
+ },
116
+ };
117
+ }
118
+ /**
119
+ * Persist the shared gate's per-activation evaluation facts
120
+ * (metadata.evaluations — shadow observations plus the live aggregate) as
121
+ * canonical `rulehost_evaluated` events (PRI-813 pattern). One bounded
122
+ * diagnostic per failure CLASS; never throws into the caller's fail-open /
123
+ * fail-closed handling.
124
+ */
125
+ function recordRuleHostEvaluations(stateDir, sessionId, evaluations) {
126
+ if (!Array.isArray(evaluations))
127
+ return [];
128
+ const diagnostics = [];
129
+ let sawInvalidEntry = false;
130
+ let sawPersistFailure = false;
131
+ for (const entry of evaluations) {
132
+ if (!isRuleHostEvaluatedEventData(entry)) {
133
+ // rc-9: a skipped evidence row must be observable, never silent.
134
+ if (!sawInvalidEntry) {
135
+ sawInvalidEntry = true;
136
+ diagnostics.push(diagnostic('degraded', 'rulehost_evaluation_entry_invalid', 'Inspect host-runtime gate metadata contract; the evaluation event was not persisted.'));
137
+ }
138
+ continue;
139
+ }
140
+ try {
141
+ appendEventLogLine(stateDir, {
142
+ ts: new Date().toISOString(),
143
+ type: 'rulehost_evaluated',
144
+ category: 'evaluated',
145
+ sessionId,
146
+ data: redactStringFields(entry),
147
+ });
148
+ }
149
+ catch (error) {
150
+ if (!sawPersistFailure) {
151
+ sawPersistFailure = true;
152
+ diagnostics.push(diagnostic('degraded', `rulehost_evaluation_persist_failed:${errorMessage(error)}`, 'Inspect workspace .state/logs writability; the evaluation event was not persisted, the tool decision is unaffected.'));
153
+ }
154
+ }
155
+ }
156
+ return diagnostics;
157
+ }
158
+ /**
159
+ * PRI-780 pattern (WorkBuddy boundary, same as Codex): this host supplies no
160
+ * runtime context provider, and the "unavailable → allow" contract is prompt
161
+ * discipline, NOT a runtime-enforced invariant. Handing v2 rules a truthy
162
+ * context would let a persisted rule evaluate context-blind and deny calls
163
+ * that were previously suspended — a silent governance change. The gate skips
164
+ * v2 rules with its structured `rule_context_v2_unavailable` warning and this
165
+ * hook annotates the warning with the explicit host-unsupported reason before
166
+ * it reaches stderr (明确 unsupported, never a silent skip).
167
+ */
168
+ const WORKBUDDY_CONTEXT_UNSUPPORTED_NOTE = 'workbuddy_runtime_context_unsupported: the WorkBuddy host provides no runtime context provider; v2 rules stay suspended on this host';
169
+ export function annotateContextWarnings(warnings) {
170
+ return warnings.map((warning) => warning.startsWith('rule_context_v2_unavailable')
171
+ ? `${warning}; ${WORKBUDDY_CONTEXT_UNSUPPORTED_NOTE}`
172
+ : warning);
173
+ }
174
+ /** The wrapper's event argument names the registration context; only a
175
+ * PreToolUse registration channel may escalate a failure to a blocking exit 2. */
176
+ function channelBlocksOnFailure(channelEventName) {
177
+ return channelEventName === WORKBUDDY_EVENT_PRE_TOOL_USE;
178
+ }
179
+ function neutralWithDiagnostics(stderr) {
180
+ return { stdout: null, exitCode: 0, stderr };
181
+ }
182
+ /** Pre-decode failures (bad JSON / decode) route per registration channel. */
183
+ function channelFailure(channelEventName, reason, nextAction) {
184
+ const line = diagnostic('degraded', reason, nextAction);
185
+ if (channelBlocksOnFailure(channelEventName)) {
186
+ // P02: exit 2 blocks the tool even with an empty stdout / closed pipe.
187
+ return { stdout: null, exitCode: 2, stderr: [line] };
188
+ }
189
+ // UserPromptSubmit: exit 2 would clear the user's prompt (P02) — protect it.
190
+ // PostToolUse/SessionStart: nothing blockable exists on those channels.
191
+ return neutralWithDiagnostics([line]);
192
+ }
193
+ export async function processWorkbuddyHookInvocation(rawStdin, channelEventName, _env = process.env) {
194
+ let parsed;
195
+ try {
196
+ parsed = JSON.parse(rawStdin);
197
+ }
198
+ catch (error) {
199
+ return channelFailure(channelEventName, `stdin_json_invalid:${errorMessage(error)}`, 'Verify the WorkBuddy hook passes one JSON object on stdin.');
200
+ }
201
+ const adapter = new WorkBuddyHooksHostAdapter();
202
+ let event;
203
+ try {
204
+ event = adapter.decodeEvent(parsed);
205
+ }
206
+ catch (error) {
207
+ const reason = error instanceof WorkBuddyDecoderError ? error.reason : `decode_threw:${errorMessage(error)}`;
208
+ const nextAction = error instanceof WorkBuddyDecoderError ? error.nextAction : 'Inspect the WorkBuddy hook payload against the Phase 0 host contract.';
209
+ return channelFailure(channelEventName, reason, nextAction);
210
+ }
211
+ // OD-07/P06 governance workspace: explicit, user-level, shared across
212
+ // projects; never auto-created here and never falling back to another host.
213
+ const resolution = resolveWorkbuddyWorkspace(os.homedir());
214
+ if (resolution.status === 'uninitialized') {
215
+ return neutralWithDiagnostics([diagnostic('skipped', resolution.reason, resolution.nextAction)]);
216
+ }
217
+ if (resolution.status === 'degraded') {
218
+ return neutralWithDiagnostics([diagnostic('degraded', resolution.reason, resolution.nextAction)]);
219
+ }
220
+ const config = loadPdConfigForPlugin(resolution.workspaceDir);
221
+ if (!config.ok) {
222
+ const [first] = config.errors;
223
+ return neutralWithDiagnostics([diagnostic('degraded', first?.reason ?? 'pd_config_invalid', first?.nextAction ?? 'Repair the governance workspace .pd/config.yaml.')]);
224
+ }
225
+ const { flags } = computeFeatureFlagsFromConfig(config.effective);
226
+ if (flags['host.workbuddy']?.enabled !== true) {
227
+ // OD-03: default OFF; observable skip, no dispatch, no workspace writes.
228
+ return neutralWithDiagnostics([diagnostic('skipped', 'host.workbuddy_disabled', 'Set features.host.workbuddy.enabled=true in the WorkBuddy governance workspace config to enable PD for WorkBuddy.')]);
229
+ }
230
+ const evidenceEnabled = flags.principle_receipt_ledger?.enabled === true;
231
+ // projectDir = the host cwd (payload cwd; SessionStart carries none);
232
+ // workspaceDir = the governance directory (OD-07). The decoder placed the
233
+ // payload cwd in context.workspaceDir as the pre-rewrite carrier — capture
234
+ // it before replacing with the governance workspace.
235
+ const projectDir = event.context.workspaceDir.length > 0 ? event.context.workspaceDir : undefined;
236
+ event = { ...event, context: { ...event.context, workspaceDir: resolution.workspaceDir } };
237
+ try {
238
+ if (event.kind === 'session_start') {
239
+ // SPEC §4.2: health check only — first version injects NO body, and the
240
+ // neutral result is an EMPTY stdout (any stdout is context-injected).
241
+ const health = await createProductionHostRuntime({ hostKind: 'workbuddy' }).health(resolution.workspaceDir);
242
+ if (!health.ok)
243
+ return neutralWithDiagnostics([diagnostic('degraded', health.reason ?? 'runtime_unhealthy', health.nextAction ?? 'Inspect the governance workspace runtime.')]);
244
+ return neutralWithDiagnostics([]);
245
+ }
246
+ const evidenceDiagnostics = [];
247
+ const evidenceContext = {
248
+ workspaceDir: resolution.workspaceDir,
249
+ evidenceEnabled,
250
+ warn: (line) => evidenceDiagnostics.push(diagnostic('degraded', line.replace(/^\[PD:Evidence\] /, 'workbuddy_evidence:'), 'Inspect workspace state.db evidence ledger; the durable raw source allows safe replay.')),
251
+ };
252
+ const stateDir = path.join(resolution.workspaceDir, '.state');
253
+ const result = await createProductionHostRuntime({
254
+ ...(projectDir !== undefined ? { projectDir } : {}),
255
+ hostKind: 'workbuddy',
256
+ toolSemantics: WORKBUDDY_TOOL_SEMANTICS,
257
+ events: workbuddyEventEmitter(stateDir, evidenceContext),
258
+ // Remediation R2 (candidate-level admission): the diagnostician's
259
+ // candidates are admitted ONLY with input evidence (needs_evidence
260
+ // otherwise), and Codex-style transcript promotion does not exist on
261
+ // this host. OpenClaw-parity: the HOOK supplies the evidence — a
262
+ // sourceRef to the durable raw event line (idempotent replay source,
263
+ // SPEC §13.7) plus a bounded failure note. No raw tool output is copied
264
+ // (ADR-0027 hook-log content rule).
265
+ painEnrichmentProvider: (hostEvent) => {
266
+ if (hostEvent.kind !== 'after_tool_call')
267
+ return {};
268
+ const toolName = hostEvent.context.toolName ?? 'unknown-tool';
269
+ const output = hostEvent.context.toolOutput;
270
+ const detail = typeof output === 'object' && output !== null && !Array.isArray(output)
271
+ ? Object.hasOwn(output, 'tool_error_code')
272
+ ? `tool_error_code=${String(output.tool_error_code)}`
273
+ : Object.hasOwn(output, 'exitCode')
274
+ ? `exitCode=${String(output.exitCode)}`
275
+ : 'failure'
276
+ : 'failure';
277
+ return {
278
+ evidence: [{
279
+ sourceRef: `workbuddy-pd-hook-event-log:${hostEvent.context.sessionId}`,
280
+ note: `${toolName} failed (${detail}); raw payload in the durable workbuddy hook event log for this session`,
281
+ }],
282
+ };
283
+ },
284
+ // PRI-780 boundary: NO context provider — v2 rules stay SUSPENDED on
285
+ // WorkBuddy (never loaded context-blind). See annotateContextWarnings.
286
+ }).dispatch(event);
287
+ const evaluationDiagnostics = recordRuleHostEvaluations(stateDir, event.context.sessionId, result.metadata?.evaluations);
288
+ // Encode BEFORE recording an attributed deny: a runtime_verified
289
+ // application claims only what reached the stdout channel (P02: the
290
+ // encoded permissionDecision is the verified blocking boundary).
291
+ const encodedUnknown = adapter.encodeOutput(result, event.kind);
292
+ if (encodedUnknown !== null && !isWorkBuddyHookOutput(encodedUnknown)) {
293
+ throw new WorkBuddyEncoderError('encodeOutput produced a non-whitelisted document', 'Encode only the frozen hookSpecificOutput contract.');
294
+ }
295
+ const encoded = encodedUnknown;
296
+ if (result.decision === 'deny') {
297
+ try {
298
+ let liveActivationId;
299
+ const evaluations = result.metadata?.evaluations;
300
+ if (Array.isArray(evaluations)) {
301
+ for (const entry of evaluations) {
302
+ if (typeof entry !== 'object' || entry === null || Array.isArray(entry))
303
+ continue;
304
+ const record = entry;
305
+ const activationMode = Object.hasOwn(record, 'activationMode') ? record.activationMode : undefined;
306
+ const activationId = Object.hasOwn(record, 'activationId') ? record.activationId : undefined;
307
+ if (activationMode === 'live' && typeof activationId === 'string' && activationId.length > 0) {
308
+ liveActivationId = activationId;
309
+ break;
310
+ }
311
+ }
312
+ }
313
+ const { metadata } = result;
314
+ const principleId = typeof metadata?.principleId === 'string' ? metadata.principleId : undefined;
315
+ const ruleId = typeof metadata?.ruleId === 'string' ? metadata.ruleId : undefined;
316
+ recordWorkbuddyDenyEvidence({
317
+ workspaceDir: resolution.workspaceDir,
318
+ sessionId: event.context.sessionId,
319
+ ...(event.context.toolCallId !== undefined ? { toolCallId: event.context.toolCallId } : {}),
320
+ toolName: event.context.toolName ?? 'unknown-tool',
321
+ activationId: liveActivationId,
322
+ principleId,
323
+ ruleId,
324
+ reason: result.reason,
325
+ evidenceEnabled,
326
+ warn: evidenceContext.warn,
327
+ });
328
+ }
329
+ catch (error) {
330
+ // P02: the deny was already encoded — an evidence failure must never
331
+ // turn it into a release.
332
+ evidenceDiagnostics.push(diagnostic('degraded', `workbuddy_evidence_deny_failed:${errorMessage(error)}`, 'The deny decision was already encoded; evidence replay from the durable source is safe.'));
333
+ }
334
+ }
335
+ const stderr = [
336
+ ...annotateContextWarnings(result.warnings ?? []).slice(0, 16).map((warning) => diagnostic('degraded', warning, 'Inspect the PD governance workspace state and retry; the hook stayed permissive (allow+warnings is degraded health, not fail-closed).')),
337
+ ...evaluationDiagnostics,
338
+ ...evidenceDiagnostics,
339
+ ];
340
+ return { stdout: encoded, exitCode: 0, stderr };
341
+ }
342
+ catch (error) {
343
+ const reason = error instanceof WorkBuddyEncoderError ? error.reason : `runtime_failed:${errorMessage(error)}`;
344
+ const nextAction = error instanceof WorkBuddyEncoderError ? error.nextAction : 'Inspect the PD governance workspace state and retry.';
345
+ if (event.kind === 'before_tool_call') {
346
+ // P02: exit 2 on the PreToolUse channel genuinely blocks the tool —
347
+ // the only honest failure posture inside the supported governance path.
348
+ return { stdout: null, exitCode: 2, stderr: [diagnostic('degraded', reason, `${nextAction} The tool call was blocked because PD could not verify it.`)] };
349
+ }
350
+ // UserPromptSubmit: protect the prompt (exit 2 clears it — P02).
351
+ // after_tool_call: the tool already ran — report evidence degradation only.
352
+ return neutralWithDiagnostics([diagnostic('degraded', reason, nextAction)]);
353
+ }
354
+ }
355
+ // ─── Process-boundary belt (PRI-943 pattern, WorkBuddy exit-code semantics) ──
356
+ // No unrejected promise, unwritable stream, or unserializable result may reach
357
+ // node's default handling. Three failure modes (reproduced from spawned
358
+ // processes in tests/pd-hook-entry.test.ts):
359
+ // * a write that THROWS synchronously — caught per write below;
360
+ // * the host closing the pipe — an ASYNC 'error' event only a listener can
361
+ // contain (ERR-156);
362
+ // * the stdout JSON failing to SERIALIZE — per SPEC §4.4 never a silent
363
+ // `{} + exit 0`: an undeliverable deny becomes exit 2 (P02: exit 2 blocks
364
+ // even with stdout closed); every other channel keeps its exit code and
365
+ // degrades observably on stderr.
366
+ let beltReported = false;
367
+ /**
368
+ * Set once main() knows the registration channel: a STDOUT delivery failure
369
+ * on the PreToolUse channel means a computed deny was lost, and P02 proved
370
+ * exit 2 blocks the tool even with a dead stdout — so the belt escalates the
371
+ * exit code instead of letting the tool run unblocked.
372
+ */
373
+ let blockingChannelArmed = false;
374
+ function writeBeltDiagnostic(reason, nextAction) {
375
+ if (beltReported)
376
+ return;
377
+ beltReported = true;
378
+ try {
379
+ process.stderr.write(`${diagnostic('degraded', reason, nextAction)}\n`);
380
+ }
381
+ catch {
382
+ // Both streams gone: no channel remains inside the belt's contract.
383
+ }
384
+ }
385
+ function reportStdoutFailure(error) {
386
+ writeBeltDiagnostic(`hook_stream_failed:${errorMessage(error)}`, 'The host closed the pipe; retry the hook invocation.');
387
+ // The deny bytes could not be delivered — the exit code is the only
388
+ // remaining real blocker (P02: stdout-closed exit 2 still blocks).
389
+ if (blockingChannelArmed && (process.exitCode ?? 0) === 0)
390
+ process.exitCode = 2;
391
+ }
392
+ function reportStderrFailure(error) {
393
+ // stderr loss never loses a decision — stdout remains the contract channel.
394
+ writeBeltDiagnostic(`hook_stream_failed:${errorMessage(error)}`, 'The host closed the pipe; retry the hook invocation.');
395
+ }
396
+ function writeStream(stream, line) {
397
+ try {
398
+ process[stream].write(`${line}\n`);
399
+ return true;
400
+ }
401
+ catch (error) {
402
+ if (stream === 'stdout')
403
+ reportStdoutFailure(error);
404
+ else
405
+ reportStderrFailure(error);
406
+ return false;
407
+ }
408
+ }
409
+ function armStreamBelts() {
410
+ process.stdout.on('error', reportStdoutFailure);
411
+ process.stderr.on('error', reportStderrFailure);
412
+ }
413
+ /**
414
+ * rc-8 + SPEC §4.4: serialization failure of the stdout contract is never a
415
+ * silent `{} + exit 0`. Returns the serialized line, or null when nothing can
416
+ * be delivered — plus whether an undeliverable deny must escalate this
417
+ * invocation to a blocking exit 2 (PreToolUse channel only).
418
+ */
419
+ function serializeStdout(value, channelEventName) {
420
+ try {
421
+ return { line: JSON.stringify(value), escalateToBlocking: false };
422
+ }
423
+ catch (error) {
424
+ writeBeltDiagnostic(`hook_stdout_serialize_failed:${errorMessage(error)}`, 'Retry the invocation; the stdout contract could not be serialized.');
425
+ // An undeliverable deny loses the P02-verified blocking channel — the
426
+ // exit code is the only remaining real blocker, so use it (PreToolUse
427
+ // registration channel only; a UserPromptSubmit additionalContext loss
428
+ // degrades without blocking so the prompt is preserved).
429
+ return { line: null, escalateToBlocking: channelBlocksOnFailure(channelEventName) };
430
+ }
431
+ }
432
+ async function main() {
433
+ // argv[2] is the wrapper's event argument (argv[0]=node, argv[1]=script).
434
+ // Double-hole destructuring — eslint's member-access fix `[, x]` would
435
+ // silently read argv[1] (the SCRIPT PATH) as the channel.
436
+ const [, , channelEventName] = process.argv;
437
+ blockingChannelArmed = channelBlocksOnFailure(channelEventName);
438
+ let raw;
439
+ try {
440
+ raw = readFileSync(0, 'utf8');
441
+ }
442
+ catch (error) {
443
+ writeStream('stderr', diagnostic('degraded', `stdin_read_failed:${errorMessage(error)}`, 'Run the hook from WorkBuddy with JSON stdin.'));
444
+ process.exitCode = 0;
445
+ return;
446
+ }
447
+ let result;
448
+ try {
449
+ result = await processWorkbuddyHookInvocation(raw, channelEventName);
450
+ }
451
+ catch (error) {
452
+ // Belt for an unexpected pre-dispatch throw: the host still gets a clean
453
+ // neutral (empty stdout) instead of a bare crash — never stdout noise.
454
+ writeStream('stderr', diagnostic('degraded', `hook_pipeline_unexpected:${errorMessage(error)}`, 'Retry the hook invocation; if it repeats, inspect PD stderr and the governance workspace config.'));
455
+ result = { stdout: null, exitCode: 0, stderr: [] };
456
+ }
457
+ for (const line of result.stderr) {
458
+ if (!writeStream('stderr', line))
459
+ break;
460
+ }
461
+ let { exitCode } = result;
462
+ if (result.stdout !== null) {
463
+ const { line, escalateToBlocking } = serializeStdout(result.stdout, channelEventName);
464
+ const delivered = line !== null && writeStream('stdout', line);
465
+ if (escalateToBlocking && exitCode === 0)
466
+ exitCode = 2;
467
+ // A serialized deny whose bytes could not REACH stdout (sync write throw)
468
+ // must not degrade to exit 0: on the blocking channel the exit code is
469
+ // then the only real blocker left (P02: stdout-closed exit 2 blocks).
470
+ // The belt's reportStdoutFailure covers the ASYNC stream-error variant.
471
+ if (!delivered && blockingChannelArmed && exitCode === 0)
472
+ exitCode = 2;
473
+ }
474
+ process.exitCode = exitCode;
475
+ }
476
+ // Node resolves the main module through symlinks/junctions while argv[1]
477
+ // keeps the unresolved link path (npm shims, junctioned runtime dirs — the
478
+ // install layout junctions ~/.pd/runtime), so compare the raw URL first,
479
+ // then canonicalize through realpath (PRI-892 pattern).
480
+ function isMainModuleEntry() {
481
+ const [, entry] = process.argv;
482
+ if (!entry)
483
+ return false;
484
+ if (pathToFileURL(entry).href === import.meta.url)
485
+ return true;
486
+ try {
487
+ return pathToFileURL(realpathSync(entry)).href === import.meta.url;
488
+ }
489
+ catch (error) {
490
+ if (path.basename(entry) !== path.basename(fileURLToPath(import.meta.url)))
491
+ return false;
492
+ writeStream('stderr', diagnostic('degraded', `entry_identity_unverified:${errorMessage(error)}`, 'Reinstall the WorkBuddy adapter; if it repeats, report this line together with the command that invoked the hook.'));
493
+ return true;
494
+ }
495
+ }
496
+ if (isMainModuleEntry()) {
497
+ armStreamBelts();
498
+ void main().catch((error) => {
499
+ writeBeltDiagnostic(`hook_fatal:${errorMessage(error)}`, 'Retry the hook invocation; if it repeats, report this line together with the command that invoked the hook.');
500
+ // The WorkBuddy neutral is EMPTY stdout — nothing to write here; the
501
+ // process must terminate with a real exit code on every path.
502
+ if (process.exitCode === undefined)
503
+ process.exitCode = 0;
504
+ });
505
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * WorkBuddy Tool Semantic Declaration (SPEC §4.5, ADR-0020 third host).
3
+ *
4
+ * PURPOSE: the WorkBuddy host layer of the Tool Semantic Registry
5
+ * (PRI-634-F pattern, mirroring codex-adapter's declaration). WorkBuddy
6
+ * names its tools with a capitalized vocabulary the core baseline never
7
+ * matches — a rule generated against `write` would pass replay and never
8
+ * fire on a real `Write` event.
9
+ *
10
+ * EVIDENCE BOUND: only names with in-repo evidence are declared —
11
+ * Read/Write/Bash appear as real tool names in the frozen Phase 0 fixtures
12
+ * (tests/fixtures/host-contract/events/*.json, probes P03); Glob/Grep/Edit
13
+ * are documented core tools in the official hooks reference snapshot
14
+ * (docs/plans/2026-10-12-workbuddy-official-hooks-reference.md §PreToolUse
15
+ * common matchers). Extending beyond this surface is a follow-up once real
16
+ * sessions sample more names — a wrong guess is worse than a gap (unknown
17
+ * names resolve to 'other' and are never fabricated into Write/Bash
18
+ * equivalences).
19
+ */
20
+ import { type ToolSemanticMappingV1, type ToolSemanticRegistry } from '@principles/core/runtime-v2';
21
+ export declare const WORKBUDDY_TOOL_SEMANTIC_MAPPINGS: readonly ToolSemanticMappingV1[];
22
+ export declare const WORKBUDDY_TOOL_SEMANTICS: ToolSemanticRegistry;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * WorkBuddy Tool Semantic Declaration (SPEC §4.5, ADR-0020 third host).
3
+ *
4
+ * PURPOSE: the WorkBuddy host layer of the Tool Semantic Registry
5
+ * (PRI-634-F pattern, mirroring codex-adapter's declaration). WorkBuddy
6
+ * names its tools with a capitalized vocabulary the core baseline never
7
+ * matches — a rule generated against `write` would pass replay and never
8
+ * fire on a real `Write` event.
9
+ *
10
+ * EVIDENCE BOUND: only names with in-repo evidence are declared —
11
+ * Read/Write/Bash appear as real tool names in the frozen Phase 0 fixtures
12
+ * (tests/fixtures/host-contract/events/*.json, probes P03); Glob/Grep/Edit
13
+ * are documented core tools in the official hooks reference snapshot
14
+ * (docs/plans/2026-10-12-workbuddy-official-hooks-reference.md §PreToolUse
15
+ * common matchers). Extending beyond this surface is a follow-up once real
16
+ * sessions sample more names — a wrong guess is worse than a gap (unknown
17
+ * names resolve to 'other' and are never fabricated into Write/Bash
18
+ * equivalences).
19
+ */
20
+ import { buildToolSemanticRegistry } from '@principles/core/runtime-v2';
21
+ export const WORKBUDDY_TOOL_SEMANTIC_MAPPINGS = Object.freeze([
22
+ { rawToolName: 'Read', canonicalKind: 'read' },
23
+ { rawToolName: 'Glob', canonicalKind: 'search' },
24
+ { rawToolName: 'Grep', canonicalKind: 'search' },
25
+ { rawToolName: 'Write', canonicalKind: 'write' },
26
+ { rawToolName: 'Edit', canonicalKind: 'write' },
27
+ { rawToolName: 'Bash', canonicalKind: 'execute' },
28
+ ]);
29
+ const built = buildToolSemanticRegistry(WORKBUDDY_TOOL_SEMANTIC_MAPPINGS);
30
+ if (!built.ok) {
31
+ throw new Error(`[PD] WorkBuddy tool semantic declaration is invalid: ${built.errors.join('; ')}`);
32
+ }
33
+ export const WORKBUDDY_TOOL_SEMANTICS = built.registry;
@@ -0,0 +1,50 @@
1
+ import type { InterventionCapabilityDeclaration } from '@principles/core/runtime-v2';
2
+ /** Evidence adapter surface version (matches the frozen core contract test expectations). */
3
+ export declare const WORKBUDDY_EVIDENCE_ADAPTER_VERSION = "workbuddy-adapter@0.1.0";
4
+ export type EvidenceWarn = (diagnosticLine: string) => void;
5
+ export declare function workbuddyCapabilityDeclarations(): InterventionCapabilityDeclaration[];
6
+ export interface WorkbuddyPromptDeliveryEvidenceInput {
7
+ workspaceDir: string;
8
+ sessionId: string;
9
+ /** WorkBuddy generation_id as carried by the injected-event runId (optional). */
10
+ turnId?: string;
11
+ /** Index-aligned per-principle injection facts from the injected event. */
12
+ injected: readonly {
13
+ principleId: string;
14
+ activationId: string;
15
+ artifactId?: string;
16
+ }[];
17
+ evidenceEnabled: boolean;
18
+ warn: EvidenceWarn;
19
+ }
20
+ /**
21
+ * Record one agent-context delivery attempt per injected principle after the
22
+ * raw injected-event line has been appended to the durable WorkBuddy event
23
+ * log — confirmation 'submitted', outcome 'attempted' (submitted ≠ delivered,
24
+ * SPEC §4.6).
25
+ */
26
+ export declare function recordWorkbuddyPromptDeliveryEvidence(input: WorkbuddyPromptDeliveryEvidenceInput): void;
27
+ export interface WorkbuddyDenyEvidenceInput {
28
+ workspaceDir: string;
29
+ sessionId?: string;
30
+ toolCallId?: string;
31
+ toolName: string;
32
+ activationId?: string;
33
+ principleId?: string;
34
+ ruleId?: string;
35
+ reason?: string;
36
+ evidenceEnabled: boolean;
37
+ warn: EvidenceWarn;
38
+ }
39
+ /**
40
+ * Record the enforcement chain for an ATTRIBUTED deny that was successfully
41
+ * encoded to the WorkBuddy stdout channel. The proof boundary is the encoded
42
+ * permissionDecision (probe P02 verified the host honors it by blocking the
43
+ * tool) — PD claims exactly that, nothing broader.
44
+ *
45
+ * Episode identity requires the per-call toolCallId (WorkBuddy call_id).
46
+ * Without it the chain is skipped: a hash fallback would mint an episode
47
+ * with NO native event key, which the normalizer rejects and drops the
48
+ * whole batch.
49
+ */
50
+ export declare function recordWorkbuddyDenyEvidence(input: WorkbuddyDenyEvidenceInput): void;