create-principles-disciple 1.146.4 → 1.146.6

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 (308) hide show
  1. package/_release/product-identity.json +1 -1
  2. package/package.json +3 -3
  3. package/release-manager/package.json +3 -3
  4. package/console/dist/ui/App.d.ts +0 -1
  5. package/console/dist/ui/App.js +0 -172
  6. package/console/dist/ui/api.d.ts +0 -611
  7. package/console/dist/ui/api.js +0 -1094
  8. package/console/dist/ui/components/auth/login-form.d.ts +0 -4
  9. package/console/dist/ui/components/auth/login-form.js +0 -142
  10. package/console/dist/ui/components/auth/splash-screen.d.ts +0 -9
  11. package/console/dist/ui/components/auth/splash-screen.js +0 -22
  12. package/console/dist/ui/components/error-boundary.d.ts +0 -15
  13. package/console/dist/ui/components/error-boundary.js +0 -30
  14. package/console/dist/ui/components/focus/daily-thought-card.d.ts +0 -1
  15. package/console/dist/ui/components/focus/daily-thought-card.js +0 -41
  16. package/console/dist/ui/components/language-switcher.d.ts +0 -2
  17. package/console/dist/ui/components/language-switcher.js +0 -17
  18. package/console/dist/ui/components/layout/app-sidebar.d.ts +0 -27
  19. package/console/dist/ui/components/layout/app-sidebar.js +0 -128
  20. package/console/dist/ui/components/layout/page-loading.d.ts +0 -13
  21. package/console/dist/ui/components/layout/page-loading.js +0 -14
  22. package/console/dist/ui/components/layout/page-shell.d.ts +0 -12
  23. package/console/dist/ui/components/layout/page-shell.js +0 -11
  24. package/console/dist/ui/components/layout/section-title.d.ts +0 -10
  25. package/console/dist/ui/components/layout/section-title.js +0 -9
  26. package/console/dist/ui/components/notifications/NotificationProvider.d.ts +0 -14
  27. package/console/dist/ui/components/notifications/NotificationProvider.js +0 -136
  28. package/console/dist/ui/components/notifications/favicon-badge.d.ts +0 -3
  29. package/console/dist/ui/components/notifications/favicon-badge.js +0 -68
  30. package/console/dist/ui/components/notifications/notification-reducer.d.ts +0 -9
  31. package/console/dist/ui/components/notifications/notification-reducer.js +0 -9
  32. package/console/dist/ui/components/notifications/sound-storage.d.ts +0 -3
  33. package/console/dist/ui/components/notifications/sound-storage.js +0 -37
  34. package/console/dist/ui/components/notifications/useNotifications.d.ts +0 -1
  35. package/console/dist/ui/components/notifications/useNotifications.js +0 -9
  36. package/console/dist/ui/components/onboarding/CircuitDiagram.d.ts +0 -8
  37. package/console/dist/ui/components/onboarding/CircuitDiagram.js +0 -18
  38. package/console/dist/ui/components/onboarding/DemoResultView.d.ts +0 -22
  39. package/console/dist/ui/components/onboarding/DemoResultView.js +0 -33
  40. package/console/dist/ui/components/onboarding/SlashCommandsCard.d.ts +0 -16
  41. package/console/dist/ui/components/onboarding/SlashCommandsCard.js +0 -20
  42. package/console/dist/ui/components/onboarding/slashCommands.d.ts +0 -20
  43. package/console/dist/ui/components/onboarding/slashCommands.js +0 -22
  44. package/console/dist/ui/components/receipts/ReceiptCoverageDisclosure.d.ts +0 -6
  45. package/console/dist/ui/components/receipts/ReceiptCoverageDisclosure.js +0 -66
  46. package/console/dist/ui/components/theme-provider.d.ts +0 -14
  47. package/console/dist/ui/components/theme-provider.js +0 -40
  48. package/console/dist/ui/components/theme-toggle.d.ts +0 -2
  49. package/console/dist/ui/components/theme-toggle.js +0 -11
  50. package/console/dist/ui/components/ui/alert-dialog.d.ts +0 -20
  51. package/console/dist/ui/components/ui/alert-dialog.js +0 -26
  52. package/console/dist/ui/components/ui/badge.d.ts +0 -9
  53. package/console/dist/ui/components/ui/badge.js +0 -22
  54. package/console/dist/ui/components/ui/button.d.ts +0 -11
  55. package/console/dist/ui/components/ui/button.js +0 -34
  56. package/console/dist/ui/components/ui/card.d.ts +0 -8
  57. package/console/dist/ui/components/ui/card.js +0 -16
  58. package/console/dist/ui/components/ui/charts.d.ts +0 -51
  59. package/console/dist/ui/components/ui/charts.js +0 -72
  60. package/console/dist/ui/components/ui/dialog.d.ts +0 -19
  61. package/console/dist/ui/components/ui/dialog.js +0 -22
  62. package/console/dist/ui/components/ui/input.d.ts +0 -3
  63. package/console/dist/ui/components/ui/input.js +0 -8
  64. package/console/dist/ui/components/ui/markdown.d.ts +0 -24
  65. package/console/dist/ui/components/ui/markdown.js +0 -119
  66. package/console/dist/ui/components/ui/progress-bar.d.ts +0 -20
  67. package/console/dist/ui/components/ui/progress-bar.js +0 -38
  68. package/console/dist/ui/components/ui/select.d.ts +0 -13
  69. package/console/dist/ui/components/ui/select.js +0 -26
  70. package/console/dist/ui/components/ui/separator.d.ts +0 -3
  71. package/console/dist/ui/components/ui/separator.js +0 -6
  72. package/console/dist/ui/components/ui/sheet.d.ts +0 -25
  73. package/console/dist/ui/components/ui/sheet.js +0 -37
  74. package/console/dist/ui/components/ui/shiny-text.d.ts +0 -28
  75. package/console/dist/ui/components/ui/shiny-text.js +0 -46
  76. package/console/dist/ui/components/ui/skeleton.d.ts +0 -3
  77. package/console/dist/ui/components/ui/skeleton.js +0 -6
  78. package/console/dist/ui/components/ui/sonner.d.ts +0 -3
  79. package/console/dist/ui/components/ui/sonner.js +0 -13
  80. package/console/dist/ui/components/ui/tooltip.d.ts +0 -7
  81. package/console/dist/ui/components/ui/tooltip.js +0 -10
  82. package/console/dist/ui/data/daily-thoughts.d.ts +0 -15
  83. package/console/dist/ui/data/daily-thoughts.js +0 -164
  84. package/console/dist/ui/hooks/useNotificationSound.d.ts +0 -12
  85. package/console/dist/ui/hooks/useNotificationSound.js +0 -74
  86. package/console/dist/ui/i18n/en.json +0 -2399
  87. package/console/dist/ui/i18n/index.d.ts +0 -2
  88. package/console/dist/ui/i18n/index.js +0 -32
  89. package/console/dist/ui/i18n/zh-CN.json +0 -2399
  90. package/console/dist/ui/main.d.ts +0 -1
  91. package/console/dist/ui/main.js +0 -9
  92. package/console/dist/ui/pages/ReportProblemValidators.d.ts +0 -144
  93. package/console/dist/ui/pages/ReportProblemValidators.js +0 -418
  94. package/console/dist/ui/pages/activation/ActivationPage.d.ts +0 -1
  95. package/console/dist/ui/pages/activation/ActivationPage.js +0 -512
  96. package/console/dist/ui/pages/activation/ActivationValidators.d.ts +0 -20
  97. package/console/dist/ui/pages/activation/ActivationValidators.js +0 -160
  98. package/console/dist/ui/pages/control-center/AgentCard.d.ts +0 -31
  99. package/console/dist/ui/pages/control-center/AgentCard.js +0 -212
  100. package/console/dist/ui/pages/control-center/AgentGroup.d.ts +0 -26
  101. package/console/dist/ui/pages/control-center/AgentGroup.js +0 -38
  102. package/console/dist/ui/pages/control-center/ControlCenterPage.d.ts +0 -1
  103. package/console/dist/ui/pages/control-center/ControlCenterPage.js +0 -509
  104. package/console/dist/ui/pages/control-center/DesignGatePanel.d.ts +0 -1
  105. package/console/dist/ui/pages/control-center/DesignGatePanel.js +0 -137
  106. package/console/dist/ui/pages/control-center/RuntimeProfileManager.d.ts +0 -31
  107. package/console/dist/ui/pages/control-center/RuntimeProfileManager.js +0 -199
  108. package/console/dist/ui/pages/control-center/WorkflowDiagram.d.ts +0 -17
  109. package/console/dist/ui/pages/control-center/WorkflowDiagram.js +0 -55
  110. package/console/dist/ui/pages/debt/DebtPage.d.ts +0 -2
  111. package/console/dist/ui/pages/debt/DebtPage.js +0 -222
  112. package/console/dist/ui/pages/design-system/DesignSystemPage.d.ts +0 -2
  113. package/console/dist/ui/pages/design-system/DesignSystemPage.js +0 -30
  114. package/console/dist/ui/pages/examiner/ExaminerPage.d.ts +0 -15
  115. package/console/dist/ui/pages/examiner/ExaminerPage.js +0 -158
  116. package/console/dist/ui/pages/failed-tasks/FailedTasksPage.d.ts +0 -1
  117. package/console/dist/ui/pages/failed-tasks/FailedTasksPage.js +0 -421
  118. package/console/dist/ui/pages/focus/ApprovalSubjectReading.d.ts +0 -24
  119. package/console/dist/ui/pages/focus/ApprovalSubjectReading.js +0 -133
  120. package/console/dist/ui/pages/focus/FocusPage.d.ts +0 -123
  121. package/console/dist/ui/pages/focus/FocusPage.js +0 -567
  122. package/console/dist/ui/pages/focus/OwnerDecisionCard.d.ts +0 -9
  123. package/console/dist/ui/pages/focus/OwnerDecisionCard.js +0 -111
  124. package/console/dist/ui/pages/focus/OwnerWorkbench.d.ts +0 -19
  125. package/console/dist/ui/pages/focus/OwnerWorkbench.js +0 -75
  126. package/console/dist/ui/pages/focus/RuleCandidateBindingPanel.d.ts +0 -34
  127. package/console/dist/ui/pages/focus/RuleCandidateBindingPanel.js +0 -298
  128. package/console/dist/ui/pages/focus/focus-validation.d.ts +0 -40
  129. package/console/dist/ui/pages/focus/focus-validation.js +0 -211
  130. package/console/dist/ui/pages/intent/IntentOnboarding.d.ts +0 -67
  131. package/console/dist/ui/pages/intent/IntentOnboarding.js +0 -289
  132. package/console/dist/ui/pages/intent/IntentPage.d.ts +0 -1
  133. package/console/dist/ui/pages/intent/IntentPage.js +0 -252
  134. package/console/dist/ui/pages/pain/PainEvidenceValidators.d.ts +0 -59
  135. package/console/dist/ui/pages/pain/PainEvidenceValidators.js +0 -125
  136. package/console/dist/ui/pages/pain/PainPage.d.ts +0 -1
  137. package/console/dist/ui/pages/pain/PainPage.js +0 -420
  138. package/console/dist/ui/pages/pain/pain-card-helpers.d.ts +0 -175
  139. package/console/dist/ui/pages/pain/pain-card-helpers.js +0 -181
  140. package/console/dist/ui/pages/principles/CorePrinciplesPage.d.ts +0 -10
  141. package/console/dist/ui/pages/principles/CorePrinciplesPage.js +0 -59
  142. package/console/dist/ui/pages/principles/PrincipleDetailPage.d.ts +0 -60
  143. package/console/dist/ui/pages/principles/PrincipleDetailPage.js +0 -602
  144. package/console/dist/ui/pages/principles/PrinciplesPage.d.ts +0 -1
  145. package/console/dist/ui/pages/principles/PrinciplesPage.js +0 -327
  146. package/console/dist/ui/pages/principles/PrinciplesViewNav.d.ts +0 -8
  147. package/console/dist/ui/pages/principles/PrinciplesViewNav.js +0 -15
  148. package/console/dist/ui/pages/report-problem/ReportProblemPage.d.ts +0 -1
  149. package/console/dist/ui/pages/report-problem/ReportProblemPage.js +0 -467
  150. package/console/dist/ui/pages/settings/SettingsPage.d.ts +0 -4
  151. package/console/dist/ui/pages/settings/SettingsPage.js +0 -457
  152. package/console/dist/ui/pages/settings/UpdatePage.d.ts +0 -1
  153. package/console/dist/ui/pages/settings/UpdatePage.js +0 -215
  154. package/console/dist/ui/pages/welcome/WelcomePage.d.ts +0 -5
  155. package/console/dist/ui/pages/welcome/WelcomePage.js +0 -187
  156. package/console/dist/ui/utils/agent-metadata.d.ts +0 -71
  157. package/console/dist/ui/utils/agent-metadata.js +0 -284
  158. package/console/dist/ui/utils/approval-review.d.ts +0 -30
  159. package/console/dist/ui/utils/approval-review.js +0 -50
  160. package/console/dist/ui/utils/approval-warning-localization.d.ts +0 -34
  161. package/console/dist/ui/utils/approval-warning-localization.js +0 -148
  162. package/console/dist/ui/utils/attention-presentation.d.ts +0 -35
  163. package/console/dist/ui/utils/attention-presentation.js +0 -46
  164. package/console/dist/ui/utils/blocker-localization.d.ts +0 -23
  165. package/console/dist/ui/utils/blocker-localization.js +0 -36
  166. package/console/dist/ui/utils/control-center-helpers.d.ts +0 -79
  167. package/console/dist/ui/utils/control-center-helpers.js +0 -189
  168. package/console/dist/ui/utils/enum-labels.d.ts +0 -50
  169. package/console/dist/ui/utils/enum-labels.js +0 -171
  170. package/console/dist/ui/utils/format-date.d.ts +0 -11
  171. package/console/dist/ui/utils/format-date.js +0 -17
  172. package/console/dist/ui/utils/onboarding-state.d.ts +0 -25
  173. package/console/dist/ui/utils/onboarding-state.js +0 -77
  174. package/console/dist/ui/utils/reading-layout.d.ts +0 -20
  175. package/console/dist/ui/utils/reading-layout.js +0 -46
  176. package/console/dist/ui/utils/rule-binding-validators.d.ts +0 -13
  177. package/console/dist/ui/utils/rule-binding-validators.js +0 -188
  178. package/console/dist/ui/utils/runtime-mode.d.ts +0 -11
  179. package/console/dist/ui/utils/runtime-mode.js +0 -11
  180. package/console/dist/ui/utils/token-storage.d.ts +0 -22
  181. package/console/dist/ui/utils/token-storage.js +0 -47
  182. package/console/dist/ui/utils/validators.d.ts +0 -1178
  183. package/console/dist/ui/utils/validators.js +0 -3297
  184. package/release-manager/dist/bootstrap-entry.d.ts +0 -2
  185. package/release-manager/dist/bootstrap-entry.d.ts.map +0 -1
  186. package/release-manager/dist/bootstrap-entry.js.map +0 -1
  187. package/release-manager/dist/i18n.d.ts +0 -6
  188. package/release-manager/dist/i18n.d.ts.map +0 -1
  189. package/release-manager/dist/i18n.js.map +0 -1
  190. package/release-manager/dist/index.d.ts +0 -7
  191. package/release-manager/dist/index.d.ts.map +0 -1
  192. package/release-manager/dist/index.js +0 -656
  193. package/release-manager/dist/index.js.map +0 -1
  194. package/release-manager/dist/installer.d.ts +0 -629
  195. package/release-manager/dist/installer.d.ts.map +0 -1
  196. package/release-manager/dist/installer.js.map +0 -1
  197. package/release-manager/dist/installers/codex-host-installer.d.ts +0 -39
  198. package/release-manager/dist/installers/codex-host-installer.d.ts.map +0 -1
  199. package/release-manager/dist/installers/codex-host-installer.js.map +0 -1
  200. package/release-manager/dist/installers/index.d.ts +0 -51
  201. package/release-manager/dist/installers/index.d.ts.map +0 -1
  202. package/release-manager/dist/installers/index.js.map +0 -1
  203. package/release-manager/dist/installers/openclaw-host-installer.d.ts +0 -14
  204. package/release-manager/dist/installers/openclaw-host-installer.d.ts.map +0 -1
  205. package/release-manager/dist/installers/openclaw-host-installer.js.map +0 -1
  206. package/release-manager/dist/installers/workbuddy-host-installer.d.ts +0 -335
  207. package/release-manager/dist/installers/workbuddy-host-installer.d.ts.map +0 -1
  208. package/release-manager/dist/installers/workbuddy-host-installer.js.map +0 -1
  209. package/release-manager/dist/mvp-config.d.ts +0 -233
  210. package/release-manager/dist/mvp-config.d.ts.map +0 -1
  211. package/release-manager/dist/mvp-config.js.map +0 -1
  212. package/release-manager/dist/prompts.d.ts +0 -43
  213. package/release-manager/dist/prompts.d.ts.map +0 -1
  214. package/release-manager/dist/prompts.js +0 -268
  215. package/release-manager/dist/prompts.js.map +0 -1
  216. package/release-manager/dist/skill-language.d.ts +0 -32
  217. package/release-manager/dist/skill-language.d.ts.map +0 -1
  218. package/release-manager/dist/skill-language.js.map +0 -1
  219. package/release-manager/dist/uninstaller.d.ts +0 -68
  220. package/release-manager/dist/uninstaller.d.ts.map +0 -1
  221. package/release-manager/dist/uninstaller.js +0 -746
  222. package/release-manager/dist/uninstaller.js.map +0 -1
  223. package/release-manager/dist/update/apply-payload.d.ts +0 -143
  224. package/release-manager/dist/update/apply-payload.d.ts.map +0 -1
  225. package/release-manager/dist/update/apply-payload.js.map +0 -1
  226. package/release-manager/dist/update/atomic-file.d.ts +0 -35
  227. package/release-manager/dist/update/atomic-file.d.ts.map +0 -1
  228. package/release-manager/dist/update/atomic-file.js.map +0 -1
  229. package/release-manager/dist/update/bootstrap-executor.d.ts +0 -21
  230. package/release-manager/dist/update/bootstrap-executor.d.ts.map +0 -1
  231. package/release-manager/dist/update/bootstrap-executor.js.map +0 -1
  232. package/release-manager/dist/update/bootstrap-protocol.d.ts +0 -56
  233. package/release-manager/dist/update/bootstrap-protocol.d.ts.map +0 -1
  234. package/release-manager/dist/update/bootstrap-protocol.js.map +0 -1
  235. package/release-manager/dist/update/channel-metadata.d.ts +0 -28
  236. package/release-manager/dist/update/channel-metadata.d.ts.map +0 -1
  237. package/release-manager/dist/update/channel-metadata.js.map +0 -1
  238. package/release-manager/dist/update/channel-promotion.d.ts +0 -39
  239. package/release-manager/dist/update/channel-promotion.d.ts.map +0 -1
  240. package/release-manager/dist/update/channel-promotion.js +0 -55
  241. package/release-manager/dist/update/channel-promotion.js.map +0 -1
  242. package/release-manager/dist/update/console-surface.d.ts +0 -19
  243. package/release-manager/dist/update/console-surface.d.ts.map +0 -1
  244. package/release-manager/dist/update/console-surface.js.map +0 -1
  245. package/release-manager/dist/update/data-compatibility.d.ts +0 -35
  246. package/release-manager/dist/update/data-compatibility.d.ts.map +0 -1
  247. package/release-manager/dist/update/data-compatibility.js +0 -45
  248. package/release-manager/dist/update/data-compatibility.js.map +0 -1
  249. package/release-manager/dist/update/install-layout.d.ts +0 -105
  250. package/release-manager/dist/update/install-layout.d.ts.map +0 -1
  251. package/release-manager/dist/update/install-layout.js.map +0 -1
  252. package/release-manager/dist/update/product-identity.d.ts +0 -70
  253. package/release-manager/dist/update/product-identity.d.ts.map +0 -1
  254. package/release-manager/dist/update/product-identity.js.map +0 -1
  255. package/release-manager/dist/update/release-asset-manifest.d.ts +0 -31
  256. package/release-manager/dist/update/release-asset-manifest.d.ts.map +0 -1
  257. package/release-manager/dist/update/release-asset-manifest.js.map +0 -1
  258. package/release-manager/dist/update/release-identity.d.ts +0 -33
  259. package/release-manager/dist/update/release-identity.d.ts.map +0 -1
  260. package/release-manager/dist/update/release-identity.js.map +0 -1
  261. package/release-manager/dist/update/release-manager-authority.d.ts +0 -39
  262. package/release-manager/dist/update/release-manager-authority.d.ts.map +0 -1
  263. package/release-manager/dist/update/release-manager-authority.js.map +0 -1
  264. package/release-manager/dist/update/release-manager.d.ts +0 -156
  265. package/release-manager/dist/update/release-manager.d.ts.map +0 -1
  266. package/release-manager/dist/update/release-manager.js.map +0 -1
  267. package/release-manager/dist/update/release-metadata-publisher.d.ts +0 -199
  268. package/release-manager/dist/update/release-metadata-publisher.d.ts.map +0 -1
  269. package/release-manager/dist/update/release-metadata-publisher.js +0 -478
  270. package/release-manager/dist/update/release-metadata-publisher.js.map +0 -1
  271. package/release-manager/dist/update/release-metadata-source.d.ts +0 -85
  272. package/release-manager/dist/update/release-metadata-source.d.ts.map +0 -1
  273. package/release-manager/dist/update/release-metadata-source.js.map +0 -1
  274. package/release-manager/dist/update/release-metadata.d.ts +0 -60
  275. package/release-manager/dist/update/release-metadata.d.ts.map +0 -1
  276. package/release-manager/dist/update/release-metadata.js.map +0 -1
  277. package/release-manager/dist/update/release-policy.d.ts +0 -51
  278. package/release-manager/dist/update/release-policy.d.ts.map +0 -1
  279. package/release-manager/dist/update/release-policy.js.map +0 -1
  280. package/release-manager/dist/update/rollback-policy.d.ts +0 -56
  281. package/release-manager/dist/update/rollback-policy.d.ts.map +0 -1
  282. package/release-manager/dist/update/rollback-policy.js +0 -61
  283. package/release-manager/dist/update/rollback-policy.js.map +0 -1
  284. package/release-manager/dist/update/transaction-journal.d.ts +0 -212
  285. package/release-manager/dist/update/transaction-journal.d.ts.map +0 -1
  286. package/release-manager/dist/update/transaction-journal.js.map +0 -1
  287. package/release-manager/dist/update/trust-metadata.d.ts +0 -55
  288. package/release-manager/dist/update/trust-metadata.d.ts.map +0 -1
  289. package/release-manager/dist/update/trust-metadata.js.map +0 -1
  290. package/release-manager/dist/update/trust-root-provisioning.d.ts +0 -99
  291. package/release-manager/dist/update/trust-root-provisioning.d.ts.map +0 -1
  292. package/release-manager/dist/update/trust-root-provisioning.js.map +0 -1
  293. package/release-manager/dist/update/update-history.d.ts +0 -46
  294. package/release-manager/dist/update/update-history.d.ts.map +0 -1
  295. package/release-manager/dist/update/update-history.js +0 -123
  296. package/release-manager/dist/update/update-history.js.map +0 -1
  297. package/release-manager/dist/utils/config-file-io.d.ts +0 -34
  298. package/release-manager/dist/utils/config-file-io.d.ts.map +0 -1
  299. package/release-manager/dist/utils/config-file-io.js.map +0 -1
  300. package/release-manager/dist/utils/env.d.ts +0 -94
  301. package/release-manager/dist/utils/env.d.ts.map +0 -1
  302. package/release-manager/dist/utils/env.js.map +0 -1
  303. package/release-manager/dist/utils/logger.d.ts +0 -15
  304. package/release-manager/dist/utils/logger.d.ts.map +0 -1
  305. package/release-manager/dist/utils/logger.js.map +0 -1
  306. package/release-manager/dist/utils/workspace-divergence.d.ts +0 -36
  307. package/release-manager/dist/utils/workspace-divergence.d.ts.map +0 -1
  308. package/release-manager/dist/utils/workspace-divergence.js.map +0 -1
@@ -1,1094 +0,0 @@
1
- import { validateApprovalReview } from './utils/approval-review.js';
2
- import { clearStoredToken, loadStoredToken, storeToken } from "./utils/token-storage.js";
3
- import { validateApprovedRuleRevisionPreview, validateApprovedRuleRevisionResult } from '../shared/approved-rule-revision-contract.js';
4
- import { validateBindingReview, validateBindingQueue, validateBindingMutation, validateBindingRevise } from './utils/rule-binding-validators.js';
5
- import { validateErrorResponse, validateHeaders, validateFeedbackReport, validateFeedbackDraftsList, validateFeedbackDraftEnvelope, validateFeedbackChannels, validateFeedbackSubmitResult, validateDeleteEnvelope, validateWorkspaceEntry, validateWorkspaceList, validateRemovedEnvelope, validateSyncResult, validateConfigSummary, validateConfigCatalog, validateAgentBindingUpdate, validateDefaultRuntimeUpdate, validateRuntimeProfileMutation, validateReadinessCheck, validateFeatureFlagUpdate, validateOutputLanguage, validateGovernanceQueue, validateRecoveryResult, validateFailedTaskDetail, validateOwnerDecisionsData, validateOwnerResolutionResult, validateActivations, validateDisableActivation, validateLifecycleMetrics, validateUpdateStatus, validateUpdateHistory, validateApplyUpdateResult, validateUpdateRecovery, validateUpdateTransaction, validateApprovalRecordDirect, validatePrinciplesList, validateCorePrinciples, validateApprovalsGrouped, validateEvidenceChain, validateTrajectoryData, validateIntentSummary, validateIntentDecisionList, validateIntentDecisionResult, validateIntentDecisionSummary, validateFollowUpResponse, validateIntentInitResult, validateIntentSaveResult, validateIntentRawContent, validateIntentVersions, validateOwnerGovernanceView, validateOwnerDecisionViewCore, validateOwnerDecisionInbox, validateOwnerDecisionLibrary, validateGovernanceExperienceSnapshot, validateRuleCodeOwnerReview, validateRuleCodeMutation, validateOwnerIdentityView, validateOwnerIdentityRegister, validateOwnerIdentityUnregister, } from "./utils/validators.js";
6
- // ── Auth ──────────────────────────────────────────────────────────────────────
7
- function getToken() {
8
- // PRI-793: localStorage-backed (with one-time migration from the legacy
9
- // sessionStorage copy) so the token survives browser restarts.
10
- return loadStoredToken();
11
- }
12
- function setToken(token) {
13
- storeToken(token);
14
- }
15
- function clearToken() {
16
- clearStoredToken();
17
- }
18
- /**
19
- * True when an unauthorized response should route the UI to the login route.
20
- *
21
- * The only registered login route is exactly "/login" (App.tsx); a hash like
22
- * "#/login-help" is a different (unmatched) route and must still redirect.
23
- * Already on the login route → false, so a failed login attempt cannot
24
- * redirect-loop. The redirect target itself is the hardcoded
25
- * "#/login?session_expired=true" literal at the assignment site — never
26
- * derived from request data.
27
- */
28
- export function shouldRedirectToLoginOnUnauthorized(currentHash) {
29
- return !(currentHash === "#/login" || currentHash.startsWith("#/login?"));
30
- }
31
- /**
32
- * Staleness guard for 401 responses (PR #1635 review race fix): a 401 may
33
- * arrive AFTER the login form's restore flow set a newer token while this
34
- * request was in flight. The stale response must neither erase the newer
35
- * token nor trigger the login redirect. Pure on the two token snapshots, so
36
- * the policy is unit-testable without a browser.
37
- */
38
- export function shouldInvalidateSessionTokenOn401(requestToken, storedTokenNow) {
39
- return storedTokenNow === requestToken;
40
- }
41
- async function request(path, options, validate) {
42
- const token = getToken();
43
- const headers = {
44
- "Content-Type": "application/json",
45
- };
46
- if (token) {
47
- headers.Authorization = `Bearer ${token}`;
48
- }
49
- try {
50
- const response = await fetch(path, {
51
- ...options,
52
- headers: {
53
- ...headers,
54
- ...(validateHeaders(options?.headers) ?? {}),
55
- },
56
- });
57
- if (!response.ok) {
58
- if (response.status === 401) {
59
- // Any 401 invalidates the session: clear the token even when none was
60
- // attached (page loaded before the server switched to token mode —
61
- // PRI-643) and route to login so a token can be entered.
62
- // Staleness guard (PR #1635 review): the login form's restore flow may
63
- // have set a NEWER token while this request was in flight — a late 401
64
- // from the earlier tokenless probe must not erase it and bounce the
65
- // just-restored session back to login.
66
- if (shouldInvalidateSessionTokenOn401(token, getToken())) {
67
- clearToken();
68
- // eslint-disable-next-line no-undef
69
- if (shouldRedirectToLoginOnUnauthorized(window.location.hash)) {
70
- // eslint-disable-next-line no-undef
71
- window.location.hash = "#/login?session_expired=true";
72
- }
73
- }
74
- }
75
- let errorMessage = `HTTP ${response.status}`;
76
- let nextAction;
77
- let reason;
78
- try {
79
- const raw = await response.json();
80
- const parsed = validateErrorResponse(raw);
81
- if (parsed) {
82
- if (parsed.message) {
83
- errorMessage = parsed.message;
84
- }
85
- else if (parsed.error) {
86
- errorMessage = parsed.error;
87
- }
88
- if (parsed.reason) {
89
- ({ reason } = parsed);
90
- }
91
- if (parsed.nextAction) {
92
- ({ nextAction } = parsed);
93
- }
94
- }
95
- }
96
- catch {
97
- // ignore parse errors
98
- }
99
- return { success: false, error: errorMessage, reason, nextAction, status: response.status };
100
- }
101
- const raw = await response.json();
102
- const apiData = (raw && typeof raw === "object" && Object.hasOwn(raw, "success") && Object.hasOwn(raw, "data"))
103
- ? raw.data
104
- : raw;
105
- if (validate) {
106
- const validated = validate(apiData);
107
- if (validated !== null) {
108
- return { success: true, data: validated };
109
- }
110
- return {
111
- success: false,
112
- error: "Response validation failed: unexpected data shape from server",
113
- nextAction: "Try refreshing the page. If the problem persists, report it.",
114
- };
115
- }
116
- // No validator provided — returns ApiResponse<unknown>.
117
- // The caller must not assume a specific data shape.
118
- return { success: true, data: apiData };
119
- }
120
- catch (err) {
121
- return {
122
- success: false,
123
- error: err instanceof Error ? err.message : "Network error",
124
- };
125
- }
126
- }
127
- async function checkAuth() {
128
- const result = await request("/api/health");
129
- return result.success;
130
- }
131
- // ── Workspaces ────────────────────────────────────────────────────────────────
132
- export function fetchRuleBindingQueue() {
133
- return request('/api/v1/governance/rule-candidate-bindings', undefined, validateBindingQueue);
134
- }
135
- export function fetchRuleBindingReview(candidateId, search = '') {
136
- return request(`/api/v1/governance/rule-candidate-bindings/${encodeURIComponent(candidateId)}/review?search=${encodeURIComponent(search)}`, undefined, validateBindingReview);
137
- }
138
- export function mutateRuleBinding(candidateId, body) {
139
- return request(`/api/v1/governance/rule-candidate-bindings/${encodeURIComponent(candidateId)}`, { method: 'POST', body: JSON.stringify(body) }, validateBindingMutation);
140
- }
141
- /** PRI-1048: consume the REAL backend revision capability (revise-once route);
142
- * eligibility was resolved server-side from the production resolver. */
143
- export function reviseRuleBindingOnce(candidateId, body) {
144
- return request(`/api/v1/governance/rule-candidate-bindings/${encodeURIComponent(candidateId)}/revise-once`, { method: 'POST', body: JSON.stringify(body) }, validateBindingRevise);
145
- }
146
- /** PRI-1048 R6 #4: the bounded one-shot SOURCE correction (PRI-1047) — the
147
- * capability that applies when the binding revision budget is spent and the
148
- * Artificer stopped for a source-material defect. CAS inputs come from the
149
- * server-computed sourceCorrection preview; the server re-validates all of it. */
150
- export function correctRuleSource(candidateId, body) {
151
- return request(`/api/v1/governance/rule-candidate-bindings/${encodeURIComponent(candidateId)}/source-correct-once`, { method: 'POST', body: JSON.stringify(body) }, validateBindingRevise);
152
- }
153
- async function fetchWorkspaces() {
154
- return request("/api/workspaces", undefined, validateWorkspaceList);
155
- }
156
- async function addWorkspace(name, path) {
157
- return request("/api/workspaces", {
158
- method: "POST",
159
- body: JSON.stringify({ name, path }),
160
- }, validateWorkspaceEntry);
161
- }
162
- async function removeWorkspace(name) {
163
- return request(`/api/workspaces/${encodeURIComponent(name)}`, { method: "DELETE" }, validateRemovedEnvelope);
164
- }
165
- async function syncWorkspace(name) {
166
- return request(`/api/workspaces/${encodeURIComponent(name)}/sync`, { method: "POST" }, validateSyncResult);
167
- }
168
- // ── Principles ────────────────────────────────────────────────────────────────
169
- async function fetchPrinciples(filter) {
170
- const query = filter === undefined ? '' : `?filter=${filter}`;
171
- return request(`/api/principles${query}`, undefined, validatePrinciplesList);
172
- }
173
- // PRI-641: read-only PD Core Principles reference. Served from the canonical
174
- // registry by the server; validated here for network shape only.
175
- async function fetchCorePrinciples() {
176
- return request("/api/principles/core", undefined, validateCorePrinciples);
177
- }
178
- // Principle detail is deeply nested; for now we accept unvalidated until a
179
- // dedicated validator is added (the page already handles missing fields gracefully).
180
- // This endpoint is marked legacy/deferred for full validation.
181
- async function fetchPrincipleDetail(principleId) {
182
- return request(`/api/principles/${encodeURIComponent(principleId)}`);
183
- }
184
- async function fetchPrincipleGovernance(principleId) {
185
- return request(`/api/v1/principles/${encodeURIComponent(principleId)}/governance`, undefined, validateOwnerGovernanceView);
186
- }
187
- // Owner Decision Experience v1 (SPEC §15): canonical Owner-facing decision
188
- // projection for the Detail first layer + compact Inbox. Read-only.
189
- async function fetchOwnerDecisionView(principleId) {
190
- return request(`/api/v1/principles/${encodeURIComponent(principleId)}/owner-decision-view`, undefined, validateOwnerDecisionViewCore);
191
- }
192
- async function fetchOwnerDecisionInbox() {
193
- return request('/api/v1/principles/owner-decision-inbox', undefined, validateOwnerDecisionInbox);
194
- }
195
- async function fetchOwnerDecisionLibrary() {
196
- return request('/api/v1/principles/owner-decision-library', undefined, validateOwnerDecisionLibrary);
197
- }
198
- async function archivePrinciple(principleId) {
199
- return request(`/api/principles/${encodeURIComponent(principleId)}/archive`, {
200
- method: "POST",
201
- });
202
- }
203
- async function unarchivePrinciple(principleId) {
204
- return request(`/api/principles/${encodeURIComponent(principleId)}/unarchive`, {
205
- method: "POST",
206
- });
207
- }
208
- // ── Principle Trajectory ──────────────────────────────────────────────────────
209
- async function fetchPrincipleTrajectory(principleId) {
210
- return request(`/api/principles/${encodeURIComponent(principleId)}/trajectory`, undefined, validateTrajectoryData);
211
- }
212
- const RECEIPT_SOURCE_STATUSES = new Set(["available", "disabled", "unavailable"]);
213
- const RECEIPT_VALIDATION_STATUSES = new Set(["valid", "partial", "malformed"]);
214
- function validateReceiptCoverage(value) {
215
- if (typeof value !== "object" || value === null)
216
- return null;
217
- const rec = value;
218
- if (typeof rec.sourceStatus !== "string" || !RECEIPT_SOURCE_STATUSES.has(rec.sourceStatus))
219
- return null;
220
- if (typeof rec.validationStatus !== "string" || !RECEIPT_VALIDATION_STATUSES.has(rec.validationStatus))
221
- return null;
222
- if (rec.observedFrom !== null && typeof rec.observedFrom !== "string")
223
- return null;
224
- if (typeof rec.asOf !== "string")
225
- return null;
226
- if (typeof rec.retentionPolicyDays !== "number")
227
- return null;
228
- return {
229
- sourceStatus: rec.sourceStatus,
230
- validationStatus: rec.validationStatus,
231
- observedFrom: rec.observedFrom,
232
- asOf: rec.asOf,
233
- retentionPolicyDays: rec.retentionPolicyDays,
234
- ...(typeof rec.reasonCode === "string" ? { reasonCode: rec.reasonCode } : {}),
235
- ...(typeof rec.nextActionCode === "string" ? { nextActionCode: rec.nextActionCode } : {}),
236
- };
237
- }
238
- const RECEIPT_KINDS = new Set(["rule_blocked", "auto_correct_applied", "self_reported", "prompt_injected"]);
239
- function validateReceiptEvent(value) {
240
- if (typeof value !== "object" || value === null)
241
- return null;
242
- const rec = value;
243
- if (typeof rec.kind !== "string" || !RECEIPT_KINDS.has(rec.kind))
244
- return null;
245
- if (rec.level !== "effect" && rec.level !== "presence")
246
- return null;
247
- if (typeof rec.createdAt !== "string")
248
- return null;
249
- const asStr = (v) => (typeof v === "string" && v.length > 0 ? v : null);
250
- return {
251
- kind: rec.kind,
252
- level: rec.level,
253
- sessionId: asStr(rec.sessionId),
254
- toolName: asStr(rec.toolName),
255
- filePath: asStr(rec.filePath),
256
- digest: asStr(rec.digest),
257
- createdAt: rec.createdAt,
258
- };
259
- }
260
- function validatePrincipleReceipts(data) {
261
- if (typeof data !== "object" || data === null)
262
- return null;
263
- const rec = data;
264
- if (typeof rec.principleId !== "string")
265
- return null;
266
- // PRI-590: coverage is a required field of the receipt contract — a missing
267
- // or malformed block means server/client contract skew; reject loudly.
268
- const coverage = validateReceiptCoverage(rec.coverage);
269
- if (coverage === null)
270
- return null;
271
- const events = [];
272
- if (Array.isArray(rec.events)) {
273
- for (const item of rec.events) {
274
- const event = validateReceiptEvent(item);
275
- if (event)
276
- events.push(event);
277
- }
278
- }
279
- return {
280
- status: rec.status === "ok" ? "ok" : "degraded",
281
- reason: typeof rec.reason === "string" ? rec.reason : undefined,
282
- nextAction: typeof rec.nextAction === "string" ? rec.nextAction : undefined,
283
- principleId: rec.principleId,
284
- effectCount: typeof rec.effectCount === "number" ? rec.effectCount : 0,
285
- presenceCount: typeof rec.presenceCount === "number" ? rec.presenceCount : 0,
286
- lastEffectAt: typeof rec.lastEffectAt === "string" ? rec.lastEffectAt : null,
287
- events,
288
- coverage,
289
- };
290
- }
291
- function validateReceiptCounts(data) {
292
- if (typeof data !== "object" || data === null)
293
- return null;
294
- const rec = data;
295
- const coverage = validateReceiptCoverage(rec.coverage);
296
- if (coverage === null)
297
- return null;
298
- const counts = [];
299
- if (Array.isArray(rec.counts)) {
300
- for (const item of rec.counts) {
301
- if (typeof item !== "object" || item === null)
302
- continue;
303
- const entry = item;
304
- if (typeof entry.principleId !== "string")
305
- continue;
306
- counts.push({
307
- principleId: entry.principleId,
308
- effectCount: typeof entry.effectCount === "number" ? entry.effectCount : 0,
309
- presenceCount: typeof entry.presenceCount === "number" ? entry.presenceCount : 0,
310
- lastEffectAt: typeof entry.lastEffectAt === "string" ? entry.lastEffectAt : null,
311
- });
312
- }
313
- }
314
- return {
315
- status: rec.status === "ok" ? "ok" : "degraded",
316
- reason: typeof rec.reason === "string" ? rec.reason : undefined,
317
- nextAction: typeof rec.nextAction === "string" ? rec.nextAction : undefined,
318
- counts,
319
- coverage,
320
- };
321
- }
322
- async function fetchPrincipleReceipts(principleId) {
323
- return request(`/api/v1/receipts/principles/${encodeURIComponent(principleId)}`, undefined, validatePrincipleReceipts);
324
- }
325
- async function fetchReceiptCounts() {
326
- return request("/api/v1/receipts/counts", undefined, validateReceiptCounts);
327
- }
328
- const EVIDENCE_RECORD_KINDS = new Set(["delivery", "application", "behavior_episode", "effect", "outcome"]);
329
- function isValidEvidenceDate(value) {
330
- const match = /^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(?:\.(\d{1,3}))?Z$/.exec(value);
331
- return match !== null && Number.isFinite(Date.parse(value))
332
- && new Date(Date.parse(value)).toISOString() === `${match[1]}.${(match[2] ?? '').padEnd(3, '0')}Z`;
333
- }
334
- /**
335
- * Human-readable one-liner per record — derived from the payload union on the
336
- * client WITHOUT importing the server contract (the wire format is validated
337
- * field-by-field here, rc-1 style).
338
- */
339
- function evidenceRecordSummary(record) {
340
- const payload = typeof record.payload === "object" && record.payload !== null
341
- ? record.payload
342
- : null;
343
- if (payload === null)
344
- return null;
345
- const { kind } = record;
346
- if (kind === "delivery") {
347
- return {
348
- summary: `${String(payload.confirmation ?? "?")} / ${String(payload.outcome ?? "?")}`,
349
- detail: `target: ${String(payload.targetKind ?? "?")}${typeof payload.failureReason === "string" ? ` — ${payload.failureReason}` : ""}`,
350
- };
351
- }
352
- if (kind === "application") {
353
- return {
354
- summary: String(payload.proofMethod ?? "?"),
355
- detail: String(payload.action ?? "?") + (typeof payload.claimText === "string" ? ` — ${payload.claimText}` : ""),
356
- };
357
- }
358
- if (kind === "behavior_episode") {
359
- return {
360
- summary: String(payload.status ?? "?"),
361
- detail: String(payload.actionSummary ?? "?") + (typeof payload.resultSummary === "string" ? ` → ${payload.resultSummary}` : ""),
362
- };
363
- }
364
- if (kind === "effect") {
365
- return {
366
- summary: String(payload.status ?? "?"),
367
- detail: String(payload.observationSummary ?? "?"),
368
- };
369
- }
370
- return {
371
- summary: String(payload.outcomeSource ?? "?"),
372
- detail: String(payload.observationSummary ?? "?"),
373
- };
374
- }
375
- function validateEvidenceAuditRecord(value) {
376
- if (typeof value !== "object" || value === null)
377
- return null;
378
- const rec = value;
379
- if (typeof rec.evidenceId !== "string" || rec.evidenceId.length === 0 || rec.evidenceId.length > 256)
380
- return null;
381
- if (typeof rec.kind !== "string" || !EVIDENCE_RECORD_KINDS.has(rec.kind))
382
- return null;
383
- if (typeof rec.observationKey !== "string" || rec.observationKey.length === 0 || rec.observationKey.length > 256
384
- || typeof rec.recordedAt !== "string" || !isValidEvidenceDate(rec.recordedAt)
385
- || (rec.occurredAt !== undefined && (typeof rec.occurredAt !== "string" || !isValidEvidenceDate(rec.occurredAt)))
386
- || (rec.associationStatus !== "linked" && rec.associationStatus !== "pending_association")
387
- || (rec.sourceStatus !== undefined && rec.sourceStatus !== "unknown")
388
- || (rec.contentRedactedAt !== undefined && (typeof rec.contentRedactedAt !== "string" || !isValidEvidenceDate(rec.contentRedactedAt))))
389
- return null;
390
- const native = typeof rec.nativeRefs === "object" && rec.nativeRefs !== null ? rec.nativeRefs : null;
391
- if (!native || (native.hostKind !== "openclaw" && native.hostKind !== "codex")
392
- || ["sessionId", "runId", "turnId", "toolCallId", "toolName", "rolloutIdentity"].some((key) => Object.hasOwn(native, key)
393
- && (typeof native[key] !== "string" || native[key].length === 0 || native[key].length > 256)))
394
- return null;
395
- const hasContentRef = Object.hasOwn(rec, "contentRef");
396
- const contentRef = typeof rec.contentRef === "object" && rec.contentRef !== null && !Array.isArray(rec.contentRef) ? rec.contentRef : null;
397
- if (hasContentRef && contentRef === null)
398
- return null;
399
- if (contentRef && (typeof contentRef.principleId !== "string" || contentRef.principleId.length === 0 || contentRef.principleId.length > 256
400
- || (contentRef.resolution !== "resolved" && contentRef.resolution !== "revision_reference_unresolved")
401
- || (contentRef.payloadDigest !== undefined && (typeof contentRef.payloadDigest !== "string" || !/^sha256:[a-f0-9]{64}$/.test(contentRef.payloadDigest)))
402
- || (contentRef.resolution === "resolved" && typeof contentRef.payloadDigest !== "string")
403
- || (typeof rec.principleId === "string" && contentRef.principleId !== rec.principleId)
404
- || ["artifactId", "version", "approvalRef"].some((key) => Object.hasOwn(contentRef, key)
405
- && (typeof contentRef[key] !== "string" || contentRef[key].length === 0 || contentRef[key].length > 256))))
406
- return null;
407
- const hasActivationRef = Object.hasOwn(rec, "activationRef");
408
- const activationRef = typeof rec.activationRef === "object" && rec.activationRef !== null && !Array.isArray(rec.activationRef) ? rec.activationRef : null;
409
- if (hasActivationRef && activationRef === null)
410
- return null;
411
- if (activationRef && (typeof activationRef.activationId !== "string"
412
- || activationRef.activationId.length === 0 || activationRef.activationId.length > 256
413
- || typeof activationRef.sourceSnapshotDigest !== "string"
414
- || !/^sha256:[a-f0-9]{64}$/.test(activationRef.sourceSnapshotDigest)
415
- || activationRef.activationId !== rec.activationId
416
- || (activationRef.activatedAt !== undefined && (typeof activationRef.activatedAt !== "string" || !isValidEvidenceDate(activationRef.activatedAt)))
417
- || ["idempotencyKey", "artifactId", "channel"].some((key) => Object.hasOwn(activationRef, key)
418
- && (typeof activationRef[key] !== "string" || activationRef[key].length === 0 || activationRef[key].length > 256))))
419
- return null;
420
- if (contentRef && activationRef && typeof contentRef.artifactId === "string" && typeof activationRef.artifactId === "string"
421
- && contentRef.artifactId !== activationRef.artifactId)
422
- return null;
423
- if (contentRef && activationRef && typeof rec.occurredAt === "string" && typeof activationRef.activatedAt === "string"
424
- && Date.parse(activationRef.activatedAt) > Date.parse(rec.occurredAt))
425
- return null;
426
- const summaryPair = evidenceRecordSummary(rec);
427
- if (summaryPair === null)
428
- return null;
429
- return {
430
- evidenceId: rec.evidenceId,
431
- kind: rec.kind,
432
- observationKey: rec.observationKey,
433
- recordedAt: rec.recordedAt,
434
- occurredAt: typeof rec.occurredAt === "string" ? rec.occurredAt : undefined,
435
- principleId: typeof rec.principleId === "string" ? rec.principleId : undefined,
436
- activationId: typeof rec.activationId === "string" ? rec.activationId : undefined,
437
- episodeKey: typeof rec.episodeKey === "string" ? rec.episodeKey : undefined,
438
- effectKey: typeof rec.effectKey === "string" ? rec.effectKey : undefined,
439
- associationStatus: rec.associationStatus,
440
- ...(rec.sourceStatus === "unknown" ? { sourceStatus: "unknown" } : {}),
441
- ...(typeof rec.contentRedactedAt === "string" ? { contentRedactedAt: rec.contentRedactedAt } : {}),
442
- ...(contentRef ? { contentReference: {
443
- principleId: String(contentRef.principleId), resolution: contentRef.resolution,
444
- ...(typeof contentRef.payloadDigest === "string" ? { payloadDigest: contentRef.payloadDigest } : {}),
445
- ...(typeof contentRef.artifactId === "string" ? { artifactId: contentRef.artifactId } : {}),
446
- ...(typeof contentRef.version === "string" ? { version: contentRef.version } : {}),
447
- ...(typeof contentRef.approvalRef === "string" ? { approvalRef: contentRef.approvalRef } : {}),
448
- } } : {}),
449
- ...(activationRef ? { activationReference: {
450
- activationId: String(activationRef.activationId), sourceSnapshotDigest: String(activationRef.sourceSnapshotDigest),
451
- ...(typeof activationRef.activatedAt === "string" ? { activatedAt: activationRef.activatedAt } : {}),
452
- ...(typeof activationRef.idempotencyKey === "string" ? { idempotencyKey: activationRef.idempotencyKey } : {}),
453
- ...(typeof activationRef.artifactId === "string" ? { artifactId: activationRef.artifactId } : {}),
454
- ...(typeof activationRef.channel === "string" ? { channel: activationRef.channel } : {}),
455
- } } : {}),
456
- nativeLineage: [`hostKind=${native.hostKind}`, ...Object.entries(native).filter(([key, entry]) => key !== "hostKind" && typeof entry === "string").map(([key, entry]) => `${key}=${String(entry)}`)].slice(0, 7),
457
- summary: summaryPair.summary,
458
- detail: summaryPair.detail,
459
- };
460
- }
461
- function validateEvidenceAudit(data) {
462
- if (typeof data !== "object" || data === null)
463
- return null;
464
- const rec = data;
465
- const coverage = validateReceiptCoverage(rec.coverage);
466
- if (coverage === null)
467
- return null;
468
- const pageKinds = ["delivery", "application", "behavior_episode", "effect", "outcome"];
469
- const pages = {};
470
- if (typeof rec.pages !== "object" || rec.pages === null)
471
- return null;
472
- const rawPages = rec.pages;
473
- for (const kind of pageKinds) {
474
- const raw = rawPages[kind];
475
- if (typeof raw !== "object" || raw === null)
476
- return null;
477
- const page = raw;
478
- if (typeof page.hasMore !== "boolean")
479
- return null;
480
- let nextCursor = null;
481
- if (page.nextCursor !== null) {
482
- if (typeof page.nextCursor !== "object" || page.nextCursor === null)
483
- return null;
484
- const cursor = page.nextCursor;
485
- if (typeof cursor.recordedAt !== "string" || typeof cursor.evidenceId !== "string")
486
- return null;
487
- nextCursor = { recordedAt: cursor.recordedAt, evidenceId: cursor.evidenceId };
488
- }
489
- pages[kind] = { hasMore: page.hasMore, nextCursor };
490
- }
491
- const sections = {};
492
- for (const field of ["deliveries", "applications", "episodes", "effects", "outcomes"]) {
493
- const list = [];
494
- if (!Array.isArray(rec[field]))
495
- return null;
496
- for (const item of rec[field]) {
497
- const record = validateEvidenceAuditRecord(item);
498
- if (!record)
499
- return null;
500
- list.push(record);
501
- }
502
- sections[field] = list;
503
- }
504
- const unresolved = [];
505
- if (Array.isArray(rec.unresolvedReferences)) {
506
- for (const item of rec.unresolvedReferences) {
507
- if (typeof item !== "object" || item === null)
508
- continue;
509
- const entry = item;
510
- if (typeof entry.evidenceId === "string" && typeof entry.missingKey === "string" && typeof entry.field === "string") {
511
- unresolved.push({ evidenceId: entry.evidenceId, missingKey: entry.missingKey, field: entry.field });
512
- }
513
- }
514
- }
515
- const capabilities = [];
516
- if (Array.isArray(rec.capabilityDeclarations)) {
517
- for (const item of rec.capabilityDeclarations) {
518
- if (typeof item !== "object" || item === null)
519
- continue;
520
- const cap = item;
521
- if (cap.hostKind !== "openclaw" && cap.hostKind !== "codex")
522
- continue;
523
- if (cap.status !== "supported" && cap.status !== "unsupported" && cap.status !== "unknown")
524
- continue;
525
- if (typeof cap.capability !== "string" || typeof cap.adapterVersion !== "string" || typeof cap.channel !== "string")
526
- continue;
527
- capabilities.push({
528
- hostKind: cap.hostKind,
529
- capability: cap.capability,
530
- status: cap.status,
531
- adapterVersion: cap.adapterVersion,
532
- channel: cap.channel,
533
- ...(typeof cap.note === "string" ? { note: cap.note } : {}),
534
- });
535
- }
536
- }
537
- return {
538
- status: rec.status === "ok" ? "ok" : "degraded",
539
- reason: typeof rec.reason === "string" ? rec.reason : undefined,
540
- nextAction: typeof rec.nextAction === "string" ? rec.nextAction : undefined,
541
- deliveries: sections.deliveries ?? [],
542
- applications: sections.applications ?? [],
543
- episodes: sections.episodes ?? [],
544
- effects: sections.effects ?? [],
545
- outcomes: sections.outcomes ?? [],
546
- pages,
547
- unresolvedReferences: unresolved,
548
- capabilityDeclarations: capabilities,
549
- coverage,
550
- };
551
- }
552
- async function fetchEvidenceAudit(selectorType, id, cursor) {
553
- const query = new URLSearchParams({ type: selectorType, id });
554
- if (cursor) {
555
- query.set("afterKind", cursor.kind);
556
- query.set("afterRecordedAt", cursor.after.recordedAt);
557
- query.set("afterEvidenceId", cursor.after.evidenceId);
558
- }
559
- return request(`/api/v1/receipts/evidence-audit?${query.toString()}`, undefined, validateEvidenceAudit);
560
- }
561
- export function fetchApprovalReview(approvalId) {
562
- return request('/api/v1/approvals/' + encodeURIComponent(approvalId), undefined, validateApprovalReview);
563
- }
564
- // ── Approvals ─────────────────────────────────────────────────────────────────
565
- async function approveApproval(approvalId, note, options) {
566
- return request('/api/v1/approvals/' + encodeURIComponent(approvalId) + '/approve', {
567
- method: 'POST',
568
- body: JSON.stringify({ note, ...(options?.expectedReview === undefined ? {} : { expectedReview: options.expectedReview }), ...(options?.targetHost !== undefined ? { host: options.targetHost } : {}), ...(options?.intentReviewed !== undefined ? { intentReviewed: options.intentReviewed, reviewedArtifactId: options.reviewedArtifactId } : {}) }),
569
- }, validateApprovalRecordDirect);
570
- }
571
- async function rejectApproval(approvalId, reason, expectedReview) {
572
- return request('/api/v1/approvals/' + encodeURIComponent(approvalId) + '/reject', {
573
- method: 'POST',
574
- body: JSON.stringify({ reason, ...(expectedReview === undefined ? {} : { expectedReview }) }),
575
- }, validateApprovalRecordDirect);
576
- }
577
- async function editApproval(approvalId, newArtifactId, editReason) {
578
- return request('/api/v1/approvals/' + encodeURIComponent(approvalId) + '/edit', {
579
- method: 'POST',
580
- body: JSON.stringify({ newArtifactId, editReason: typeof editReason === 'string' ? editReason : editReason.reason, ...(typeof editReason === 'string' ? {} : { expectedReview: editReason.expectedReview }) }),
581
- }, validateApprovalRecordDirect);
582
- }
583
- // ── MVP seed feedback report drafts (PRI-285) ────────────────────────────────
584
- async function createFeedbackReport(input, diagnostics) {
585
- // Ensure diagnostics is always present in the serialized body — when
586
- // undefined, JSON.stringify drops the field entirely, leaving the server
587
- // with `{ input }` and no diagnostics. Coerce to `{}` so the server's
588
- // `obj.diagnostics ?? {}` fallback still receives an explicit object.
589
- // rc-9: the empty object is the explicit "no diagnostics collected" shape;
590
- // the server's collectDiagnostics records `unavailableReason` for each field.
591
- return request('/api/feedback/reports', {
592
- method: 'POST',
593
- body: JSON.stringify({ input, diagnostics: diagnostics ?? {} }),
594
- }, validateFeedbackReport);
595
- }
596
- async function listFeedbackReports() {
597
- // The API returns { drafts: [...] } — validate the drafts array inside
598
- return request('/api/feedback/reports', undefined, (v) => {
599
- const drafts = validateFeedbackDraftsList(v);
600
- if (drafts === null)
601
- return null;
602
- return { drafts };
603
- });
604
- }
605
- async function getFeedbackReport(id) {
606
- return request('/api/feedback/reports/' + encodeURIComponent(id), undefined, validateFeedbackDraftEnvelope);
607
- }
608
- async function deleteFeedbackReport(id) {
609
- return request('/api/feedback/reports/' + encodeURIComponent(id), {
610
- method: 'DELETE',
611
- }, validateDeleteEnvelope);
612
- }
613
- // ── Feedback submit ladder (Slice 3, spec §8) ─────────────────────────────────
614
- async function fetchFeedbackChannels() {
615
- return request('/api/feedback/submit/channels', undefined, validateFeedbackChannels);
616
- }
617
- async function submitFeedbackReport(id, channel) {
618
- return request('/api/feedback/reports/' + encodeURIComponent(id) + '/submit', {
619
- method: 'POST',
620
- body: JSON.stringify({ channel }),
621
- }, validateFeedbackSubmitResult);
622
- }
623
- /**
624
- * Manually mark a draft as sent (mailto/export channels, spec §11.4). The
625
- * console cannot server-confirm delivery for these channels, so this is an
626
- * honest user-declared status write-back — never a fake acknowledgement.
627
- */
628
- async function markFeedbackReportSent(id, via) {
629
- return request('/api/feedback/reports/' + encodeURIComponent(id) + '/mark-sent', {
630
- method: 'POST',
631
- body: JSON.stringify({ via }),
632
- }, validateFeedbackSubmitResult);
633
- }
634
- // ── Config / Control Center API (PRI-303, PRI-309) ───────────────────────────
635
- async function fetchConfigSummary() {
636
- return request('/api/v1/config/summary', undefined, validateConfigSummary);
637
- }
638
- async function fetchConfigCatalog() {
639
- return request('/api/v1/config/catalog', undefined, validateConfigCatalog);
640
- }
641
- async function updateAgentBinding(agentName, runtimeProfile, enabled) {
642
- return request(`/api/v1/config/agents/${encodeURIComponent(agentName)}/binding`, {
643
- method: 'PATCH',
644
- body: JSON.stringify({ runtimeProfile, enabled }),
645
- }, validateAgentBindingUpdate);
646
- }
647
- async function updateDefaultRuntime(defaultRuntime) {
648
- return request('/api/v1/config/default-runtime', {
649
- method: 'PATCH',
650
- body: JSON.stringify({ defaultRuntime }),
651
- }, validateDefaultRuntimeUpdate);
652
- }
653
- // ── Owner identity (ADR-0022 / PRI-578) ──────────────────────────────────────
654
- export async function fetchOwnerIdentity() {
655
- return request('/api/v1/owner-identity', undefined, validateOwnerIdentityView);
656
- }
657
- export async function registerOwnerIdentity(ownerId, credentialId) {
658
- return request('/api/v1/owner-identity', {
659
- method: 'POST',
660
- body: JSON.stringify({ ownerId, credentialId }),
661
- }, validateOwnerIdentityRegister);
662
- }
663
- export async function unregisterOwnerIdentity() {
664
- return request('/api/v1/owner-identity', { method: 'DELETE' }, validateOwnerIdentityUnregister);
665
- }
666
- // ── Runtime Profile CRUD (POST/PATCH/DELETE /api/v1/config/profiles) ──────────
667
- /**
668
- * Create a new runtime profile.
669
- *
670
- * Body shape: `{ id: string, profile: { type, provider?, model?, ... } }`.
671
- * Server validates per-type requirements (pi-ai needs provider/model/apiKeyEnv)
672
- * and returns 400 with a message on validation failure. The server response is
673
- * `{ profileId, profile }`; we validate the contract fields and rely on the
674
- * caller to re-fetch the catalog for display.
675
- *
676
- * rc-9: server-side validation errors surface as `result.error` (no silent
677
- * fallback) — the request() helper extracts the message from the error envelope.
678
- */
679
- async function createRuntimeProfile(id, profile) {
680
- return request('/api/v1/config/profiles', {
681
- method: 'POST',
682
- body: JSON.stringify({ id, profile }),
683
- }, validateRuntimeProfileMutation);
684
- }
685
- /**
686
- * Update an existing runtime profile (partial patch).
687
- *
688
- * Body shape: a partial profile object (e.g. `{ model: 'new-model' }`).
689
- * The server rejects type changes with 400; other fields are merged.
690
- */
691
- async function updateRuntimeProfile(profileId, patch) {
692
- return request(`/api/v1/config/profiles/${encodeURIComponent(profileId)}`, {
693
- method: 'PATCH',
694
- body: JSON.stringify(patch),
695
- }, validateRuntimeProfileMutation);
696
- }
697
- /**
698
- * Delete a runtime profile.
699
- *
700
- * The server rejects deletion with 400 when the profile is the defaultRuntime
701
- * or is referenced by any agent (error message lists the agent names). The
702
- * caller must surface this error to the user (rc-9: no silent fallback).
703
- */
704
- async function deleteRuntimeProfile(profileId) {
705
- return request(`/api/v1/config/profiles/${encodeURIComponent(profileId)}`, { method: 'DELETE' }, validateRuntimeProfileMutation);
706
- }
707
- /**
708
- * Fetch dynamic readiness for a single agent (GET /api/v1/config/readiness/:name).
709
- *
710
- * The summary/catalog endpoints return a static, pessimistic readiness that
711
- * doesn't probe the actual provider. This endpoint performs a live check
712
- * (e.g. testing whether the API key env var is set and the provider responds).
713
- *
714
- * Used by AgentCard when L2 is expanded and the static readiness is 'unknown'
715
- * — the pessimistic value is replaced with the live result. On failure the
716
- * caller falls back to the static value (rc-9: the error is surfaced via the
717
- * ApiResponse error envelope, not silently swallowed).
718
- */
719
- async function fetchAgentReadiness(agentName) {
720
- return request(`/api/v1/config/readiness/${encodeURIComponent(agentName)}`, undefined, validateReadinessCheck);
721
- }
722
- // ── Feature Flag Toggle (spec 2026-06-27 §13.5) ─────────────────────────────
723
- async function patchFeatureFlag(featureName, enabled) {
724
- return request(`/api/v1/config/features/${encodeURIComponent(featureName)}`, {
725
- method: 'PATCH',
726
- body: JSON.stringify({ enabled }),
727
- }, validateFeatureFlagUpdate);
728
- }
729
- // ── Principles Output Language (PRI-332 P1-1) ────────────────────────────────
730
- async function fetchOutputLanguage() {
731
- return request('/api/v1/config/principles/output-language', undefined, validateOutputLanguage);
732
- }
733
- async function updateOutputLanguage(outputLanguage) {
734
- return request('/api/v1/config/principles/output-language', {
735
- method: 'PATCH',
736
- body: JSON.stringify({ outputLanguage }),
737
- }, validateOutputLanguage);
738
- }
739
- // ── CR8: Backend Data Contract (G.1) ─────────────────────────────────────────
740
- async function fetchGovernanceQueue() {
741
- return request('/api/v1/governance/queue', undefined, validateGovernanceQueue);
742
- }
743
- // PRI-586: read-only governance experience snapshot. Only called when the
744
- // governance_experience_v1 flag is enabled — flag-off the endpoint 403s and
745
- // the Console keeps the legacy Focus experience (ERR-102: disabled ≠ unavailable).
746
- async function fetchGovernanceExperience() {
747
- return request('/api/v1/governance/experience', undefined, validateGovernanceExperienceSnapshot);
748
- }
749
- // Governance Recovery Actions v1: Owner-triggered recovery of a failed /
750
- // needs_human_review internalization task (failed→pending | needs_human_review→pending).
751
- // force=true recovers a task whose attempt budget is exhausted (core raises
752
- // its maxAttempts); it only affects the failed path.
753
- async function recoverFailedTask(taskId, reason, force) {
754
- const body = {};
755
- if (reason !== undefined && reason.length > 0) {
756
- body.reason = reason;
757
- }
758
- if (force === true) {
759
- body.force = true;
760
- }
761
- return request('/api/v1/failed-tasks/' + encodeURIComponent(taskId) + '/recover', {
762
- method: 'POST',
763
- body: JSON.stringify(body),
764
- }, validateRecoveryResult);
765
- }
766
- // PRI-747 F22 / PRI-749: consume the existing single-task detail endpoint
767
- // (task record + run history). The server route and
768
- // SqliteTaskStore.getFailedTaskDetail already existed; this wrapper is the
769
- // missing UI-side consumer the Failed Tasks page expands into.
770
- async function fetchFailedTaskDetail(taskId) {
771
- return request('/api/v1/failed-tasks/' + encodeURIComponent(taskId), undefined, validateFailedTaskDetail);
772
- }
773
- // PRI-629: unified Owner Decision inbox — read projection + resolution.
774
- async function fetchOwnerDecisions() {
775
- return request('/api/v1/governance/owner-decisions', undefined, validateOwnerDecisionsData);
776
- }
777
- async function resolveOwnerDecision(taskId, body) {
778
- return request('/api/v1/governance/owner-decisions/' + encodeURIComponent(taskId) + '/resolve', { method: 'POST', body: JSON.stringify(body) }, validateOwnerResolutionResult);
779
- }
780
- async function fetchApprovalsGrouped(targetHost) {
781
- const query = targetHost !== undefined ? `?host=${targetHost}` : '';
782
- return request(`/api/v1/approvals/grouped${query}`, undefined, validateApprovalsGrouped);
783
- }
784
- async function fetchAllActivations(targetHost) {
785
- const query = targetHost !== undefined ? `?host=${targetHost}` : '';
786
- return request(`/api/v1/activations${query}`, undefined, validateActivations);
787
- }
788
- async function disableActivation(activationId) {
789
- return request(`/api/v1/activations/${encodeURIComponent(activationId)}/disable`, {
790
- method: 'POST',
791
- body: JSON.stringify({ confirmed: true }),
792
- }, validateDisableActivation);
793
- }
794
- async function fetchRuleCodeOwnerReview(activationId) {
795
- return request(`/api/v1/activations/${encodeURIComponent(activationId)}/owner-review`, undefined, validateRuleCodeOwnerReview);
796
- }
797
- export async function fetchApprovedRuleRevisionPreview(activationId) {
798
- return request(`/api/v1/activations/${encodeURIComponent(activationId)}/rule-revision-preview`, undefined, validateApprovedRuleRevisionPreview);
799
- }
800
- export async function reviseApprovedRuleOnce(activationId, input) {
801
- return request(`/api/v1/activations/${encodeURIComponent(activationId)}/revise-rule-once`, {
802
- method: 'POST', body: JSON.stringify(input),
803
- }, validateApprovedRuleRevisionResult);
804
- }
805
- async function proposePromptRevision(activationId, statement, targetHost) {
806
- return request(`/api/v1/activations/${encodeURIComponent(activationId)}/propose-revision`, {
807
- method: 'POST',
808
- body: JSON.stringify({ statement, ...(targetHost !== undefined ? { host: targetHost } : {}) }),
809
- }, (v) => {
810
- if (typeof v !== 'object' || v === null || Array.isArray(v))
811
- return null;
812
- const rec = v;
813
- if (rec.ok !== true && rec.ok !== false)
814
- return null;
815
- const result = { ok: rec.ok };
816
- if (typeof rec.alreadyPending === 'boolean')
817
- result.alreadyPending = rec.alreadyPending;
818
- if (typeof rec.newArtifactId === 'string')
819
- result.newArtifactId = rec.newArtifactId;
820
- if (typeof rec.approvalId === 'string')
821
- result.approvalId = rec.approvalId;
822
- if (typeof rec.supersededActivationId === 'string')
823
- result.supersededActivationId = rec.supersededActivationId;
824
- if (typeof rec.oldStatement === 'string')
825
- result.oldStatement = rec.oldStatement;
826
- if (typeof rec.newStatement === 'string')
827
- result.newStatement = rec.newStatement;
828
- if (typeof rec.title === 'string')
829
- result.title = rec.title;
830
- if (typeof rec.reason === 'string')
831
- result.reason = rec.reason;
832
- if (typeof rec.nextAction === 'string')
833
- result.nextAction = rec.nextAction;
834
- if (typeof rec.error === 'string')
835
- result.error = rec.error;
836
- return result;
837
- });
838
- }
839
- async function mutateRuleCode(path, body) {
840
- return request(path, { method: 'POST', body: JSON.stringify(body) }, validateRuleCodeMutation);
841
- }
842
- function ruleCodeDecision(activationId, action, body) {
843
- return mutateRuleCode(`/api/v1/activations/${encodeURIComponent(activationId)}/${action}`, body);
844
- }
845
- function pauseAllRuleCode(body) { return mutateRuleCode('/api/v1/activations/emergency-pause', body); }
846
- function releaseRuleCodePause(pauseId, body) { return mutateRuleCode(`/api/v1/activations/emergency-pause/${encodeURIComponent(pauseId)}/release`, body); }
847
- async function fetchLifecycleMetrics(principleId) {
848
- return request(`/api/v1/lifecycle/principles/${encodeURIComponent(principleId)}`, undefined, validateLifecycleMetrics);
849
- }
850
- // ── Updates (CR9) ─────────────────────────────────────────────────────────────
851
- async function fetchUpdateStatus() {
852
- return request('/api/update/check', undefined, validateUpdateStatus);
853
- }
854
- async function fetchUpdateHistory() {
855
- return request('/api/update/history', undefined, validateUpdateHistory);
856
- }
857
- async function applyFullUpdate() {
858
- return request('/api/update/apply-full', {
859
- method: 'POST',
860
- body: JSON.stringify({}),
861
- }, validateApplyUpdateResult);
862
- }
863
- // PRI-848 (SPEC §12.1): recovery/continuation surface — the page attaches to an
864
- // unfinished transaction instead of starting a duplicate update.
865
- async function fetchUpdateRecovery() {
866
- return request('/api/update/recovery', undefined, validateUpdateRecovery);
867
- }
868
- async function fetchUpdateTransaction(transactionId) {
869
- return request(`/api/update/transaction/${encodeURIComponent(transactionId)}`, undefined, validateUpdateTransaction);
870
- }
871
- // ── Evidence Chain (PRI-331) ──────────────────────────────────────────────────
872
- async function fetchEvidenceChain() {
873
- return request('/api/v1/evidence-chain', undefined, validateEvidenceChain);
874
- }
875
- // ── Intent Summary (PRI-466) ─────────────────────────────────────────────────
876
- async function fetchIntentSummary(lang = 'zh-CN') {
877
- return request(`/api/v1/intent?lang=${lang}`, undefined, validateIntentSummary);
878
- }
879
- // ── Intent Init / Edit (PRI-477 onboarding) ──────────────────────────────────
880
- /**
881
- * Fetch raw INTENT.md content for editing via GET /api/v1/intent/content.
882
- */
883
- async function fetchIntentContent(lang = 'zh-CN') {
884
- return request(`/api/v1/intent/content?lang=${lang}`, undefined, validateIntentRawContent);
885
- }
886
- /**
887
- * Create INTENT.md from the SPEC §7 template via POST /api/v1/intent/init.
888
- * Does NOT overwrite an existing file unless force=true.
889
- */
890
- async function createIntentTemplate(force = false, lang = 'zh-CN') {
891
- return request(`/api/v1/intent/init?lang=${lang}`, {
892
- method: 'POST',
893
- body: JSON.stringify({ force }),
894
- }, validateIntentInitResult);
895
- }
896
- /**
897
- * Save user-edited INTENT.md content via PUT /api/v1/intent/content.
898
- */
899
- async function saveIntentContent(content, lang = 'zh-CN') {
900
- return request(`/api/v1/intent/content?lang=${lang}`, {
901
- method: 'PUT',
902
- body: JSON.stringify({ content }),
903
- }, validateIntentSaveResult);
904
- }
905
- async function fetchIntentVersions(lang = 'zh-CN') {
906
- return request(`/api/v1/intent/versions?lang=${lang}`, undefined, validateIntentVersions);
907
- }
908
- async function recordIntentDecision(payload) {
909
- return request('/api/v1/intent-decisions', {
910
- method: 'POST',
911
- body: JSON.stringify(payload),
912
- }, validateIntentDecisionResult);
913
- }
914
- async function listIntentDecisionsByPainId(painId) {
915
- return request(`/api/v1/intent-decisions?painId=${encodeURIComponent(painId)}`, undefined, validateIntentDecisionList);
916
- }
917
- async function listIntentDecisionsByTaskId(taskId) {
918
- return request(`/api/v1/intent-decisions?taskId=${encodeURIComponent(taskId)}`, undefined, validateIntentDecisionList);
919
- }
920
- async function fetchIntentDecisionSummary() {
921
- return request('/api/v1/intent-decisions/summary', undefined, validateIntentDecisionSummary);
922
- }
923
- async function dispatchFollowUp(decisionId, payload) {
924
- return request(`/api/v1/intent-decisions/${encodeURIComponent(decisionId)}/follow-up`, {
925
- method: 'POST',
926
- body: JSON.stringify(payload),
927
- }, validateFollowUpResponse);
928
- }
929
- function isDesignGateRecord(value) {
930
- return typeof value === "object" && value !== null && !Array.isArray(value);
931
- }
932
- function validateDesignGateSessions(value) {
933
- if (!isDesignGateRecord(value) || !Array.isArray(value.sessions))
934
- return null;
935
- const sessions = [];
936
- for (const entry of value.sessions) {
937
- if (!isDesignGateRecord(entry)
938
- || typeof entry.projectWorkspacePath !== "string" || entry.projectWorkspacePath.trim() === ""
939
- || typeof entry.hostSessionId !== "string" || entry.hostSessionId.trim() === "")
940
- return null;
941
- sessions.push({ projectWorkspacePath: entry.projectWorkspacePath, hostSessionId: entry.hostSessionId });
942
- }
943
- return { sessions };
944
- }
945
- function isDesignGateAction(value) {
946
- return value === "read" || value === "write" || value === "execute";
947
- }
948
- function isDesignGateDecisionValue(value) {
949
- return value === "approved" || value === "not_approved" || value === "not_required";
950
- }
951
- function isNonEmptyDesignGateString(value) {
952
- return typeof value === "string" && value.trim().length > 0;
953
- }
954
- function isDesignGateStringArray(value) {
955
- if (!Array.isArray(value))
956
- return false;
957
- for (let index = 0; index < value.length; index += 1) {
958
- if (!Object.hasOwn(value, index) || !isNonEmptyDesignGateString(value[index]))
959
- return false;
960
- }
961
- return true;
962
- }
963
- /**
964
- * Field-by-field mirror of the server declaration contract (rc-1 style) —
965
- * the browser bundle never runtime-imports the Node-oriented core barrel, so
966
- * the wire format is re-validated locally; the server remains the authority.
967
- */
968
- function isDesignGateDeclarationValue(value) {
969
- if (!isDesignGateRecord(value))
970
- return false;
971
- if (!Object.hasOwn(value, "sourceRef") || !isNonEmptyDesignGateString(value.sourceRef))
972
- return false;
973
- if (!isNonEmptyDesignGateString(value.governanceWorkspacePath))
974
- return false;
975
- if (!isNonEmptyDesignGateString(value.projectWorkspacePath))
976
- return false;
977
- if (!isNonEmptyDesignGateString(value.hostSessionId))
978
- return false;
979
- if (!isNonEmptyDesignGateString(value.taskRef))
980
- return false;
981
- if (!isNonEmptyDesignGateString(value.specPath) || !isNonEmptyDesignGateString(value.specDigest))
982
- return false;
983
- if (!isDesignGateRecord(value.scope))
984
- return false;
985
- if (!Object.hasOwn(value.scope, "paths") || !Object.hasOwn(value.scope, "actions"))
986
- return false;
987
- if (!isDesignGateStringArray(value.scope.paths) || value.scope.paths.length === 0)
988
- return false;
989
- if (!Array.isArray(value.scope.actions) || value.scope.actions.length === 0)
990
- return false;
991
- for (let index = 0; index < value.scope.actions.length; index += 1) {
992
- if (!Object.hasOwn(value.scope.actions, index) || !isDesignGateAction(value.scope.actions[index]))
993
- return false;
994
- }
995
- if (!isDesignGateDecisionValue(value.decision))
996
- return false;
997
- if (typeof value.revision !== "number" || !Number.isSafeInteger(value.revision) || value.revision < 1)
998
- return false;
999
- if (typeof value.revoked !== "boolean")
1000
- return false;
1001
- if (!isDesignGateRecord(value.actor)
1002
- || !Object.hasOwn(value.actor, "ownerId") || !Object.hasOwn(value.actor, "credentialId")
1003
- || !isNonEmptyDesignGateString(value.actor.ownerId) || !isNonEmptyDesignGateString(value.actor.credentialId))
1004
- return false;
1005
- if (!isNonEmptyDesignGateString(value.decidedAt))
1006
- return false;
1007
- return true;
1008
- }
1009
- function validateDesignGateDeclarationEnvelope(value) {
1010
- if (!isDesignGateRecord(value) || !Object.hasOwn(value, "declaration"))
1011
- return null;
1012
- if (value.declaration === null)
1013
- return { declaration: null };
1014
- return isDesignGateDeclarationValue(value.declaration) ? { declaration: value.declaration } : null;
1015
- }
1016
- const designGateBasePath = "/api/v1/governance/design-gate";
1017
- async function fetchDesignGateSessions() {
1018
- return request(`${designGateBasePath}/sessions`, undefined, validateDesignGateSessions);
1019
- }
1020
- async function fetchDesignGateDeclaration(projectWorkspacePath, hostSessionId) {
1021
- const query = new URLSearchParams({ projectWorkspacePath, hostSessionId });
1022
- return request(`${designGateBasePath}/declaration?${query.toString()}`, undefined, validateDesignGateDeclarationEnvelope);
1023
- }
1024
- async function createDesignGateDeclaration(input) {
1025
- return request(`${designGateBasePath}/declarations`, { method: "POST", body: JSON.stringify(input) }, validateDesignGateDeclarationEnvelope);
1026
- }
1027
- async function updateDesignGateDecision(sourceRef, expectedRevision, decision) {
1028
- return request(`${designGateBasePath}/declarations/${encodeURIComponent(sourceRef)}/decision`, { method: "POST", body: JSON.stringify({ expectedRevision, decision }) }, validateDesignGateDeclarationEnvelope);
1029
- }
1030
- async function revokeDesignGateDeclaration(sourceRef, expectedRevision) {
1031
- return request(`${designGateBasePath}/declarations/${encodeURIComponent(sourceRef)}/revoke`, { method: "POST", body: JSON.stringify({ expectedRevision }) }, validateDesignGateDeclarationEnvelope);
1032
- }
1033
- // ── Exports ───────────────────────────────────────────────────────────────────
1034
- export { request,
1035
- // auth
1036
- getToken, setToken, clearToken, checkAuth, approveApproval, rejectApproval, editApproval, fetchPrinciples, fetchCorePrinciples, fetchPrincipleDetail, fetchPrincipleGovernance, fetchOwnerDecisionView, fetchOwnerDecisionInbox, fetchOwnerDecisionLibrary, fetchPrincipleTrajectory, fetchPrincipleReceipts, fetchReceiptCounts, fetchEvidenceAudit, archivePrinciple, unarchivePrinciple, createFeedbackReport, listFeedbackReports, getFeedbackReport, deleteFeedbackReport,
1037
- // Feedback submit ladder (Slice 3, spec §8)
1038
- fetchFeedbackChannels, submitFeedbackReport, markFeedbackReportSent, fetchConfigSummary, fetchConfigCatalog, updateAgentBinding, updateDefaultRuntime, createRuntimeProfile, updateRuntimeProfile, deleteRuntimeProfile, fetchAgentReadiness, patchFeatureFlag, fetchOutputLanguage, updateOutputLanguage, fetchWorkspaces, addWorkspace, removeWorkspace, syncWorkspace, fetchGovernanceQueue, fetchGovernanceExperience, recoverFailedTask, fetchFailedTaskDetail, fetchOwnerDecisions, resolveOwnerDecision, fetchApprovalsGrouped, fetchAllActivations, disableActivation, proposePromptRevision, fetchRuleCodeOwnerReview, ruleCodeDecision, pauseAllRuleCode, releaseRuleCodePause, fetchLifecycleMetrics, fetchUpdateStatus, fetchUpdateHistory, applyFullUpdate, fetchUpdateRecovery, fetchUpdateTransaction, fetchEvidenceChain, fetchIntentSummary, fetchIntentContent, createIntentTemplate, saveIntentContent, fetchIntentVersions, recordIntentDecision, listIntentDecisionsByPainId, listIntentDecisionsByTaskId, fetchIntentDecisionSummary, dispatchFollowUp, fetchDesignGateSessions, fetchDesignGateDeclaration, createDesignGateDeclaration, updateDesignGateDecision, revokeDesignGateDeclaration, };
1039
- export async function fetchExaminerOverview() {
1040
- return request('/api/v1/examiner/overview', undefined, (v) => {
1041
- if (v !== null && typeof v === 'object' && Object.hasOwn(v, 'studies'))
1042
- return v;
1043
- return null;
1044
- });
1045
- }
1046
- export async function fetchExaminerPrinciples() {
1047
- return request('/api/v1/examiner/principles', undefined, (v) => {
1048
- if (v && typeof v === 'object' && Array.isArray(v.principles))
1049
- return v;
1050
- return null;
1051
- });
1052
- }
1053
- export async function createExaminerStudy(input) {
1054
- return request('/api/v1/examiner/studies', { method: 'POST', body: JSON.stringify(input) }, (v) => {
1055
- if (v && typeof v.studyId === 'string')
1056
- return v;
1057
- return null;
1058
- });
1059
- }
1060
- export async function fetchExaminerStudyStatus(studyId) {
1061
- return request(`/api/v1/examiner/studies/${encodeURIComponent(studyId)}`, undefined, (v) => {
1062
- if (v && typeof v.studyId === 'string')
1063
- return v;
1064
- return null;
1065
- });
1066
- }
1067
- export async function runExaminerPreflight(studyId) {
1068
- return request(`/api/v1/examiner/studies/${encodeURIComponent(studyId)}/preflight`, { method: 'POST' }, (v) => {
1069
- if (v && typeof v.ok === 'boolean')
1070
- return v;
1071
- return null;
1072
- });
1073
- }
1074
- export async function runExaminerStudy(studyId) {
1075
- return request(`/api/v1/examiner/studies/${encodeURIComponent(studyId)}/run`, { method: 'POST', body: JSON.stringify({ mode: 'offline-stub' }) }, (v) => {
1076
- if (v && Array.isArray(v.units))
1077
- return v;
1078
- return null;
1079
- });
1080
- }
1081
- export async function generateExaminerReport(studyId) {
1082
- return request(`/api/v1/examiner/studies/${encodeURIComponent(studyId)}/report`, { method: 'POST' }, (v) => {
1083
- if (v && typeof v.status === 'string')
1084
- return v;
1085
- return null;
1086
- });
1087
- }
1088
- export async function fetchExaminerReport(studyId) {
1089
- return request(`/api/v1/examiner/studies/${encodeURIComponent(studyId)}/report`, undefined, (v) => {
1090
- if (v && v.report)
1091
- return v;
1092
- return null;
1093
- });
1094
- }