agentworkshop 0.8.8 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (589) hide show
  1. package/.AgentWorkShop/prompts/host-tools.json +68 -0
  2. package/.output/.AgentWorkShop/prompts/host-tools.json +68 -0
  3. package/.output/.AgentWorkShop/schema.json +2 -0
  4. package/.output/nitro.json +1 -1
  5. package/.output/public/_nuxt/{Cdi9qfTr.js → CDO7Zey1.js} +2 -2
  6. package/.output/public/_nuxt/builds/latest.json +1 -1
  7. package/.output/public/_nuxt/builds/meta/f507c33b-4ecc-4e32-af88-2e3736b443e9.json +1 -0
  8. package/.output/server/chunks/_/access.mjs +1 -1
  9. package/.output/server/chunks/_/data-export.mjs +5 -5
  10. package/.output/server/chunks/_/data-query.mjs +2 -2
  11. package/.output/server/chunks/_/eda-run.repo.mjs +3 -3
  12. package/.output/server/chunks/_/features.mjs +5 -5
  13. package/.output/server/chunks/_/golden.mjs +2 -2
  14. package/.output/server/chunks/_/host-bindings.mjs +1 -1
  15. package/.output/server/chunks/_/index.mjs +2 -2
  16. package/.output/server/chunks/_/mes-secrets.repo.mjs +1 -1
  17. package/.output/server/chunks/_/nitro.mjs +2556 -1314
  18. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  19. package/.output/server/chunks/_/spc.mjs +2 -2
  20. package/.output/server/chunks/build/_id_-CsCtnbwe.mjs +1 -1
  21. package/.output/server/chunks/build/_id_-P1W47Gqq.mjs +1 -1
  22. package/.output/server/chunks/build/_wsId_-DpOErFj6.mjs +1 -1
  23. package/.output/server/chunks/build/agents-D7CdEUTv.mjs +1 -1
  24. package/.output/server/chunks/build/aml-DRAFRcGU.mjs +1 -1
  25. package/.output/server/chunks/build/analysis-J9axLuRt.mjs +1 -1
  26. package/.output/server/chunks/build/api-B4Om0mEc.mjs +1 -1
  27. package/.output/server/chunks/build/api-BEW_ebY_.mjs +1 -1
  28. package/.output/server/chunks/build/api-BsAgXWxi.mjs +1 -1
  29. package/.output/server/chunks/build/board-CJUc032b.mjs +1 -1
  30. package/.output/server/chunks/build/channel-templates-ggsBacZF.mjs +1 -1
  31. package/.output/server/chunks/build/constants-HPHJvjne.mjs +1 -1
  32. package/.output/server/chunks/build/daq-B_dRMDw4.mjs +1 -1
  33. package/.output/server/chunks/build/data-D8uX1dnm.mjs +1 -1
  34. package/.output/server/chunks/build/dcw-D_HD_H_2.mjs +1 -1
  35. package/.output/server/chunks/build/default-CNWS6NUw.mjs +1 -1
  36. package/.output/server/chunks/build/es-Bxu10NJ2.mjs +1 -1
  37. package/.output/server/chunks/build/logs-BnYSMRXM.mjs +1 -1
  38. package/.output/server/chunks/build/monitor-Cq6hRFeQ.mjs +1 -1
  39. package/.output/server/chunks/build/ontology-ohICfVVb.mjs +1 -1
  40. package/.output/server/chunks/build/operations-4zOVhW7o.mjs +1 -1
  41. package/.output/server/chunks/build/optimizer-BlWTsM-W.mjs +1 -1
  42. package/.output/server/chunks/build/pages-DEv4ProW.mjs +1 -1
  43. package/.output/server/chunks/build/permissions-DgXQZSyx.mjs +1 -1
  44. package/.output/server/chunks/build/pipeline-CkavMBhk.mjs +1 -1
  45. package/.output/server/chunks/build/plugins-LRjaSEZy.mjs +1 -1
  46. package/.output/server/chunks/build/schedules-Hz2DJUE2.mjs +1 -1
  47. package/.output/server/chunks/build/settings-DXLJPq7d.mjs +1 -1
  48. package/.output/server/chunks/build/studio-hSqH9TYS.mjs +1 -1
  49. package/.output/server/chunks/build/teams-BbwYJyzv.mjs +1 -1
  50. package/.output/server/chunks/build/tokens-GYaGJ35Z.mjs +1 -1
  51. package/.output/server/chunks/build/tools-CnYi9cou.mjs +1 -1
  52. package/.output/server/chunks/build/town-BV-hbwb5.mjs +1 -1
  53. package/.output/server/chunks/build/town-CcoQKjMj.mjs +1 -1
  54. package/.output/server/chunks/build/types-D6J7slEa.mjs +1 -1
  55. package/.output/server/chunks/build/types-DWqIeMRP.mjs +1 -1
  56. package/.output/server/chunks/build/useAgentHarnessOptions-Dq0l0Z6d.mjs +1 -1
  57. package/.output/server/chunks/build/useAgentTemplateActions-BFOHb5-L.mjs +1 -1
  58. package/.output/server/chunks/build/useAgentTemplateDialogState-CZzpu5og.mjs +1 -1
  59. package/.output/server/chunks/build/useAgentTemplateForm-CuJPOPcK.mjs +1 -1
  60. package/.output/server/chunks/build/useAgentTemplatesCatalog-B2bIhZLA.mjs +1 -1
  61. package/.output/server/chunks/build/useAmlDatasets-DeoE1idn.mjs +1 -1
  62. package/.output/server/chunks/build/useAmlEntities-BJhvdqHJ.mjs +1 -1
  63. package/.output/server/chunks/build/useAmlEnv-CDIZ6xTe.mjs +1 -1
  64. package/.output/server/chunks/build/useAmlExperiments-Dloi834i.mjs +1 -1
  65. package/.output/server/chunks/build/useAmlFormat-C2sl3MGB.mjs +1 -1
  66. package/.output/server/chunks/build/useAmlJobs-BF9LpwXz.mjs +1 -1
  67. package/.output/server/chunks/build/useAmlModels-_bweOr3R.mjs +1 -1
  68. package/.output/server/chunks/build/useAmlNotes-DQj980iX.mjs +1 -1
  69. package/.output/server/chunks/build/useAmlPredict-DHNgDSJn.mjs +1 -1
  70. package/.output/server/chunks/build/useAnalysisFeed-BrEGV_9x.mjs +1 -1
  71. package/.output/server/chunks/build/useDaqAddNode-D_Rkju0f.mjs +1 -1
  72. package/.output/server/chunks/build/useDaqDetailBinding-DCWaLKXT.mjs +1 -1
  73. package/.output/server/chunks/build/useDaqDetailFrames-BOIcOJRB.mjs +1 -1
  74. package/.output/server/chunks/build/useDaqDetailHistory-D6WulPVs.mjs +1 -1
  75. package/.output/server/chunks/build/useDaqDetailNode-BGMRUIXN.mjs +1 -1
  76. package/.output/server/chunks/build/useDaqDetailParams-Cm9a9r5G.mjs +1 -1
  77. package/.output/server/chunks/build/useDaqFilters-zAAVlzJQ.mjs +1 -1
  78. package/.output/server/chunks/build/useDaqNodeWindow-1DWj2H5G.mjs +1 -1
  79. package/.output/server/chunks/build/useDaqOptimizations-BE_9Z2s_.mjs +1 -1
  80. package/.output/server/chunks/build/useDaqTemplates-CK37sMfi.mjs +1 -1
  81. package/.output/server/chunks/build/useDashboardCharts-D45083s_.mjs +1 -1
  82. package/.output/server/chunks/build/useDashboardData-Cw8lrPo5.mjs +1 -1
  83. package/.output/server/chunks/build/useDcwAddNode-KnocMk1m.mjs +1 -1
  84. package/.output/server/chunks/build/useDcwCards-C53IiOcg.mjs +1 -1
  85. package/.output/server/chunks/build/useDcwDetailScope-D6qXrfZu.mjs +1 -1
  86. package/.output/server/chunks/build/useDcwDetailTemplates-DPOXu1o_.mjs +1 -1
  87. package/.output/server/chunks/build/useDcwFilter-DNQ6Ivwd.mjs +1 -1
  88. package/.output/server/chunks/build/useDcwLedger-BhbUBCbi.mjs +1 -1
  89. package/.output/server/chunks/build/useDcwLineMutations-KA7VnggO.mjs +1 -1
  90. package/.output/server/chunks/build/useDcwLineRun-3zx_UCxi.mjs +1 -1
  91. package/.output/server/chunks/build/useDcwParamApprovals-DzyY6Tmi.mjs +1 -1
  92. package/.output/server/chunks/build/useDcwProducts-B05ymt3k.mjs +1 -1
  93. package/.output/server/chunks/build/useDcwQuery-vWpgpSmJ.mjs +1 -1
  94. package/.output/server/chunks/build/useDcwQuickActions-DUkLy34S.mjs +1 -1
  95. package/.output/server/chunks/build/useDcwRecipes-BAb4Yg3d.mjs +1 -1
  96. package/.output/server/chunks/build/useDcwTemplates-D2aoejps.mjs +1 -1
  97. package/.output/server/chunks/build/useDcwWrites-7w8txksD.mjs +1 -1
  98. package/.output/server/chunks/build/useExpConfirmations-BM626N4p.mjs +1 -1
  99. package/.output/server/chunks/build/useLogsFormat-B-o4MHy7.mjs +1 -1
  100. package/.output/server/chunks/build/useLogsManual-D0dvgCsP.mjs +1 -1
  101. package/.output/server/chunks/build/useLogsQuery-D7hrJ3yn.mjs +1 -1
  102. package/.output/server/chunks/build/useLogsScope-DEUyq-My.mjs +1 -1
  103. package/.output/server/chunks/build/useMonitorColumns-vVnt3r5Q.mjs +1 -1
  104. package/.output/server/chunks/build/useMonitorData-DIkiLr_h.mjs +1 -1
  105. package/.output/server/chunks/build/useMonitorFormat-CyURtH8N.mjs +1 -1
  106. package/.output/server/chunks/build/useMonitorTerminal-Dj4QwRNW.mjs +1 -1
  107. package/.output/server/chunks/build/useOperationsFeed-Ci4mZAn_.mjs +1 -1
  108. package/.output/server/chunks/build/useRecipeDispatchApprovals-BYtiqfeb.mjs +1 -1
  109. package/.output/server/chunks/build/useTeamActions-BDjU06LP.mjs +1 -1
  110. package/.output/server/chunks/build/useTeamAddMemberDialog-J3oFn3FI.mjs +1 -1
  111. package/.output/server/chunks/build/useTeamCreateDialog-fbn4ixYu.mjs +1 -1
  112. package/.output/server/chunks/build/useTeamDeployDialog-BNezMD2k.mjs +1 -1
  113. package/.output/server/chunks/build/useTeamDialogState-CFRUQxAf.mjs +1 -1
  114. package/.output/server/chunks/build/useTeamPluginDialog-BZznrOVe.mjs +1 -1
  115. package/.output/server/chunks/build/useTeamsCatalog-DuZFP3oG.mjs +1 -1
  116. package/.output/server/chunks/build/useTokenClipboard-CwQpoFeP.mjs +1 -1
  117. package/.output/server/chunks/build/useTokenCreate-Ctl0YGhL.mjs +1 -1
  118. package/.output/server/chunks/build/useTokenRename-Cm3ypSfN.mjs +1 -1
  119. package/.output/server/chunks/build/useTokenReveal-CeoWL5Mt.mjs +1 -1
  120. package/.output/server/chunks/build/useTokensList-CNIzON3u.mjs +1 -1
  121. package/.output/server/chunks/build/useWorkbenchAuth-CY-bVFMu.mjs +1 -1
  122. package/.output/server/chunks/build/useWorkbenchWorkspaces-DhZQFss9.mjs +1 -1
  123. package/.output/server/chunks/build/useWorkspaceAuth-Dlvj9csD.mjs +1 -1
  124. package/.output/server/chunks/build/useWorkspaceChannels-CPFepxTN.mjs +1 -1
  125. package/.output/server/chunks/build/useWorkspacePanels-CTwREmq0.mjs +1 -1
  126. package/.output/server/chunks/build/useWorkspaceShell-BCypjjjE.mjs +1 -1
  127. package/.output/server/chunks/build/users-DjiVC_tS.mjs +1 -1
  128. package/.output/server/chunks/build/workshop-1gKeDASV.mjs +1 -1
  129. package/.output/server/chunks/routes/api/health.get.mjs +1 -1
  130. package/.output/server/chunks/routes/api/index.get.mjs +1 -1
  131. package/.output/server/chunks/routes/api/index.post.mjs +1 -1
  132. package/.output/server/chunks/routes/api/mcp/workshop.mjs +1 -1
  133. package/.output/server/chunks/routes/api/metrics.mjs +1 -1
  134. package/.output/server/chunks/routes/api/plugins/_name/_...path_.mjs +1 -1
  135. package/.output/server/chunks/routes/api/plugins/client/_name_.get.mjs +1 -1
  136. package/.output/server/chunks/routes/api/plugins/i18n.get.mjs +1 -1
  137. package/.output/server/chunks/routes/api/plugins/manifest.get.mjs +1 -1
  138. package/.output/server/chunks/routes/api/system/backup/list.get.mjs +1 -1
  139. package/.output/server/chunks/routes/api/system/backup/run.post.mjs +3 -3
  140. package/.output/server/chunks/routes/api/system/config-groups/_id_.delete.mjs +1 -1
  141. package/.output/server/chunks/routes/api/system/config-groups/_id_.patch.mjs +1 -1
  142. package/.output/server/chunks/routes/api/system/config.get.mjs +1 -1
  143. package/.output/server/chunks/routes/api/system/index.get.mjs +1 -1
  144. package/.output/server/chunks/routes/api/system/index.patch.mjs +1 -1
  145. package/.output/server/chunks/routes/api/system/index.post.mjs +1 -1
  146. package/.output/server/chunks/routes/api/system/index2.get.mjs +1 -1
  147. package/.output/server/chunks/routes/api/system/monitor/terminal/ws.mjs +1 -1
  148. package/.output/server/chunks/routes/api/system/monitor/terminate.post.mjs +1 -1
  149. package/.output/server/chunks/routes/api/system/monitor.get.mjs +1 -1
  150. package/.output/server/chunks/routes/api/system/settings/events.get.mjs +1 -1
  151. package/.output/server/chunks/routes/api/system/settings/reset.post.mjs +1 -1
  152. package/.output/server/chunks/routes/api/system/timezone.get.mjs +1 -1
  153. package/.output/server/chunks/routes/api/users/_id_.delete.mjs +1 -1
  154. package/.output/server/chunks/routes/api/users/_id_.get.mjs +1 -1
  155. package/.output/server/chunks/routes/api/users/_id_.put.mjs +1 -1
  156. package/.output/server/chunks/routes/api/users/change-password.post.mjs +1 -1
  157. package/.output/server/chunks/routes/api/users/index.get.mjs +1 -1
  158. package/.output/server/chunks/routes/api/users/index.post.mjs +1 -1
  159. package/.output/server/chunks/routes/api/users/login.post.mjs +1 -1
  160. package/.output/server/chunks/routes/api/users/logout.post.mjs +1 -1
  161. package/.output/server/chunks/routes/api/users/me.get.mjs +1 -1
  162. package/.output/server/chunks/routes/api/users/register.post.mjs +1 -1
  163. package/.output/server/chunks/routes/api/users/setup-status.get.mjs +1 -1
  164. package/.output/server/chunks/routes/api/users/tokens/_id/token.get.mjs +1 -1
  165. package/.output/server/chunks/routes/api/users/tokens/_id_.delete.mjs +1 -1
  166. package/.output/server/chunks/routes/api/users/tokens/_id_.patch.mjs +1 -1
  167. package/.output/server/chunks/routes/api/workshop/_...path_.mjs +1 -1
  168. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.get.mjs +1 -1
  169. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.post.mjs +1 -1
  170. package/.output/server/chunks/routes/api/workshop/a2a/send.post.mjs +1 -1
  171. package/.output/server/chunks/routes/api/workshop/agent-tools/approvals/_id/decide.post.mjs +1 -1
  172. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.delete.mjs +1 -1
  173. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.patch.mjs +1 -1
  174. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/grant.post.mjs +1 -1
  175. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/revoke.post.mjs +1 -1
  176. package/.output/server/chunks/routes/api/workshop/agent-tools/index.get.mjs +1 -1
  177. package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs +2 -2
  178. package/.output/server/chunks/routes/api/workshop/agent-tools/index2.get.mjs +1 -1
  179. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs +1 -1
  180. package/.output/server/chunks/routes/api/workshop/agent-tools/list.get.mjs +1 -1
  181. package/.output/server/chunks/routes/api/workshop/agents/_id_.delete.mjs +1 -1
  182. package/.output/server/chunks/routes/api/workshop/agents/_id_.get.mjs +1 -1
  183. package/.output/server/chunks/routes/api/workshop/agents/_id_.patch.mjs +1 -1
  184. package/.output/server/chunks/routes/api/workshop/agents/subscribe.post.mjs +1 -1
  185. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id/preview.get.mjs +1 -1
  186. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.delete.mjs +1 -1
  187. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs +1 -1
  188. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.patch.mjs +1 -1
  189. package/.output/server/chunks/routes/api/workshop/aml/entities/prune.post.mjs +1 -1
  190. package/.output/server/chunks/routes/api/workshop/aml/env/recheck.post.mjs +1 -1
  191. package/.output/server/chunks/routes/api/workshop/aml/env/uv.post.mjs +1 -1
  192. package/.output/server/chunks/routes/api/workshop/aml/env/venv.post.mjs +1 -1
  193. package/.output/server/chunks/routes/api/workshop/aml/index.get.mjs +1 -1
  194. package/.output/server/chunks/routes/api/workshop/aml/index.post.mjs +1 -1
  195. package/.output/server/chunks/routes/api/workshop/aml/index2.get.mjs +1 -1
  196. package/.output/server/chunks/routes/api/workshop/aml/index2.post.mjs +1 -1
  197. package/.output/server/chunks/routes/api/workshop/aml/index3.get.mjs +1 -1
  198. package/.output/server/chunks/routes/api/workshop/aml/index3.post.mjs +1 -1
  199. package/.output/server/chunks/routes/api/workshop/aml/index4.get.mjs +1 -1
  200. package/.output/server/chunks/routes/api/workshop/aml/index5.get.mjs +1 -1
  201. package/.output/server/chunks/routes/api/workshop/aml/index6.get.mjs +1 -1
  202. package/.output/server/chunks/routes/api/workshop/aml/index7.get.mjs +1 -1
  203. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/cancel.post.mjs +1 -1
  204. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/logs.get.mjs +1 -1
  205. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/retry.post.mjs +1 -1
  206. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id_.delete.mjs +1 -1
  207. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id_.get.mjs +1 -1
  208. package/.output/server/chunks/routes/api/workshop/aml/models/_id/predict.post.mjs +1 -1
  209. package/.output/server/chunks/routes/api/workshop/aml/models/_id/promote.post.mjs +1 -1
  210. package/.output/server/chunks/routes/api/workshop/aml/models/_id_.delete.mjs +1 -1
  211. package/.output/server/chunks/routes/api/workshop/aml/models/_id_.patch.mjs +1 -1
  212. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id/train.post.mjs +1 -1
  213. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id_.delete.mjs +1 -1
  214. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id_.patch.mjs +1 -1
  215. package/.output/server/chunks/routes/api/workshop/aml/twin/providers.get.mjs +1 -1
  216. package/.output/server/chunks/routes/api/workshop/analysis/_id_.delete.mjs +1 -1
  217. package/.output/server/chunks/routes/api/workshop/analysis/_id_.get.mjs +1 -1
  218. package/.output/server/chunks/routes/api/workshop/analysis/_id_.patch.mjs +1 -1
  219. package/.output/server/chunks/routes/api/workshop/approvals/_id/decide.post.mjs +1 -1
  220. package/.output/server/chunks/routes/api/workshop/assets/character/_id_.delete.mjs +1 -1
  221. package/.output/server/chunks/routes/api/workshop/assets/devices/_id_.delete.mjs +1 -1
  222. package/.output/server/chunks/routes/api/workshop/assets/index.get.mjs +1 -1
  223. package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs +1 -1
  224. package/.output/server/chunks/routes/api/workshop/assets/index2.get.mjs +1 -1
  225. package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs +1 -1
  226. package/.output/server/chunks/routes/api/workshop/audit.get.mjs +1 -1
  227. package/.output/server/chunks/routes/api/workshop/caller.mjs +1 -1
  228. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +2 -2
  229. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.delete.mjs +1 -1
  230. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.get.mjs +1 -1
  231. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.patch.mjs +1 -1
  232. package/.output/server/chunks/routes/api/workshop/channel-templates/from-channel.post.mjs +1 -1
  233. package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs +1 -1
  234. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.get.mjs +1 -1
  235. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.post.mjs +1 -1
  236. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/_memoryId_.delete.mjs +1 -1
  237. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/search.post.mjs +1 -1
  238. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/model.patch.mjs +1 -1
  239. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/position.patch.mjs +1 -1
  240. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/range.patch.mjs +1 -1
  241. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/rotate-token.post.mjs +1 -1
  242. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/stop.post.mjs +1 -1
  243. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.delete.mjs +1 -1
  244. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.patch.mjs +1 -1
  245. package/.output/server/chunks/routes/api/workshop/channels/_id/chat/index.get.mjs +1 -1
  246. package/.output/server/chunks/routes/api/workshop/channels/_id/chat/index.post.mjs +1 -1
  247. package/.output/server/chunks/routes/api/workshop/channels/_id/chat/messages/_messageId/read.post.mjs +1 -1
  248. package/.output/server/chunks/routes/api/workshop/channels/_id/chat/permissions.get.mjs +1 -1
  249. package/.output/server/chunks/routes/api/workshop/channels/_id/events.get.mjs +1 -1
  250. package/.output/server/chunks/routes/api/workshop/channels/_id/execution-mode.patch.mjs +1 -1
  251. package/.output/server/chunks/routes/api/workshop/channels/_id/index.get.mjs +1 -1
  252. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs +1 -1
  253. package/.output/server/chunks/routes/api/workshop/channels/_id/index.put.mjs +1 -1
  254. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.get.mjs +1 -1
  255. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.post.mjs +1 -1
  256. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.put.mjs +1 -1
  257. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.get.mjs +1 -1
  258. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs +1 -1
  259. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.get.mjs +1 -1
  260. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.post.mjs +1 -1
  261. package/.output/server/chunks/routes/api/workshop/channels/_id/index5.get.mjs +1 -1
  262. package/.output/server/chunks/routes/api/workshop/channels/_id/index6.get.mjs +1 -1
  263. package/.output/server/chunks/routes/api/workshop/channels/_id/index7.get.mjs +1 -1
  264. package/.output/server/chunks/routes/api/workshop/channels/_id/line.put.mjs +1 -1
  265. package/.output/server/chunks/routes/api/workshop/channels/_id/members/_userId/approve.post.mjs +1 -1
  266. package/.output/server/chunks/routes/api/workshop/channels/_id/members/_userId_.delete.mjs +1 -1
  267. package/.output/server/chunks/routes/api/workshop/channels/_id/members/join.post.mjs +1 -1
  268. package/.output/server/chunks/routes/api/workshop/channels/_id/members/leave.post.mjs +1 -1
  269. package/.output/server/chunks/routes/api/workshop/channels/_id/memories/_memoryId_.delete.mjs +1 -1
  270. package/.output/server/chunks/routes/api/workshop/channels/_id/queue.get.mjs +1 -1
  271. package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs +1 -1
  272. package/.output/server/chunks/routes/api/workshop/channels/_id/tools/reset.post.mjs +1 -1
  273. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.get.mjs +1 -1
  274. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.patch.mjs +1 -1
  275. package/.output/server/chunks/routes/api/workshop/channels/_id_.delete.mjs +1 -1
  276. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs +1 -1
  277. package/.output/server/chunks/routes/api/workshop/channels/index.patch.mjs +1 -1
  278. package/.output/server/chunks/routes/api/workshop/channels.get.mjs +1 -1
  279. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +7 -7
  280. package/.output/server/chunks/routes/api/workshop/daq/_id/bind.post.mjs +1 -1
  281. package/.output/server/chunks/routes/api/workshop/daq/_id/bindings.put.mjs +1 -1
  282. package/.output/server/chunks/routes/api/workshop/daq/_id/frames/content.get.mjs +1 -1
  283. package/.output/server/chunks/routes/api/workshop/daq/_id/frames.get.mjs +1 -1
  284. package/.output/server/chunks/routes/api/workshop/daq/_id/ingest.post.mjs +2 -2
  285. package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs +1 -1
  286. package/.output/server/chunks/routes/api/workshop/daq/_id/test.post.mjs +1 -1
  287. package/.output/server/chunks/routes/api/workshop/daq/_id_.delete.mjs +1 -1
  288. package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs +1 -1
  289. package/.output/server/chunks/routes/api/workshop/daq/alarms/_id/ack.post.mjs +1 -1
  290. package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs +1 -1
  291. package/.output/server/chunks/routes/api/workshop/daq/controller.post.mjs +1 -1
  292. package/.output/server/chunks/routes/api/workshop/daq/export/_id_.get.mjs +1 -1
  293. package/.output/server/chunks/routes/api/workshop/daq/export-file.get.mjs +1 -1
  294. package/.output/server/chunks/routes/api/workshop/daq/index.get.mjs +1 -1
  295. package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs +1 -1
  296. package/.output/server/chunks/routes/api/workshop/daq/index2.post.mjs +1 -1
  297. package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs +1 -1
  298. package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs +1 -1
  299. package/.output/server/chunks/routes/api/workshop/daq/query.get.mjs +1 -1
  300. package/.output/server/chunks/routes/api/workshop/daq/storage/retention.put.mjs +1 -1
  301. package/.output/server/chunks/routes/api/workshop/daq/storage/rollup.post.mjs +1 -1
  302. package/.output/server/chunks/routes/api/workshop/daq/storage.get.mjs +1 -1
  303. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs +1 -1
  304. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs +1 -1
  305. package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs +1 -1
  306. package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs +1 -1
  307. package/.output/server/chunks/routes/api/workshop/dcw/_id/bindings.put.mjs +1 -1
  308. package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs +1 -1
  309. package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs +1 -1
  310. package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs +1 -1
  311. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +1 -1
  312. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +1 -1
  313. package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs +1 -1
  314. package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs +1 -1
  315. package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs +1 -1
  316. package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs +1 -1
  317. package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs +1 -1
  318. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +1 -1
  319. package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs +1 -1
  320. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +1 -1
  321. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +1 -1
  322. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +1 -1
  323. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +1 -1
  324. package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs +1 -1
  325. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs +1 -1
  326. package/.output/server/chunks/routes/api/workshop/dcw/index7.get.mjs +1 -1
  327. package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs +1 -1
  328. package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs +1 -1
  329. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +1 -1
  330. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +1 -1
  331. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +1 -1
  332. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.patch.mjs +1 -1
  333. package/.output/server/chunks/routes/api/workshop/dcw/mes-artifacts/file.get.mjs +1 -1
  334. package/.output/server/chunks/routes/api/workshop/dcw/mes-hook-test.post.mjs +1 -1
  335. package/.output/server/chunks/routes/api/workshop/dcw/mes-test-read.post.mjs +1 -1
  336. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs +1 -1
  337. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs +1 -1
  338. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs +1 -1
  339. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs +1 -1
  340. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs +1 -1
  341. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/write.post.mjs +1 -1
  342. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs +1 -1
  343. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs +1 -1
  344. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs +1 -1
  345. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs +1 -1
  346. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs +1 -1
  347. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs +1 -1
  348. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/revert.post.mjs +1 -1
  349. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs +1 -1
  350. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/versions.get.mjs +1 -1
  351. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs +2 -2
  352. package/.output/server/chunks/routes/api/workshop/dcw/recipes/index.patch.mjs +1 -1
  353. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs +1 -1
  354. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs +1 -1
  355. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs +1 -1
  356. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +1 -1
  357. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +1 -1
  358. package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs +1 -1
  359. package/.output/server/chunks/routes/api/workshop/device-twins/_id/control.post.mjs +1 -1
  360. package/.output/server/chunks/routes/api/workshop/device-twins/_id/telemetry.post.mjs +1 -1
  361. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs +1 -1
  362. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs +1 -1
  363. package/.output/server/chunks/routes/api/workshop/eda/charts/_id_.delete.mjs +1 -1
  364. package/.output/server/chunks/routes/api/workshop/eda/charts/_id_.get.mjs +1 -1
  365. package/.output/server/chunks/routes/api/workshop/eda/charts/_id_.patch.mjs +1 -1
  366. package/.output/server/chunks/routes/api/workshop/eda/commonality.get.mjs +1 -1
  367. package/.output/server/chunks/routes/api/workshop/eda/dashboards/_id_.delete.mjs +1 -1
  368. package/.output/server/chunks/routes/api/workshop/eda/dashboards/_id_.get.mjs +1 -1
  369. package/.output/server/chunks/routes/api/workshop/eda/dashboards/_id_.patch.mjs +1 -1
  370. package/.output/server/chunks/routes/api/workshop/eda/features/jobs.get.mjs +1 -1
  371. package/.output/server/chunks/routes/api/workshop/eda/features/run.post.mjs +1 -1
  372. package/.output/server/chunks/routes/api/workshop/eda/golden/_id_.delete.mjs +1 -1
  373. package/.output/server/chunks/routes/api/workshop/eda/golden/deviation.get.mjs +1 -1
  374. package/.output/server/chunks/routes/api/workshop/eda/golden/single.get.mjs +1 -1
  375. package/.output/server/chunks/routes/api/workshop/eda/index.get.mjs +1 -1
  376. package/.output/server/chunks/routes/api/workshop/eda/index.post.mjs +1 -1
  377. package/.output/server/chunks/routes/api/workshop/eda/index2.get.mjs +1 -1
  378. package/.output/server/chunks/routes/api/workshop/eda/index2.post.mjs +1 -1
  379. package/.output/server/chunks/routes/api/workshop/eda/index3.get.mjs +1 -1
  380. package/.output/server/chunks/routes/api/workshop/eda/index3.post.mjs +1 -1
  381. package/.output/server/chunks/routes/api/workshop/eda/index4.get.mjs +1 -1
  382. package/.output/server/chunks/routes/api/workshop/eda/index4.post.mjs +1 -1
  383. package/.output/server/chunks/routes/api/workshop/eda/index5.get.mjs +1 -1
  384. package/.output/server/chunks/routes/api/workshop/eda/index5.post.mjs +1 -1
  385. package/.output/server/chunks/routes/api/workshop/eda/index6.get.mjs +1 -1
  386. package/.output/server/chunks/routes/api/workshop/eda/index6.post.mjs +1 -1
  387. package/.output/server/chunks/routes/api/workshop/eda/index7.get.mjs +1 -1
  388. package/.output/server/chunks/routes/api/workshop/eda/index7.post.mjs +1 -1
  389. package/.output/server/chunks/routes/api/workshop/eda/index8.get.mjs +1 -1
  390. package/.output/server/chunks/routes/api/workshop/eda/index8.post.mjs +1 -1
  391. package/.output/server/chunks/routes/api/workshop/eda/ocap/_id_.get.mjs +1 -1
  392. package/.output/server/chunks/routes/api/workshop/eda/ocap/_id_.patch.mjs +1 -1
  393. package/.output/server/chunks/routes/api/workshop/eda/runs/_id/labels.patch.mjs +1 -1
  394. package/.output/server/chunks/routes/api/workshop/eda/runs.get.mjs +1 -1
  395. package/.output/server/chunks/routes/api/workshop/eda/spc/_id/recompute.post.mjs +1 -1
  396. package/.output/server/chunks/routes/api/workshop/eda/spc/_id_.delete.mjs +1 -1
  397. package/.output/server/chunks/routes/api/workshop/eda/spc/_id_.get.mjs +1 -1
  398. package/.output/server/chunks/routes/api/workshop/eda/templates/_id_.delete.mjs +1 -1
  399. package/.output/server/chunks/routes/api/workshop/eda/templates/_id_.get.mjs +1 -1
  400. package/.output/server/chunks/routes/api/workshop/eda/templates/_id_.patch.mjs +1 -1
  401. package/.output/server/chunks/routes/api/workshop/eda/vm/predict.post.mjs +1 -1
  402. package/.output/server/chunks/routes/api/workshop/exp/confirmations/_id/decide.post.mjs +1 -1
  403. package/.output/server/chunks/routes/api/workshop/exp/index.get.mjs +1 -1
  404. package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs +1 -1
  405. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +1 -1
  406. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +1 -1
  407. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +1 -1
  408. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +1 -1
  409. package/.output/server/chunks/routes/api/workshop/index.get.mjs +1 -1
  410. package/.output/server/chunks/routes/api/workshop/index.mjs +1 -1
  411. package/.output/server/chunks/routes/api/workshop/index.post.mjs +1 -1
  412. package/.output/server/chunks/routes/api/workshop/index.put.mjs +1 -1
  413. package/.output/server/chunks/routes/api/workshop/index10.get.mjs +1 -1
  414. package/.output/server/chunks/routes/api/workshop/index10.post.mjs +1 -1
  415. package/.output/server/chunks/routes/api/workshop/index11.get.mjs +1 -1
  416. package/.output/server/chunks/routes/api/workshop/index12.get.mjs +1 -1
  417. package/.output/server/chunks/routes/api/workshop/index13.get.mjs +1 -1
  418. package/.output/server/chunks/routes/api/workshop/index14.get.mjs +1 -1
  419. package/.output/server/chunks/routes/api/workshop/index15.get.mjs +1 -1
  420. package/.output/server/chunks/routes/api/workshop/index16.get.mjs +1 -1
  421. package/.output/server/chunks/routes/api/workshop/index2.get.mjs +1 -1
  422. package/.output/server/chunks/routes/api/workshop/index2.post.mjs +1 -1
  423. package/.output/server/chunks/routes/api/workshop/index3.get.mjs +1 -1
  424. package/.output/server/chunks/routes/api/workshop/index3.post.mjs +1 -1
  425. package/.output/server/chunks/routes/api/workshop/index4.get.mjs +1 -1
  426. package/.output/server/chunks/routes/api/workshop/index4.post.mjs +1 -1
  427. package/.output/server/chunks/routes/api/workshop/index5.get.mjs +1 -1
  428. package/.output/server/chunks/routes/api/workshop/index5.post.mjs +1 -1
  429. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +1 -1
  430. package/.output/server/chunks/routes/api/workshop/index6.post.mjs +1 -1
  431. package/.output/server/chunks/routes/api/workshop/index7.get.mjs +1 -1
  432. package/.output/server/chunks/routes/api/workshop/index7.post.mjs +1 -1
  433. package/.output/server/chunks/routes/api/workshop/index8.get.mjs +1 -1
  434. package/.output/server/chunks/routes/api/workshop/index8.post.mjs +1 -1
  435. package/.output/server/chunks/routes/api/workshop/index9.get.mjs +1 -1
  436. package/.output/server/chunks/routes/api/workshop/index9.post.mjs +1 -1
  437. package/.output/server/chunks/routes/api/workshop/mailbox/all.get.mjs +1 -1
  438. package/.output/server/chunks/routes/api/workshop/mailbox.get.mjs +1 -1
  439. package/.output/server/chunks/routes/api/workshop/memories/maintenance.post.mjs +1 -1
  440. package/.output/server/chunks/routes/api/workshop/mes/datasets.get.mjs +1 -1
  441. package/.output/server/chunks/routes/api/workshop/mes/index.get.mjs +1 -1
  442. package/.output/server/chunks/routes/api/workshop/mes/index.put.mjs +1 -1
  443. package/.output/server/chunks/routes/api/workshop/mes/points.get.mjs +1 -1
  444. package/.output/server/chunks/routes/api/workshop/mes/preview.post.mjs +1 -1
  445. package/.output/server/chunks/routes/api/workshop/mes/secrets/_ref_.delete.mjs +1 -1
  446. package/.output/server/chunks/routes/api/workshop/notifications/read.post.mjs +1 -1
  447. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/autofix.mjs +1 -1
  448. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/compile.mjs +1 -1
  449. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/evidence.mjs +1 -1
  450. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/publish.mjs +1 -1
  451. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/rules/_ruleId/approval-decision.mjs +1 -1
  452. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/rules/_ruleId/approval.mjs +1 -1
  453. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/rules/_ruleId/transition.mjs +1 -1
  454. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/subgraph.mjs +1 -1
  455. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/validate.mjs +1 -1
  456. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId_.mjs +1 -1
  457. package/.output/server/chunks/routes/api/workshop/ontology/export/_ontologyId_.mjs +1 -1
  458. package/.output/server/chunks/routes/api/workshop/ontology/index.mjs +1 -1
  459. package/.output/server/chunks/routes/api/workshop/ontology/scene.mjs +1 -1
  460. package/.output/server/chunks/routes/api/workshop/ontology/traces/_ontologyId_.mjs +1 -1
  461. package/.output/server/chunks/routes/api/workshop/ontology/versions/_ontologyId/compare.mjs +1 -1
  462. package/.output/server/chunks/routes/api/workshop/ontology/versions/_ontologyId_.mjs +1 -1
  463. package/.output/server/chunks/routes/api/workshop/optimization/bindings/_id_.delete.mjs +1 -1
  464. package/.output/server/chunks/routes/api/workshop/optimization/capabilities.get.mjs +1 -1
  465. package/.output/server/chunks/routes/api/workshop/optimization/index.get.mjs +1 -1
  466. package/.output/server/chunks/routes/api/workshop/optimization/index.mjs +1 -1
  467. package/.output/server/chunks/routes/api/workshop/optimization/index2.mjs +1 -1
  468. package/.output/server/chunks/routes/api/workshop/optimization/profiles/_id/publish.post.mjs +1 -1
  469. package/.output/server/chunks/routes/api/workshop/optimization/recommendations/_id/crosscheck.post.mjs +1 -1
  470. package/.output/server/chunks/routes/api/workshop/optimization/recommendations/_id/dispatch.post.mjs +1 -1
  471. package/.output/server/chunks/routes/api/workshop/optimization/solve.post.mjs +1 -1
  472. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +1 -1
  473. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +1 -1
  474. package/.output/server/chunks/routes/api/workshop/plugins/index.get.mjs +1 -1
  475. package/.output/server/chunks/routes/api/workshop/process-model/datasets.post.mjs +1 -1
  476. package/.output/server/chunks/routes/api/workshop/process-model/eligibility.mjs +1 -1
  477. package/.output/server/chunks/routes/api/workshop/process-model/experiments.mjs +305 -20
  478. package/.output/server/chunks/routes/api/workshop/process-model/experiments.mjs.map +1 -1
  479. package/.output/server/chunks/routes/api/workshop/process-model/index.mjs +1 -1
  480. package/.output/server/chunks/routes/api/workshop/process-model/specs/_id/publish.post.mjs +1 -1
  481. package/.output/server/chunks/routes/api/workshop/process-model/train.post.mjs +1 -1
  482. package/.output/server/chunks/routes/api/workshop/runtime.get.mjs +1 -1
  483. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +1 -1
  484. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +1 -1
  485. package/.output/server/chunks/routes/api/workshop/scene/layouts.get.mjs +1 -1
  486. package/.output/server/chunks/routes/api/workshop/schedules/_id/run.post.mjs +1 -1
  487. package/.output/server/chunks/routes/api/workshop/schedules/_id/runs.get.mjs +1 -1
  488. package/.output/server/chunks/routes/api/workshop/schedules/_id_.delete.mjs +1 -1
  489. package/.output/server/chunks/routes/api/workshop/schedules/_id_.get.mjs +1 -1
  490. package/.output/server/chunks/routes/api/workshop/schedules/_id_.patch.mjs +1 -1
  491. package/.output/server/chunks/routes/api/workshop/tasks/_id/complete.post.mjs +1 -1
  492. package/.output/server/chunks/routes/api/workshop/tasks/_id/dispatch.post.mjs +1 -1
  493. package/.output/server/chunks/routes/api/workshop/tasks/_id/index.post.mjs +1 -1
  494. package/.output/server/chunks/routes/api/workshop/tasks/_id/reassign.post.mjs +1 -1
  495. package/.output/server/chunks/routes/api/workshop/tasks/_id/reopen.post.mjs +1 -1
  496. package/.output/server/chunks/routes/api/workshop/tasks/_id/report.post.mjs +1 -1
  497. package/.output/server/chunks/routes/api/workshop/tasks/_id/retry.post.mjs +1 -1
  498. package/.output/server/chunks/routes/api/workshop/tasks/_id/supersede.post.mjs +1 -1
  499. package/.output/server/chunks/routes/api/workshop/tasks/_id/update.post.mjs +1 -1
  500. package/.output/server/chunks/routes/api/workshop/tasks/_id_.get.mjs +1 -1
  501. package/.output/server/chunks/routes/api/workshop/tasks.get.mjs +1 -1
  502. package/.output/server/chunks/routes/api/workshop/teams/_id/deploy.post.mjs +1 -1
  503. package/.output/server/chunks/routes/api/workshop/teams/_id/index.get.mjs +1 -1
  504. package/.output/server/chunks/routes/api/workshop/teams/_id/index.post.mjs +1 -1
  505. package/.output/server/chunks/routes/api/workshop/teams/_id/index.put.mjs +1 -1
  506. package/.output/server/chunks/routes/api/workshop/teams/_id/index2.get.mjs +1 -1
  507. package/.output/server/chunks/routes/api/workshop/teams/_id/members/_agentId_.delete.mjs +1 -1
  508. package/.output/server/chunks/routes/api/workshop/teams/_id_.delete.mjs +1 -1
  509. package/.output/server/chunks/routes/api/workshop/teams/_id_.get.mjs +1 -1
  510. package/.output/server/chunks/routes/api/workshop/teams/_id_.patch.mjs +1 -1
  511. package/.output/server/chunks/routes/api/workshop/tools/_name_.get.mjs +1 -1
  512. package/.output/server/chunks/routes/api/workshop/tools/sync.post.mjs +1 -1
  513. package/.output/server/chunks/routes/api/workshop/users/me.get.mjs +1 -1
  514. package/.output/server/chunks/routes/api/workshop/users/register.post.mjs +1 -1
  515. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +2 -2
  516. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.delete.mjs +1 -1
  517. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.post.mjs +1 -1
  518. package/.output/server/chunks/routes/api/workshop/workspaces/index.delete.mjs +1 -1
  519. package/.output/server/chunks/routes/renderer.mjs +2 -2
  520. package/.output/server/chunks/virtual/entry.mjs +5 -1
  521. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  522. package/.output/server/index.mjs +1 -1
  523. package/.output/server/package.json +1 -1
  524. package/README-zh.md +3 -3
  525. package/README.md +3 -3
  526. package/config.yml +1 -1
  527. package/docs/aml.md +112 -112
  528. package/docs/cli.en.md +4 -4
  529. package/docs/cli.md +3 -3
  530. package/docs/plugins.en.md +1 -1
  531. package/docs/plugins.md +1 -1
  532. package/docs/sdk.en.md +1 -1
  533. package/docs/sdk.md +1 -1
  534. package/i18n/locales/en.ts +2 -0
  535. package/i18n/locales/zh-CN.ts +2 -0
  536. package/package.json +1 -1
  537. package/scripts/_audit/demo-shot-studio.mjs +37 -0
  538. package/scripts/_audit/demo-shots.mjs +38 -0
  539. package/scripts/_audit/gen-demo-report.py +69 -0
  540. package/scripts/_audit/mqtt-pub.mjs +13 -0
  541. package/scripts/_audit/mqtt-topic-probe.mjs +15 -0
  542. package/scripts/_audit/proto-b3-device-4021.mjs +90 -0
  543. package/scripts/_audit/proto-doc-device-4120.mjs +53 -0
  544. package/scripts/acceptance-scientific-loop.ts +224 -0
  545. package/scripts/generate-identifiability-fixtures.ts +98 -0
  546. package/server/api/workshop/process-model/experiments.ts +28 -2
  547. package/server/plugins-builtin/diag-bridge/host/plugin.mjs +759 -753
  548. package/server/plugins-builtin/rag-bridge/index.mjs +490 -484
  549. package/server/repositories/user.repository.ts +24 -1
  550. package/server/services/user.service.ts +8 -6
  551. package/server/services/workshop/agents/host-tool-bridge/catalog.ts +2 -0
  552. package/server/services/workshop/agents/host-tool-bridge/tools/industrial.ts +4 -1
  553. package/server/services/workshop/agents/host-tool-bridge/tools/messaging.ts +5 -1
  554. package/server/services/workshop/agents/industrial/aml-dataset-tools.ts +3 -0
  555. package/server/services/workshop/agents/industrial/bench-approval-only.ts +335 -58
  556. package/server/services/workshop/agents/industrial/dcw-tools.ts +7 -1
  557. package/server/services/workshop/agents/industrial/identifiability-tools.ts +247 -0
  558. package/server/services/workshop/agents/industrial/index.ts +1 -0
  559. package/server/services/workshop/agents/industrial/manual-approval.ts +3 -1
  560. package/server/services/workshop/agents/industrial/ops-tools.ts +58 -15
  561. package/server/services/workshop/agents/industrial/optimization-tools.ts +33 -19
  562. package/server/services/workshop/agents/plugin-governance.ts +22 -2
  563. package/server/services/workshop/aml/action-coverage.ts +253 -0
  564. package/server/services/workshop/aml/causal-claim.ts +68 -0
  565. package/server/services/workshop/aml/dataset-builder.ts +19 -0
  566. package/server/services/workshop/aml/gates.ts +45 -1
  567. package/server/services/workshop/aml/identifiability.ts +335 -0
  568. package/server/services/workshop/aml/intervention-ledger.ts +281 -0
  569. package/server/services/workshop/aml/ontology-learning.ts +143 -0
  570. package/server/services/workshop/aml/twin/cross-check.ts +176 -0
  571. package/server/services/workshop/daq/daq-controller/contracts.ts +3 -0
  572. package/server/services/workshop/daq/daq-controller/crud.ts +12 -2
  573. package/server/services/workshop/daq/daq-controller/push.ts +22 -0
  574. package/server/services/workshop/daq/drivers/mqtt.ts +28 -0
  575. package/server/services/workshop/daq/drivers/shared.ts +6 -0
  576. package/server/services/workshop/db/database/open.ts +2 -0
  577. package/server/services/workshop/db/database/rows.ts +4 -1
  578. package/server/services/workshop/db/database/schema.ts +38 -2
  579. package/server/services/workshop/db/message.repo.ts +10 -3
  580. package/server/services/workshop/dcw/dcw-controller/write-audit.ts +21 -1
  581. package/server/services/workshop/process-model/experiment-runner.ts +393 -0
  582. package/server/services/workshop/process-model/experiment.ts +25 -10
  583. package/server/services/workshop/runtime/agent-runtime/lifecycle.ts +34 -11
  584. package/server/services/workshop/runtime/agent-runtime/state.ts +6 -1
  585. package/server/services/workshop/settings.ts +4 -1
  586. package/server/services/workshop/types/a2a.ts +16 -1
  587. package/shared/config/schema.json +2 -0
  588. package/shared/dcw-protocol/closed-loop.ts +2 -0
  589. package/.output/public/_nuxt/builds/meta/1231252d-2864-43c0-83b2-4e70d3b86dea.json +0 -1
@@ -1,7 +1,8 @@
1
1
  import { existsSync } from 'node:fs'
2
2
  import { backupRegistry } from '../services/workshop/db/backup-registry'
3
3
  import { join, resolve } from 'node:path'
4
- import { randomBytes, randomUUID, scryptSync, createHash, timingSafeEqual } from 'node:crypto'
4
+ import { randomBytes, randomUUID, scryptSync, createHash, timingSafeEqual, scrypt as scryptAsync } from 'node:crypto'
5
+ import { promisify } from 'node:util'
5
6
  import { DatabaseSync } from 'node:sqlite'
6
7
  import { ensureDataDir } from '@/shared/config/home.mjs'
7
8
  import type { Paginated, User, UserListQuery, UserToken } from '../types/user'
@@ -181,6 +182,28 @@ export function verifyPassword(password: string, stored: string): boolean {
181
182
  return expected.length === actual.length && timingSafeEqual(expected, actual)
182
183
  }
183
184
 
185
+ // ===== P2-9(2026-11-01):异步 scrypt 变体 =====
186
+ // 热路径(登录/改密校验)走 worker 线程池(scrypt 回调),不再阻塞事件循环 ——
187
+ // 单次 ~50-100ms 的 CPU 阻塞在并发登录时会排队放大为秒级卡顿(验收计划 P2-9)。
188
+ // 管理面低频路径(创建/改密写入)保留同步版:调用点在同步 SQLite 事务链上,
189
+ // 异步化会外溢到仓库 API 形状(18+ 点),收益/风险比不划算 —— 显式记录为设计取舍。
190
+
191
+ const scryptP = promisify(scryptAsync) as (p: string, s: string, l: number) => Promise<Buffer>
192
+
193
+ /** 异步校验密码(登录/改密热路径专用;语义与 verifyPassword 完全一致) */
194
+ export async function verifyPasswordAsync(password: string, stored: string): Promise<boolean> {
195
+ const [salt, hex] = stored.split(':')
196
+ if (!salt || !hex) return false
197
+ const expected = Buffer.from(hex, 'hex')
198
+ try {
199
+ const actual = await scryptP(password, salt, expected.length)
200
+ return expected.length === actual.length && timingSafeEqual(expected, actual)
201
+ }
202
+ catch {
203
+ return false
204
+ }
205
+ }
206
+
184
207
  // ===== Token 哈希 =====
185
208
 
186
209
  function hashToken(token: string): string {
@@ -1,4 +1,4 @@
1
- import { userRepository, findByToken, verifyPassword } from '../repositories/user.repository'
1
+ import { userRepository, findByToken, verifyPasswordAsync } from '../repositories/user.repository'
2
2
  import type { UserListInput, UserListQuery, UserToken, AuthResult } from '../types/user'
3
3
  import type { UserCreate, UserUpdate, UserLogin, UserRegister } from '../schemas/user.schema'
4
4
  import { AppError, ErrorCodes } from '../utils/errors'
@@ -100,14 +100,15 @@ export const userService = {
100
100
  return { id, revokedSessions: revoked, mustChangePassword: true }
101
101
  },
102
102
 
103
- /** 本人修改密码(首登强制改密同一入口):当前密码验证 → 更新哈希并清除强制标记 */
104
- changePassword(userId: string, currentPassword: string, newPassword: string) {
103
+ /** 本人修改密码(首登强制改密同一入口):当前密码验证 → 更新哈希并清除强制标记。
104
+ * P2-9(2026-11-01):校验走异步 scrypt(worker 线程池),不再阻塞事件循环。 */
105
+ async changePassword(userId: string, currentPassword: string, newPassword: string) {
105
106
  const user = userRepository.findById(userId)
106
107
  if (!user) {
107
108
  throw new AppError(404, ErrorCodes.NOT_FOUND, '用户不存在')
108
109
  }
109
110
  const { hash } = userRepository.getPasswordHash(user.email) ?? {}
110
- if (!hash || !verifyPassword(currentPassword, hash)) {
111
+ if (!hash || !(await verifyPasswordAsync(currentPassword, hash))) {
111
112
  throw new AppError(401, 'UNAUTHORIZED', '当前密码不正确')
112
113
  }
113
114
  userRepository.update(userId, { password: newPassword, mustChangePassword: false })
@@ -150,7 +151,7 @@ export const userService = {
150
151
  * - 密码错误时累计,达阈值返回 429 统一文案(不泄露"账号是否存在");
151
152
  * - IP 只入审计(来源可追溯),不参与判定。
152
153
  */
153
- login(input: UserLogin, opts: { ip?: string } = {}): AuthResult {
154
+ async login(input: UserLogin, opts: { ip?: string } = {}): Promise<AuthResult> {
154
155
  const FAIL_WINDOW_MS = 15 * 60_000
155
156
  const LOCK_THRESHOLD = 5
156
157
  const accountKey = input.email.trim().toLowerCase()
@@ -163,7 +164,8 @@ export const userService = {
163
164
  const locked = Boolean(rec && rec.count >= LOCK_THRESHOLD && Date.now() - rec.firstAt < FAIL_WINDOW_MS)
164
165
 
165
166
  const { id, hash } = userRepository.getPasswordHash(input.email) ?? {}
166
- const passwordOk = Boolean(id && hash && verifyPassword(input.password, hash))
167
+ // P2-9(2026-11-01):登录校验走异步 scrypt —— 并发登录不再排队阻塞事件循环
168
+ const passwordOk = Boolean(id && hash && await verifyPasswordAsync(input.password, hash))
167
169
  if (!passwordOk) {
168
170
  if (!rec || Date.now() - rec.firstAt >= FAIL_WINDOW_MS) fails.set(accountKey, { count: 1, firstAt: Date.now() })
169
171
  else rec.count += 1
@@ -73,6 +73,8 @@ export const OBSERVER_READ_TOOL_NAMES = new Set([
73
73
  'line_context',
74
74
  'dcw_journal',
75
75
  'daq_query',
76
+ 'daq_identifiability',
77
+ 'intervention_history',
76
78
  'exp_collect',
77
79
  'analysis_save',
78
80
  'analysis_query',
@@ -9,7 +9,7 @@
9
9
  * 该族**不依赖 workspace**,由 dispatch 在 workspace 门控之前分流(保持原分发顺序)。
10
10
  */
11
11
  import type { HostToolResult } from '../types'
12
- import { toolLineStart, toolLineStop, toolLineStatus, toolAmlDatasetBuild, toolAmlDatasetStats, toolAmlJobCancel, toolAmlJobLogs, toolAmlJobStatus, toolAmlJobSubmit, toolAmlLeaderboard, toolAmlModelFind, toolAmlModelPromote, toolAmlModelReference, toolAmlModelAnnotate, toolAmlNodeCatalog, toolAmlTrainingPlanCreate, toolAmlTrainingPlanList, toolAmlTrainingPlanTrain, toolDaqExport, toolDaqFrames, toolDaqQuery, toolDcwControl, toolDcwJudge, toolDcwJournal, toolDcwRollback, toolLineContext, toolMesCatalog, toolMesDatasetRead, toolMesDatasets, toolMesExport, toolMesFetch, toolMyIndustrialNodes, toolOpsLog, toolParamControl, toolRecipeApply, toolRecipeCatalog, toolRecipeCreate, toolRecipeLog, toolRecipeRollback, toolRecipeTrial, toolRecipeUpdate, toolRecipeVersions, toolOptimizationExplore, toolTwinProviderCatalog, toolTwinSceneDiscover, toolTwinSceneCompile, toolTwinSceneFreeze, toolTwinSceneRead, toolTwinPhysicsSpecDraft, toolTwinPhysicsSpecValidate, toolTwinPhysicsSpecCompile, toolTwinSnapshotCreate, toolTwinTrialRun, toolMpcOptimize, toolTwinGateEvaluate, toolTwinBayesOptimize, toolTwinCalibrationRequest, toolAnalysisSave, toolAnalysisQuery } from '../../industrial'
12
+ import { toolLineStart, toolLineStop, toolLineStatus, toolAmlDatasetBuild, toolAmlDatasetStats, toolAmlJobCancel, toolAmlJobLogs, toolAmlJobStatus, toolAmlJobSubmit, toolAmlLeaderboard, toolAmlModelFind, toolAmlModelPromote, toolAmlModelReference, toolAmlModelAnnotate, toolAmlNodeCatalog, toolAmlTrainingPlanCreate, toolAmlTrainingPlanList, toolAmlTrainingPlanTrain, toolDaqExport, toolDaqFrames, toolDaqQuery, toolDcwControl, toolDcwJudge, toolDcwJournal, toolDcwRollback, toolLineContext, toolMesCatalog, toolMesDatasetRead, toolMesDatasets, toolMesExport, toolMesFetch, toolMyIndustrialNodes, toolOpsLog, toolParamControl, toolRecipeApply, toolRecipeCatalog, toolRecipeCreate, toolRecipeLog, toolRecipeRollback, toolRecipeTrial, toolRecipeUpdate, toolRecipeVersions, toolOptimizationExplore, toolDaqIdentifiability, toolInterventionHistory, toolTwinProviderCatalog, toolTwinSceneDiscover, toolTwinSceneCompile, toolTwinSceneFreeze, toolTwinSceneRead, toolTwinPhysicsSpecDraft, toolTwinPhysicsSpecValidate, toolTwinPhysicsSpecCompile, toolTwinSnapshotCreate, toolTwinTrialRun, toolMpcOptimize, toolTwinGateEvaluate, toolTwinBayesOptimize, toolTwinCalibrationRequest, toolAnalysisSave, toolAnalysisQuery } from '../../industrial'
13
13
 
14
14
  import { toolExpCollect } from '../../industrial/exp-tools'
15
15
  import { toolRecipePropose } from '../../industrial/recipe-propose-tools'
@@ -60,6 +60,9 @@ const INDUSTRIAL_HANDLERS = new Map<string, IndustrialToolHandler>([
60
60
  ['daq_query', (agentId, args) => toolDaqQuery(agentId, args as Parameters<typeof toolDaqQuery>[1])],
61
61
  ['daq_export', (agentId, args) => toolDaqExport(agentId, args as Parameters<typeof toolDaqExport>[1])],
62
62
  ['daq_frames', (agentId, args) => toolDaqFrames(agentId, args as Parameters<typeof toolDaqFrames>[1])],
63
+ // P1/P2(科学探索计划):可辨识性预检与干预台账查询(全只读)
64
+ ['daq_identifiability', (agentId, args) => toolDaqIdentifiability(agentId, args as Parameters<typeof toolDaqIdentifiability>[1])],
65
+ ['intervention_history', (agentId, args) => toolInterventionHistory(agentId, args as Parameters<typeof toolInterventionHistory>[1])],
63
66
  ['dcw_judge', (agentId, args) => toolDcwJudge(agentId, args as { record_id?: string, verdict?: string, reason?: string })],
64
67
  ['dcw_rollback', (agentId, args) => toolDcwRollback(agentId, args as { record_id?: string, node_id?: string, to?: string })],
65
68
  ['dcw_journal', (agentId, args) => toolDcwJournal(agentId, args as { node_id?: string, recipe_id?: string, limit?: number | string })],
@@ -6,6 +6,7 @@
6
6
  import type { AgentWorkspace } from '../../agent-interface'
7
7
  import type { HostToolBridgeContext, HostToolResult, HostToolSessionState } from '../types'
8
8
  import { partsToText } from '../session'
9
+ import { isHumanChatDelivery } from '../../../types/a2a'
9
10
 
10
11
  export async function handleSendMessageToAgent(
11
12
  args: Record<string, unknown>,
@@ -119,7 +120,10 @@ export async function handlePollMessages(
119
120
  ): Promise<HostToolResult> {
120
121
  const limit = (args.limit as number | undefined) ?? 10
121
122
  const waitSec = Math.min(180, Math.max(0, Number(args.wait_seconds ?? 0) || 0))
122
- const msgs = await ws.waitMailbox(limit, waitSec * 1000)
123
+ // 双保险:运行时 waitPending 已排除人类群聊投递;此处再滤一次,防止旧元数据/回退路径
124
+ // 把需要 platformReply 回写群聊的消息读走(读即取后用户将收不到答复)。
125
+ const msgs = (await ws.waitMailbox(limit, waitSec * 1000))
126
+ .filter(m => !isHumanChatDelivery(m))
123
127
  if (msgs.length === 0) {
124
128
  return {
125
129
  text: waitSec > 0
@@ -302,6 +302,9 @@ export async function toolAmlDatasetStats(_agentId: string, args: { dataset_id?:
302
302
  ` 三元组: ${dataset.lineId} / ${dataset.productId} / ${dataset.recipeId} | 行数 ${dataset.rowCount} | 批次 ${dataset.runIds.length}(${report.runsUsed.length} 参与构建)| 创建 ${dataset.createdAt.slice(0, 19).replace('T', ' ')}`,
303
303
  statLines.length ? `\n逐节点统计(train 切分):\n${statLines.join('\n')}` : null,
304
304
  lagLines.length ? `\n控制→目标滞后(互相关峰值,正 = 控制领先):\n${lagLines.join('\n')}` : null,
305
+ (report.actionCoverage ?? []).length
306
+ ? `\n动作覆盖(role=control;G6 门依据 —— 水平<3 或与时间共线则模型学不到动作):\n${(report.actionCoverage ?? []).map(c => `- ${amlNodeName(c.controlId)}(${c.controlId}):水平 ${c.distinctLevels} 个,切换 ${c.stepCount} 次,时间共线 |r|=${c.collinearityWithTime.toFixed(3)},贴边 ${(c.saturationRatio * 100).toFixed(0)}%${c.levelPhaseMatrix.length ? `;水平×时间 {${c.levelPhaseMatrix.map(l => `${l.level}@${(l.meanPhase * 100).toFixed(0)}%`).join(', ')}}` : ''}`).join('\n')}`
307
+ : null,
305
308
  profileLines.length ? `\nrun 轮廓(逐批次目标均值,漂移检测):\n${profileLines.join('\n')}` : null,
306
309
  `\n窗口计数:train ${report.windowCount.train} / val ${report.windowCount.val} / test ${report.windowCount.test}(byRun 分层切分,防同批泄漏)`,
307
310
  report.runsDropped.length > 0 ? `丢弃批次:\n${report.runsDropped.map(d => `- ${d.runId}: ${d.reason}`).join('\n')}` : null,
@@ -1,12 +1,19 @@
1
1
  import { execFileSync } from 'node:child_process'
2
2
  import { createHash } from 'node:crypto'
3
- import { lstatSync, readFileSync, realpathSync } from 'node:fs'
3
+ import { closeSync, fsyncSync, lstatSync, openSync, readFileSync, realpathSync, rmSync, writeFileSync } from 'node:fs'
4
+ import { networkInterfaces } from 'node:os'
4
5
  import { basename, dirname, isAbsolute, join, resolve } from 'node:path'
5
6
 
6
7
  type TrialTarget = { id: string, driver: string, driverConfig: Record<string, unknown> }
8
+ type TrialParam = { node_id: string, value: number }
9
+ type PilotArm = 'ON' | 'OFF'
10
+ type PilotCase = 'legal-approved' | 'legal-rejected' | 'out-of-range-approved'
7
11
  type Qualification = {
8
- schema_version: number
12
+ schema_version: 2
9
13
  run_id: string
14
+ episode_id: string
15
+ arm: 'OFF'
16
+ case: PilotCase
10
17
  aw_home: string
11
18
  aw_base: string
12
19
  sim_base: string
@@ -14,11 +21,86 @@ type Qualification = {
14
21
  simulator_pid: number
15
22
  line_id: string
16
23
  recipe_id: string
24
+ actor_id: string
25
+ hypothesis: string
26
+ params: TrialParam[]
27
+ configuration_sha256: string
28
+ fixture_sha256: string
29
+ manifest_sha256: string
17
30
  expires_at_utc: string
18
31
  nodes: Array<{ node_id: string, driver: string, driver_config_sha256: string, host?: string, port?: number }>
19
32
  }
20
33
 
21
- export type ApprovalOnlyTrialReceipt = { approval_bypassed: true, run_id: string }
34
+ type Manifest = {
35
+ schema_version: 'a1-approval-pilot-v1'
36
+ run_id: string
37
+ study_type: 'descriptive-pilot'
38
+ configuration_sha256: string
39
+ network_isolation: { mode: 'docker-network-none', loopback_only: true }
40
+ episodes: Array<{
41
+ episode_id: string
42
+ case: PilotCase
43
+ arm_order: PilotArm[]
44
+ actor_id: string
45
+ line_id: string
46
+ recipe_id: string
47
+ hypothesis: string
48
+ params: TrialParam[]
49
+ fixture_sha256: string
50
+ }>
51
+ }
52
+
53
+ export type ApprovalOnlyTrialReceipt = {
54
+ approval_bypassed: true
55
+ run_id: string
56
+ episode_id: string
57
+ arm: 'OFF'
58
+ case: PilotCase
59
+ invocation_id: string
60
+ configuration_sha256: string
61
+ fixture_sha256: string
62
+ }
63
+
64
+ type TrialCheckInput = {
65
+ stage: 'approval' | 'dispatch'
66
+ invocationId: string
67
+ actorId: string
68
+ recipeId: string
69
+ line: { id: string, simulated?: boolean } | undefined
70
+ nodes: TrialTarget[]
71
+ hypothesis: string
72
+ params: TrialParam[]
73
+ }
74
+
75
+ function sha256(value: string | Buffer): string {
76
+ return createHash('sha256').update(value).digest('hex')
77
+ }
78
+
79
+ function stableJson(value: unknown): string {
80
+ if (Array.isArray(value)) return `[${value.map(stableJson).join(',')}]`
81
+ if (value && typeof value === 'object') {
82
+ return `{${Object.entries(value as Record<string, unknown>).sort(([a], [b]) => a.localeCompare(b)).map(([key, item]) => `${JSON.stringify(key)}:${stableJson(item)}`).join(',')}}`
83
+ }
84
+ return JSON.stringify(value) ?? 'null'
85
+ }
86
+
87
+ /** Digest of the exact actor, recipe, target driver configuration, candidate and rationale. */
88
+ export function approvalOnlyFixtureSha256(input: Omit<TrialCheckInput, 'stage' | 'invocationId'>): string {
89
+ const projection = {
90
+ schema_version: 1,
91
+ actor_id: input.actorId,
92
+ line_id: input.line?.id ?? '',
93
+ recipe_id: input.recipeId,
94
+ hypothesis: input.hypothesis,
95
+ params: input.params.map(param => ({ node_id: param.node_id, value: Number(param.value) })).sort((a, b) => a.node_id.localeCompare(b.node_id)),
96
+ nodes: input.nodes.map(node => ({
97
+ node_id: node.id,
98
+ driver: node.driver,
99
+ driver_config_sha256: sha256(stableJson(node.driverConfig)),
100
+ })).sort((a, b) => a.node_id.localeCompare(b.node_id)),
101
+ }
102
+ return sha256(stableJson(projection))
103
+ }
22
104
 
23
105
  function loopbackUrl(raw: string | undefined, label: string): URL {
24
106
  const url = new URL(raw ?? '')
@@ -29,8 +111,7 @@ function loopbackUrl(raw: string | undefined, label: string): URL {
29
111
  return url
30
112
  }
31
113
 
32
- function targetEndpoint(node: TrialTarget): { host: string, port: number } | null {
33
- if (node.driver === 'mock') return null
114
+ function targetEndpoint(node: TrialTarget): { host: string, port: number } {
34
115
  let host: string
35
116
  let port: number
36
117
  if (node.driver === 'opcua') {
@@ -39,7 +120,7 @@ function targetEndpoint(node: TrialTarget): { host: string, port: number } | nul
39
120
  host = endpoint.hostname
40
121
  port = Number(endpoint.port)
41
122
  }
42
- else if (node.driver === 'modbus-tcp' || node.driver === 'modbus-rtu') {
123
+ else if (node.driver === 'modbus-tcp') {
43
124
  host = String(node.driverConfig.host ?? '')
44
125
  port = Number(node.driverConfig.port)
45
126
  }
@@ -51,65 +132,261 @@ function targetEndpoint(node: TrialTarget): { host: string, port: number } | nul
51
132
  }
52
133
 
53
134
  function assertListener(port: number, pid: number): void {
54
- const rows = execFileSync('netstat.exe', ['-ano', '-p', 'tcp'], { encoding: 'utf8', timeout: 8000, maxBuffer: 4 * 1024 * 1024 })
55
- .split(/\r?\n/).map(line => line.trim().split(/\s+/))
56
- .filter(parts => parts[0] === 'TCP' && parts[3]?.toUpperCase() === 'LISTENING' && parts[1]?.endsWith(`:${port}`))
57
- if (!rows.length || rows.some(parts => Number(parts[4]) !== pid || !['127.0.0.1', '[::1]'].includes(parts[1]!.slice(0, -(String(port).length + 1))))) {
58
- throw new Error(`simulator ownership or loopback binding is unverified for port ${port}`)
135
+ if (process.platform === 'win32') {
136
+ const rows = execFileSync('netstat.exe', ['-ano', '-p', 'tcp'], { encoding: 'utf8', timeout: 8000, maxBuffer: 4 * 1024 * 1024 })
137
+ .split(/\r?\n/).map(line => line.trim().split(/\s+/))
138
+ .filter(parts => parts[0] === 'TCP' && parts[3]?.toUpperCase() === 'LISTENING' && parts[1]?.endsWith(`:${port}`))
139
+ if (!rows.length || rows.some(parts => Number(parts[4]) !== pid || !['127.0.0.1', '[::1]'].includes(parts[1]!.slice(0, -(String(port).length + 1))))) {
140
+ throw new Error(`listener ownership or loopback binding is unverified for port ${port}`)
141
+ }
142
+ return
143
+ }
144
+ if (process.platform !== 'linux') throw new Error('listener ownership verification is supported only on Windows or Linux')
145
+ const output = execFileSync('ss', ['-ltnpH'], { encoding: 'utf8', timeout: 8000, maxBuffer: 4 * 1024 * 1024 })
146
+ const matching = output.split(/\r?\n/).filter(line => line.trim().split(/\s+/)[3]?.endsWith(`:${port}`))
147
+ if (!matching.length || matching.some((line) => {
148
+ const parts = line.trim().split(/\s+/)
149
+ const local = parts[3]?.slice(0, -(String(port).length + 1))
150
+ const owners = [...line.matchAll(/pid=(\d+)/g)].map(match => Number(match[1]))
151
+ return !['127.0.0.1', '[::1]'].includes(local ?? '') || owners.length !== 1 || owners[0] !== pid
152
+ })) {
153
+ throw new Error(`listener ownership or loopback binding is unverified for port ${port}`)
59
154
  }
60
155
  }
61
156
 
62
- /** This switch has no tool argument or UI setting. Its qualification file stays in
63
- * the disposable AW_HOME and must be renewed for each run before bypassing HITL. */
64
- export function approvalOnlyTrialReceipt(input: {
65
- recipeId: string
66
- line: { id: string, simulated?: boolean } | undefined
67
- nodes: TrialTarget[]
68
- }): ApprovalOnlyTrialReceipt | null {
157
+ export function assertLoopbackOnlyNetworkNamespace(interfaces: ReturnType<typeof networkInterfaces>): void {
158
+ if (process.platform !== 'linux') throw new Error('approval-only trials require a Linux network namespace with verified no-egress isolation')
159
+ const names = Object.keys(interfaces)
160
+ const loopbackAddresses = interfaces.lo ?? []
161
+ if (names.length !== 1 || names[0] !== 'lo' || loopbackAddresses.length === 0
162
+ || loopbackAddresses.some(address => !address?.internal || !['127.0.0.1', '::1'].includes(address.address))) {
163
+ throw new Error('approval-only trials require a loopback-only network namespace')
164
+ }
165
+ const routes = readFileSync('/proc/net/route', 'utf8').trim().split(/\r?\n/).slice(1)
166
+ if (routes.some((line) => {
167
+ const parts = line.trim().split(/\s+/)
168
+ return parts[1] === '00000000' && parts[0] !== 'lo'
169
+ })) throw new Error('approval-only network namespace has an IPv4 default route via a non-loopback interface')
170
+ const routes6 = readFileSync('/proc/net/ipv6_route', 'utf8').trim().split(/\r?\n/)
171
+ if (routes6.some((line) => {
172
+ const parts = line.trim().split(/\s+/)
173
+ return /^0{32}$/.test(parts[1] ?? '') && parts[2] === '00' && parts[0] !== 'lo'
174
+ })) {
175
+ throw new Error('approval-only network namespace has an IPv6 default route via a non-loopback interface')
176
+ }
177
+ }
178
+
179
+ function configurationSha256(configuration: Record<string, unknown>): string {
180
+ const projection = { ...configuration }
181
+ delete projection.configuration_sha256
182
+ return sha256(stableJson(projection))
183
+ }
184
+
185
+ function readRegularJson(path: string, label: string): { value: Record<string, unknown>, bytes: Buffer } {
186
+ const stat = lstatSync(path)
187
+ if (!stat.isFile() || stat.isSymbolicLink()) throw new Error(`${label} must be a regular non-symlink file`)
188
+ const bytes = readFileSync(path)
189
+ return { value: JSON.parse(bytes.toString('utf8')) as Record<string, unknown>, bytes }
190
+ }
191
+
192
+ function readClaim(path: string): Record<string, unknown> {
193
+ return readRegularJson(path, 'approval-only one-shot claim').value
194
+ }
195
+
196
+ function withClaimLock<T>(home: string, callback: () => T): T {
197
+ const lockPath = join(home, 'approval-only-claim.lock')
198
+ let fd: number
199
+ try {
200
+ fd = openSync(lockPath, 'wx', 0o600)
201
+ }
202
+ catch (err) {
203
+ throw new Error(`approval-only qualification is busy or has a stale lock: ${err instanceof Error ? err.message : String(err)}`, { cause: err })
204
+ }
205
+ try {
206
+ writeFileSync(fd, `${process.pid}\n`, 'utf8')
207
+ fsyncSync(fd)
208
+ return callback()
209
+ }
210
+ finally {
211
+ closeSync(fd)
212
+ // A process crash may leave the exclusive lock behind; that intentionally fails closed.
213
+ rmSync(lockPath, { force: true })
214
+ }
215
+ }
216
+
217
+ function receiptOf(q: Qualification, invocationId: string): ApprovalOnlyTrialReceipt {
218
+ return {
219
+ approval_bypassed: true,
220
+ run_id: q.run_id,
221
+ episode_id: q.episode_id,
222
+ arm: q.arm,
223
+ case: q.case,
224
+ invocation_id: invocationId,
225
+ configuration_sha256: q.configuration_sha256,
226
+ fixture_sha256: q.fixture_sha256,
227
+ }
228
+ }
229
+
230
+ export function sameApprovalOnlyTrialReceipt(
231
+ first: ApprovalOnlyTrialReceipt | null | undefined,
232
+ second: ApprovalOnlyTrialReceipt | null | undefined,
233
+ ): boolean {
234
+ return Boolean(first && second
235
+ && first.approval_bypassed === true && second.approval_bypassed === true
236
+ && first.run_id === second.run_id
237
+ && first.episode_id === second.episode_id
238
+ && first.arm === 'OFF' && second.arm === 'OFF'
239
+ && first.case === second.case
240
+ && first.invocation_id === second.invocation_id
241
+ && first.configuration_sha256 === second.configuration_sha256
242
+ && first.fixture_sha256 === second.fixture_sha256)
243
+ }
244
+
245
+ function validate(input: TrialCheckInput): { q: Qualification, home: string, claimPath: string } {
246
+ if (!input.invocationId || input.invocationId.length > 160) throw new Error('trusted invocation id is required')
247
+ const runId = process.env.AW_AGENTTEAM_RUN_ID ?? ''
248
+ const episodeId = process.env.AW_BENCH_APPROVAL_ONLY_EPISODE_ID ?? ''
249
+ if (!/^[a-zA-Z0-9_-]{8,80}$/.test(runId) || process.env.AW_BENCH_APPROVAL_ONLY_ACK !== runId) throw new Error('run confirmation mismatch')
250
+ if (!/^[a-zA-Z0-9_-]{8,80}$/.test(episodeId) || process.env.AW_BENCH_APPROVAL_ONLY_ARM !== 'OFF') throw new Error('episode or manifest arm confirmation mismatch')
251
+ if (!/^[a-f0-9]{64}$/.test(process.env.AW_BENCH_APPROVAL_ONLY_MANIFEST_SHA256 ?? '')
252
+ || !/^[a-f0-9]{64}$/.test(process.env.AW_BENCH_APPROVAL_ONLY_CONFIG_SHA256 ?? '')) throw new Error('manifest/configuration digest confirmation is invalid')
253
+ if (process.env.AW_MODE !== 'home' || (process.env.AW_BENCH_MODE && process.env.AW_BENCH_MODE !== '0')) throw new Error('home mode is required and AW_BENCH_MODE must be disabled')
254
+
255
+ const rawHome = process.env.AW_HOME ?? ''
256
+ if (!isAbsolute(rawHome)) throw new Error('an explicit isolated AW_HOME is required')
257
+ const home = realpathSync(rawHome)
258
+ if (basename(home) !== 'aw-home' || basename(dirname(home)) !== 'OFF' || basename(dirname(dirname(home))) !== episodeId
259
+ || basename(dirname(dirname(dirname(home)))) !== 'episodes'
260
+ || basename(dirname(dirname(dirname(dirname(home))))) !== 'runtime'
261
+ || basename(dirname(dirname(dirname(dirname(dirname(home)))))) !== `${runId}-approval-ablation`) {
262
+ throw new Error('AW_HOME must be this run/episode OFF arm runtime directory')
263
+ }
264
+ if (resolve(rawHome) !== home) throw new Error('AW_HOME must not traverse a symlink')
265
+ const runRoot = dirname(dirname(dirname(dirname(dirname(home)))))
266
+ const expectedHome = join(runRoot, 'runtime', 'episodes', episodeId, 'OFF', 'aw-home')
267
+ if (home !== realpathSync(expectedHome)) throw new Error('AW_HOME path does not match the qualified OFF episode')
268
+
269
+ const aw = loopbackUrl(process.env.AW_BASE, 'AW_BASE')
270
+ const sim = loopbackUrl(process.env.SIM_BASE, 'SIM_BASE')
271
+ if (Number(sim.port) === 4010 || Number(aw.port) === 3001) throw new Error('shared default service ports are forbidden')
272
+
273
+ const qualificationPath = join(home, 'approval-only-qualification.json')
274
+ const { value: parsed } = readRegularJson(qualificationPath, 'approval-only qualification')
275
+ const q = parsed as unknown as Qualification
276
+ const expiry = Date.parse(q.expires_at_utc)
277
+ if (q.schema_version !== 2 || q.run_id !== runId || q.episode_id !== episodeId || q.arm !== 'OFF'
278
+ || resolve(q.aw_home) !== home || q.aw_base !== aw.origin || q.sim_base !== sim.origin
279
+ || q.configuration_sha256 !== process.env.AW_BENCH_APPROVAL_ONLY_CONFIG_SHA256
280
+ || q.manifest_sha256 !== process.env.AW_BENCH_APPROVAL_ONLY_MANIFEST_SHA256
281
+ || !Number.isFinite(expiry) || expiry <= Date.now() || expiry - Date.now() > 10 * 60_000) {
282
+ throw new Error('qualification is mismatched, expired, or not bound to this OFF episode')
283
+ }
284
+ if (!input.line?.simulated || q.line_id !== input.line.id || q.recipe_id !== input.recipeId || q.actor_id !== input.actorId
285
+ || q.hypothesis !== input.hypothesis || input.nodes.length !== 1 || input.params.length !== 1 || !Array.isArray(q.nodes)) {
286
+ throw new Error('the qualified simulated line, actor, recipe, candidate, and single target are required')
287
+ }
288
+ const sameParams = q.params.length === input.params.length && q.params.every((param, index) =>
289
+ param.node_id === input.params[index]?.node_id && Number(param.value) === Number(input.params[index]?.value))
290
+ if (!sameParams) throw new Error('candidate values differ from the qualified episode')
291
+
292
+ const endpoints = input.nodes.map((node) => {
293
+ const allowed = q.nodes.filter(entry => entry.node_id === node.id)
294
+ const hash = sha256(stableJson(node.driverConfig))
295
+ if (allowed.length !== 1 || allowed[0]!.driver !== node.driver || allowed[0]!.driver_config_sha256 !== hash) throw new Error('target or driver configuration differs from qualification')
296
+ const endpoint = targetEndpoint(node)
297
+ if (allowed[0]!.host !== endpoint.host || allowed[0]!.port !== endpoint.port) throw new Error('driver endpoint differs from qualification')
298
+ return endpoint
299
+ })
300
+ const fixtureSha = approvalOnlyFixtureSha256(input)
301
+ if (q.fixture_sha256 !== fixtureSha) throw new Error('actor/recipe/node/value/schema fixture digest mismatch')
302
+
303
+ const { value: manifest, bytes: manifestBytes } = readRegularJson(join(runRoot, 'manifest.json'), 'A1 pilot manifest')
304
+ const { value: configuration } = readRegularJson(join(runRoot, 'configuration.json'), 'A1 pilot configuration')
305
+ if (sha256(manifestBytes) !== q.manifest_sha256 || configurationSha256(configuration) !== q.configuration_sha256
306
+ || manifest.schema_version !== 'a1-approval-pilot-v1' || manifest.run_id !== runId
307
+ || manifest.study_type !== 'descriptive-pilot' || manifest.configuration_sha256 !== q.configuration_sha256
308
+ || stableJson(manifest.network_isolation) !== stableJson({ mode: 'docker-network-none', loopback_only: true })
309
+ || configuration.run_id !== runId || configuration.configuration_sha256 !== q.configuration_sha256) {
310
+ throw new Error('run manifest/configuration changed after episode qualification')
311
+ }
312
+ const registered = (manifest.episodes as Manifest['episodes'] | undefined)?.filter(row => row.episode_id === episodeId) ?? []
313
+ if (registered.length !== 1) throw new Error('episode id is absent or duplicated in the frozen manifest')
314
+ const row = registered[0]!
315
+ if (row.case !== q.case || row.arm_order.length !== 2 || [...row.arm_order].sort().join(',') !== 'OFF,ON'
316
+ || row.actor_id !== q.actor_id || row.line_id !== q.line_id
317
+ || row.recipe_id !== q.recipe_id || row.hypothesis !== q.hypothesis || row.fixture_sha256 !== q.fixture_sha256
318
+ || stableJson(row.params) !== stableJson(q.params)) throw new Error('episode qualification differs from its preregistered manifest row')
319
+
320
+ assertLoopbackOnlyNetworkNamespace(networkInterfaces())
321
+ const simRoot = realpathSync(q.simulator_root)
322
+ if (simRoot !== realpathSync(join(runRoot, 'runtime', 'episodes', episodeId, 'OFF', 'simulator')) || !Number.isInteger(q.simulator_pid) || q.simulator_pid <= 0) {
323
+ throw new Error('private simulator root/PID mismatch')
324
+ }
325
+ const commandLine = readFileSync(`/proc/${q.simulator_pid}/cmdline`, 'utf8').replaceAll('\0', ' ').replaceAll('\\', '/').toLowerCase()
326
+ if (!process.kill(q.simulator_pid, 0)) throw new Error('simulator PID is not alive')
327
+ if (!commandLine.includes(`${simRoot.replaceAll('\\', '/').toLowerCase()}/src/server/index.ts`)) throw new Error('simulator PID does not own this run\'s entry point')
328
+ assertListener(Number(aw.port), process.pid)
329
+ for (const port of new Set([Number(sim.port), ...endpoints.map(endpoint => endpoint.port)])) assertListener(port, q.simulator_pid)
330
+ return { q, home, claimPath: join(home, 'approval-only-claim.json') }
331
+ }
332
+
333
+ /** Validate the fixed OFF episode at approval time, then require atomic one-shot dispatch consumption. */
334
+ export function approvalOnlyTrialReceipt(input: TrialCheckInput): ApprovalOnlyTrialReceipt | null {
69
335
  const requested = process.env.AW_BENCH_APPROVAL_ONLY
70
336
  if (requested == null || requested === '' || requested === '0') return null
71
337
  try {
72
338
  if (requested !== '1') throw new Error('AW_BENCH_APPROVAL_ONLY must be 1 or disabled')
73
- const runId = process.env.AW_AGENTTEAM_RUN_ID ?? ''
74
- if (!/^[a-zA-Z0-9_-]{8,80}$/.test(runId) || process.env.AW_BENCH_APPROVAL_ONLY_ACK !== runId) throw new Error('run confirmation mismatch')
75
- if (process.env.AW_MODE !== 'home' || (process.env.AW_BENCH_MODE && process.env.AW_BENCH_MODE !== '0')) throw new Error('home mode is required and AW_BENCH_MODE must be disabled')
76
- const rawHome = process.env.AW_HOME ?? ''
77
- if (!isAbsolute(rawHome)) throw new Error('an explicit isolated AW_HOME is required')
78
- const home = realpathSync(rawHome)
79
- if (basename(home) !== 'aw-home' || basename(dirname(home)) !== 'runtime' || !basename(dirname(dirname(home))).startsWith(runId)) {
80
- throw new Error('AW_HOME must be this run\'s runtime/aw-home directory')
81
- }
82
- const aw = loopbackUrl(process.env.AW_BASE, 'AW_BASE')
83
- const sim = loopbackUrl(process.env.SIM_BASE, 'SIM_BASE')
84
- if (Number(sim.port) === 4010 || Number(aw.port) === 3001) throw new Error('shared default service ports are forbidden')
85
- const qualificationPath = join(home, 'approval-only-qualification.json')
86
- if (!lstatSync(qualificationPath).isFile() || lstatSync(qualificationPath).isSymbolicLink()) throw new Error('qualification must be a regular run-private file')
87
- const q = JSON.parse(readFileSync(qualificationPath, 'utf8')) as Qualification
88
- const expiry = Date.parse(q.expires_at_utc)
89
- if (q.schema_version !== 1 || q.run_id !== runId || resolve(q.aw_home) !== home || q.aw_base !== aw.origin || q.sim_base !== sim.origin
90
- || !Number.isFinite(expiry) || expiry <= Date.now() || expiry - Date.now() > 3_600_000) throw new Error('qualification is mismatched or expired')
91
- if (!input.line?.simulated || q.line_id !== input.line.id || q.recipe_id !== input.recipeId || input.nodes.length !== 1 || !Array.isArray(q.nodes)) {
92
- throw new Error('the qualified simulated line, recipe and targets are required')
93
- }
94
- const endpoints = input.nodes.map((node) => {
95
- const allowed = q.nodes.filter(entry => entry.node_id === node.id)
96
- const hash = createHash('sha256').update(JSON.stringify(node.driverConfig)).digest('hex')
97
- if (allowed.length !== 1 || allowed[0]!.driver !== node.driver || allowed[0]!.driver_config_sha256 !== hash) throw new Error('target or driver configuration differs from qualification')
98
- const endpoint = targetEndpoint(node)
99
- if (endpoint && (allowed[0]!.host !== endpoint.host || allowed[0]!.port !== endpoint.port)) throw new Error('driver endpoint differs from qualification')
100
- return endpoint
101
- }).filter((endpoint): endpoint is { host: string, port: number } => endpoint !== null)
102
- if (endpoints.length) {
103
- if (process.platform !== 'win32') throw new Error('simulator PID verification is supported only on Windows')
104
- const simRoot = realpathSync(q.simulator_root)
105
- if (simRoot !== realpathSync(join(dirname(home), 'simulator')) || !Number.isInteger(q.simulator_pid) || q.simulator_pid <= 0) throw new Error('private simulator root/PID mismatch')
106
- const commandLine = execFileSync('powershell.exe', ['-NoProfile', '-NonInteractive', '-Command', `(Get-CimInstance Win32_Process -Filter "ProcessId=${q.simulator_pid}").CommandLine`], { encoding: 'utf8', timeout: 8000, maxBuffer: 64 * 1024 })
107
- .replaceAll('\\', '/').toLowerCase()
108
- if (!commandLine.includes(`${simRoot.replaceAll('\\', '/').toLowerCase()}/src/server/index.ts`)) throw new Error('simulator PID does not own this run\'s entry point')
109
- assertListener(Number(aw.port), process.pid)
110
- for (const port of new Set([Number(sim.port), ...endpoints.map(endpoint => endpoint.port)])) assertListener(port, q.simulator_pid)
111
- }
112
- return { approval_bypassed: true, run_id: runId }
339
+ const { q, home, claimPath } = validate(input)
340
+ return withClaimLock(home, () => {
341
+ if (input.stage === 'approval') {
342
+ const claim = {
343
+ schema_version: 1,
344
+ state: 'claimed',
345
+ run_id: q.run_id,
346
+ episode_id: q.episode_id,
347
+ invocation_id: input.invocationId,
348
+ arm: q.arm,
349
+ case: q.case,
350
+ configuration_sha256: q.configuration_sha256,
351
+ fixture_sha256: q.fixture_sha256,
352
+ claimed_at_utc: new Date().toISOString(),
353
+ }
354
+ const fd = openSync(claimPath, 'wx', 0o600)
355
+ try {
356
+ writeFileSync(fd, `${JSON.stringify(claim, null, 2)}\n`, 'utf8')
357
+ fsyncSync(fd)
358
+ }
359
+ finally { closeSync(fd) }
360
+ }
361
+ else {
362
+ const existing = readClaim(claimPath)
363
+ if (existing.state !== 'claimed' || existing.run_id !== q.run_id || existing.episode_id !== q.episode_id
364
+ || existing.arm !== 'OFF' || existing.invocation_id !== input.invocationId
365
+ || existing.fixture_sha256 !== q.fixture_sha256 || existing.configuration_sha256 !== q.configuration_sha256) {
366
+ throw new Error('dispatch does not match the claimed one-shot episode/invocation')
367
+ }
368
+ const consumedPath = join(home, 'approval-only-consumed.json')
369
+ const consumed = {
370
+ schema_version: 1,
371
+ state: 'consumed-before-dispatch',
372
+ run_id: q.run_id,
373
+ episode_id: q.episode_id,
374
+ invocation_id: input.invocationId,
375
+ arm: q.arm,
376
+ case: q.case,
377
+ configuration_sha256: q.configuration_sha256,
378
+ fixture_sha256: q.fixture_sha256,
379
+ consumed_at_utc: new Date().toISOString(),
380
+ }
381
+ const fd = openSync(consumedPath, 'wx', 0o600)
382
+ try {
383
+ writeFileSync(fd, `${JSON.stringify(consumed, null, 2)}\n`, 'utf8')
384
+ fsyncSync(fd)
385
+ }
386
+ finally { closeSync(fd) }
387
+ }
388
+ return receiptOf(q, input.invocationId)
389
+ })
113
390
  }
114
391
  catch (err) {
115
392
  throw new Error(`Approval-only trial refused: ${err instanceof Error ? err.message : String(err)}`, { cause: err })
@@ -7,6 +7,7 @@ import { agentBadgeLabel } from '../agent-badge'
7
7
  import { findDcwTemplate } from '../../dcw/dcw-templates'
8
8
  import { getActiveLineRun } from '../../dcw/line-run'
9
9
  import { getAgentNodeBindingRepo } from '../node-bindings.repo'
10
+ import { scientificPayloadForWrite } from './identifiability-tools'
10
11
  import { getDaqNodeRepo } from '../../daq/daq-node.repo'
11
12
  import { getDcwController } from '../../dcw/dcw-controller'
12
13
  import { getDcwLineRepo } from '../../dcw/dcw-line.repo'
@@ -204,11 +205,14 @@ async function dcwControlGovernedLegacy(agentId: string, args: { node_id?: strin
204
205
  const via = recipeBinding && authorizedRecipe
205
206
  ? `经配方授权「${authorizedRecipe.name}」${lineManual ? '(产线手动模式)' : ''}${channelManual ? '(频道手动模式)' : ''}`
206
207
  : (channelManual ? '(频道手动模式)' : '')
208
+ // P5 审批卡科学载荷:上次可辨识性判定 + 可证伪方式(卡片自动填,不再只有散文)
209
+ const sci = scientificPayloadForWrite(nodeId, node.name, value)
207
210
  const ap = await requestManualApproval({
208
211
  agentId,
209
212
  nodeId,
213
+ payload: sci.payload,
210
214
  // 审批卡可见"为什么":Agent 依据(hypothesis)随卡展示,人工批准时有判断材料
211
- detail: `${node.name}(${tpl?.ch ?? node.templateKey})设定 ${value}${node.unit},有效写入区间 ${bd.effective.min}~${bd.effective.max}${node.unit}(${bd.layers.map(l => l.label).join(' ∩ ')})${via ? ` ${via}` : ''}${hypothesisText ? `;Agent 依据:${hypothesisText.slice(0, 200)}` : ''}`,
215
+ detail: `${node.name}(${tpl?.ch ?? node.templateKey})设定 ${value}${node.unit},有效写入区间 ${bd.effective.min}~${bd.effective.max}${node.unit}(${bd.layers.map(l => l.label).join(' ∩ ')})${via ? ` ${via}` : ''}${hypothesisText ? `;Agent 依据:${hypothesisText.slice(0, 200)}` : ''}\n${sci.lines.join('\n')}`,
212
216
  // 批准后复核同一条授权路径:直绑看 dcw 绑定,配方授权看配方绑定与参数仍存在
213
217
  verify: recipeBinding
214
218
  ? () => {
@@ -245,6 +249,8 @@ async function dcwControlGovernedLegacy(agentId: string, args: { node_id?: strin
245
249
  taskId: args.task_id ? String(args.task_id) : undefined,
246
250
  hypothesis: args.hypothesis ? String(args.hypothesis) : '',
247
251
  approvalId: approvalId || undefined,
252
+ // v34 干预台账归因:写入发生时所在 Channel(台账 path/channel 维度)
253
+ channelId: channelId ?? undefined,
248
254
  // 台账口径(三模式):该次写入发生时的频道生效执行模式(事后审计"这条写入当时是什么模式")
249
255
  executionMode: execMode,
250
256
  }