openpond 0.0.69 → 0.1.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 (188) hide show
  1. package/dist/chunks/{app-layer-EXXOWJ5H.js → app-layer-XEYHFJHI.js} +2 -2
  2. package/dist/chunks/{app-server-runtime-7FBQBE3C.js → app-server-runtime-Y6MW4XCG.js} +7 -6
  3. package/dist/chunks/{apps-RZSDOFAG.js → apps-GSXUDK6V.js} +2 -2
  4. package/dist/chunks/{chunk-SFMNGWNO.js → chunk-2JABRRNR.js} +1 -1
  5. package/dist/chunks/{chunk-MMRJNSWY.js → chunk-6G6MDZLM.js} +1096 -120
  6. package/dist/chunks/{chunk-NPNIL6SQ.js → chunk-AN2EYCN3.js} +1 -1
  7. package/dist/chunks/{chunk-F36ZVO6U.js → chunk-CNTM26OW.js} +1 -1
  8. package/dist/chunks/{chunk-FEOLMLYU.js → chunk-EFET7LB7.js} +21 -2
  9. package/dist/chunks/{training-5CPTZRVC.js → chunk-J7PYGDRY.js} +251 -16
  10. package/dist/chunks/{chunk-Y57RTLVV.js → chunk-N3TGCM7J.js} +93 -35
  11. package/dist/chunks/{chunk-BLFIIAWZ.js → chunk-NTK22KJD.js} +68 -21
  12. package/dist/chunks/{chunk-QTN6HXOR.js → chunk-P6JLLWMI.js} +2 -2
  13. package/dist/chunks/chunk-R3C3MNSI.js +140 -0
  14. package/dist/chunks/{chunk-7C4OIFOC.js → chunk-TGM5IPYO.js} +31 -3
  15. package/dist/chunks/{chunk-OOM2PHBE.js → chunk-TZWAUV2L.js} +1130 -226
  16. package/dist/chunks/{cli-HIXVXM72.js → cli-L5VPOV6I.js} +6 -5
  17. package/dist/chunks/continual-FYDKLCO7.js +803 -0
  18. package/dist/chunks/{core-commands-34SVH6ZQ.js → core-commands-MAN3CSJQ.js} +3 -3
  19. package/dist/chunks/{desktop-test-66DPBNJX.js → desktop-test-OE5SST2W.js} +2 -2
  20. package/dist/chunks/{extension-ZMRHCDO3.js → extension-J3CIEDP4.js} +968 -19
  21. package/dist/chunks/{help-COHCZEP2.js → help-JNGJJFU5.js} +1 -1
  22. package/dist/chunks/{opchat-2PGW2GNN.js → opchat-6HEQJFLL.js} +2 -2
  23. package/dist/chunks/{organizations-NZ4OY56V.js → organizations-MWAPNOCK.js} +5 -4
  24. package/dist/chunks/{profile-GEMTRPUG.js → profile-P7HMONTZ.js} +2 -2
  25. package/dist/chunks/{project-agent-NX6YBGWC.js → project-agent-2RAK7GAZ.js} +2 -2
  26. package/dist/chunks/{sandbox-command-UEY53OJO.js → sandbox-command-G22CPFNK.js} +2 -2
  27. package/dist/chunks/{sandbox-template-YKYRB645.js → sandbox-template-S4WRUWJ6.js} +3 -3
  28. package/dist/chunks/{src-IXYDKOBI.js → src-A6O6ZGIL.js} +15899 -8010
  29. package/dist/chunks/{src-LKJBD5AM.js → src-BKBZ7WLO.js} +4 -3
  30. package/dist/chunks/taskset-BMI7KOWP.js +66 -0
  31. package/dist/chunks/{teams-bot-K6KZHZJV.js → teams-bot-5VBYEN7M.js} +2 -2
  32. package/dist/chunks/training-UPVSGDTB.js +17 -0
  33. package/dist/chunks/{workspaces-WXM72UZF.js → workspaces-XM5BY3MO.js} +4 -2
  34. package/dist/cli.js +13 -13
  35. package/dist/web/assets/App-DfiCmBv6.js +173 -0
  36. package/dist/web/assets/{AppDialog-DX-xs3KA.js → AppDialog-CSXu5wRu.js} +1 -1
  37. package/dist/web/assets/{AppTerminalPanel-CYVj_ITT.js → AppTerminalPanel-y2bVL2RV.js} +2 -2
  38. package/dist/web/assets/{AppsView-ByjyGog7.js → AppsView-Bs9pwD2H.js} +1 -1
  39. package/dist/web/assets/{BrowserSidebar-BDwtMAZl.js → BrowserSidebar-CUgT5V1m.js} +1 -1
  40. package/dist/web/assets/{CartesianChart-Dv6jJfPR.js → CartesianChart-DA85hfrP.js} +1 -1
  41. package/dist/web/assets/{CollaborationTabs-CC5AIhMh.js → CollaborationTabs-B8mlPhM3.js} +1 -1
  42. package/dist/web/assets/{CommandMenu-Ct0Sx7yP.js → CommandMenu-EwUGCeC_.js} +1 -1
  43. package/dist/web/assets/{CommunityView-C_zVE0jg.js → CommunityView-IHNq-YJz.js} +1 -1
  44. package/dist/web/assets/{ComposerCreateImproveStrip-CNn4OywM.js → ComposerCreateImproveStrip-qOL2zA26.js} +1 -1
  45. package/dist/web/assets/{GetStartedView-DRFpHDLd.js → GetStartedView-C2ypO0v7.js} +1 -1
  46. package/dist/web/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  47. package/dist/web/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  48. package/dist/web/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  49. package/dist/web/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  50. package/dist/web/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  51. package/dist/web/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  52. package/dist/web/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  53. package/dist/web/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  54. package/dist/web/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  55. package/dist/web/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  56. package/dist/web/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  57. package/dist/web/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  58. package/dist/web/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  59. package/dist/web/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  60. package/dist/web/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  61. package/dist/web/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  62. package/dist/web/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  63. package/dist/web/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  64. package/dist/web/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  65. package/dist/web/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  66. package/dist/web/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  67. package/dist/web/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  68. package/dist/web/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  69. package/dist/web/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  70. package/dist/web/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  71. package/dist/web/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  72. package/dist/web/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  73. package/dist/web/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  74. package/dist/web/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  75. package/dist/web/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  76. package/dist/web/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  77. package/dist/web/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  78. package/dist/web/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  79. package/dist/web/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  80. package/dist/web/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  81. package/dist/web/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  82. package/dist/web/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  83. package/dist/web/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  84. package/dist/web/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  85. package/dist/web/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  86. package/dist/web/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  87. package/dist/web/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  88. package/dist/web/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  89. package/dist/web/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  90. package/dist/web/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  91. package/dist/web/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  92. package/dist/web/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  93. package/dist/web/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  94. package/dist/web/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  95. package/dist/web/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  96. package/dist/web/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  97. package/dist/web/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  98. package/dist/web/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  99. package/dist/web/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  100. package/dist/web/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  101. package/dist/web/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  102. package/dist/web/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  103. package/dist/web/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  104. package/dist/web/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  105. package/dist/web/assets/LabModelVersionDetailPage-BK0eoUlW.js +1 -0
  106. package/dist/web/assets/{LabSkillSidebar-B9jY4AgE.js → LabSkillSidebar-CRPb4qBn.js} +1 -1
  107. package/dist/web/assets/LabsRoute-Bw-HD6QC.js +2 -0
  108. package/dist/web/assets/LabsRoute-CGFgymTX.css +1 -0
  109. package/dist/web/assets/MainChatThread-Cu6_UnNE.js +2 -0
  110. package/dist/web/assets/MainPane-k1iII9e9.js +8 -0
  111. package/dist/web/assets/MarkdownText-N60tvLug.js +268 -0
  112. package/dist/web/assets/Messages-CYQFLElK.js +10 -0
  113. package/dist/web/assets/{NativeSkillSidebar-DjebFRoi.js → NativeSkillSidebar-zbx7WmOk.js} +1 -1
  114. package/dist/web/assets/{NewExperienceSwitcher-C-bJxHxY.js → NewExperienceSwitcher-B0zev5Sx.js} +1 -1
  115. package/dist/web/assets/{NewProjectDialog-Cx8QcZm7.js → NewProjectDialog-lZlzrp-R.js} +1 -1
  116. package/dist/web/assets/{OutputsPage-Y9HM-SHX.js → OutputsPage-B4zYYUT5.js} +1 -1
  117. package/dist/web/assets/{ProjectsPage-BBr58yKT.js → ProjectsPage-97wgc84s.js} +1 -1
  118. package/dist/web/assets/RightChatPanelStack-I2znDCc7.js +1 -0
  119. package/dist/web/assets/{RightSidebarHomePanel-Dx-1elSI.js → RightSidebarHomePanel-BUcWVJi-.js} +1 -1
  120. package/dist/web/assets/ScheduledWorkPage-Bp-t0eVj.js +1 -0
  121. package/dist/web/assets/SettingsView-C1xyn1Y4.js +6 -0
  122. package/dist/web/assets/{TeamChatView-Bkyhu40R.js → TeamChatView-Fj5_yjVE.js} +2 -2
  123. package/dist/web/assets/{TerminalOverlay-CaCkZDzO.js → TerminalOverlay-D2WBeJvp.js} +1 -1
  124. package/dist/web/assets/{TrainingCreationPanel-Vvi41WNT.js → TrainingCreationPanel-dYW_dh3M.js} +1 -1
  125. package/dist/web/assets/{TrainingDraftPanel-C2C3hffI.js → TrainingDraftPanel-zeJWmmW6.js} +1 -1
  126. package/dist/web/assets/{UsageSettingsSection-DpPBd-ra.js → UsageSettingsSection-B6SBqYuB.js} +2 -2
  127. package/dist/web/assets/WorkSidebarPanel-BwbWKpOZ.js +1 -0
  128. package/dist/web/assets/{WorkspaceDiffPanel-D_zKOW4K.js → WorkspaceDiffPanel-D9Kp0vFw.js} +6 -6
  129. package/dist/web/assets/WorkspaceEnvironmentMenu-D-3YGp06.js +32 -0
  130. package/dist/web/assets/WorkspaceGitDialogs-BUbzUN4m.js +1 -0
  131. package/dist/web/assets/{WorkspaceMonacoEditor--GOVrHFp.js → WorkspaceMonacoEditor-CXPY7bBI.js} +3 -3
  132. package/dist/web/assets/{arrow-up-right-BRZWXpqJ.js → arrow-up-right-C7VWgGQP.js} +1 -1
  133. package/dist/web/assets/{chat-file-links-CgFHK89C.js → chat-file-links-CqfMdhHQ.js} +1 -1
  134. package/dist/web/assets/chevron-up-DD9Tei-Q.js +1 -0
  135. package/dist/web/assets/{clipboard-dPd_3lpG.js → clipboard-B-8k7mlT.js} +1 -1
  136. package/dist/web/assets/{cloud-upload-DOwvN4hp.js → cloud-upload-CUVFzURz.js} +1 -1
  137. package/dist/web/assets/{cssMode-BM4j9M0D.js → cssMode-DYvfmqoL.js} +1 -1
  138. package/dist/web/assets/{folder-open-DavjPCw4.js → folder-open-CnbcQIy8.js} +1 -1
  139. package/dist/web/assets/{folder-plus-Dyqast6G.js → folder-plus-BOaLAKy4.js} +1 -1
  140. package/dist/web/assets/{git-commit-horizontal-s3X0cQlz.js → git-commit-horizontal-DQeHsooT.js} +1 -1
  141. package/dist/web/assets/{htmlMode-Nlx7ckXa.js → htmlMode-BXEI-BVY.js} +1 -1
  142. package/dist/web/assets/index-CGMb_VXm.css +1 -0
  143. package/dist/web/assets/{index-5-B6FIuE.js → index-D-VK8mST.js} +1 -1
  144. package/dist/web/assets/index-D-WCyNdJ.js +1 -0
  145. package/dist/web/assets/{info-CVvrNOHr.js → info-DtzDuGLn.js} +1 -1
  146. package/dist/web/assets/{jsonMode-B7monA6g.js → jsonMode-Dosjh_hK.js} +1 -1
  147. package/dist/web/assets/{lspLanguageFeatures-CcJ9GDtK.js → lspLanguageFeatures-BNe-6FJA.js} +1 -1
  148. package/dist/web/assets/{minimize-2-O1DnznGK.js → minimize-2-DnxKN5oK.js} +1 -1
  149. package/dist/web/assets/{monaco.contribution-QOOCizYq.js → monaco.contribution-CfF-ajhi.js} +2 -2
  150. package/dist/web/assets/{monaco.contribution-2PozfA9g.js → monaco.contribution-CnkROzNv.js} +2 -2
  151. package/dist/web/assets/{monaco.contribution-BSJ2jQTi.js → monaco.contribution-Dyns81H2.js} +2 -2
  152. package/dist/web/assets/{monaco.contribution-BMAF2bmO.js → monaco.contribution-ytyanGyj.js} +2 -2
  153. package/dist/web/assets/{play-BpCc5ZbR.js → play-B3o6IAQd.js} +1 -1
  154. package/dist/web/assets/{python-BK41iew-.js → python-B7zZ_9Z_.js} +1 -1
  155. package/dist/web/assets/{refresh-cw-Csoy1ev1.js → refresh-cw-DSJZXa8S.js} +1 -1
  156. package/dist/web/assets/{save-Dbztj0W7.js → save-iC-AXHN6.js} +1 -1
  157. package/dist/web/assets/square-B2roZTxf.js +1 -0
  158. package/dist/web/assets/{toggleHighContrast-DrmwDpyz.js → toggleHighContrast-CjlV4YHK.js} +1 -1
  159. package/dist/web/assets/{training-daZlCtKV.css → training-eg6uFi3M.css} +1 -1
  160. package/dist/web/assets/{tsMode-CFgCMr7d.js → tsMode-XmKmSq0B.js} +1 -1
  161. package/dist/web/assets/{upload-C5nhiSMq.js → upload-BgHXNjfJ.js} +1 -1
  162. package/dist/web/assets/{useLocalAgentSchedules-LAsobERb.js → useLocalAgentSchedules-CVJz0AMr.js} +1 -1
  163. package/dist/web/assets/{wifi-off-BHxh2UbA.js → wifi-off-CneL8bDZ.js} +1 -1
  164. package/dist/web/assets/{workers-FKb-NyBI.js → workers-CT7VYBR5.js} +1 -1
  165. package/dist/web/assets/{yaml-C5DbF9S6.js → yaml-CF8jchCz.js} +1 -1
  166. package/dist/web/index.html +2 -2
  167. package/docs/command-reference.md +58 -2
  168. package/package.json +3 -1
  169. package/dist/web/assets/App-BF9L0JUv.js +0 -171
  170. package/dist/web/assets/LabModelVersionDetailPage-BzF-IVXQ.js +0 -1
  171. package/dist/web/assets/LabsRoute-CS_orT9s.css +0 -1
  172. package/dist/web/assets/LabsRoute-Di1Zs4gZ.js +0 -2
  173. package/dist/web/assets/MainChatThread-8VzlD8Hi.js +0 -2
  174. package/dist/web/assets/MainPane-StAOFINE.js +0 -6
  175. package/dist/web/assets/MarkdownText-B8D_ftSJ.js +0 -9
  176. package/dist/web/assets/Messages-TY62tiDp.js +0 -10
  177. package/dist/web/assets/RightChatPanelStack-DzUbDKwp.js +0 -1
  178. package/dist/web/assets/ScheduledWorkPage-BuXw_W8b.js +0 -1
  179. package/dist/web/assets/SettingsView-DB_zPHYY.js +0 -6
  180. package/dist/web/assets/WorkSidebarPanel-CeWGboTh.js +0 -1
  181. package/dist/web/assets/WorkspaceEnvironmentMenu-BTz9FISP.js +0 -32
  182. package/dist/web/assets/WorkspaceGitDialogs-BnBRUYpS.js +0 -1
  183. package/dist/web/assets/activity-DA5DNQwD.js +0 -1
  184. package/dist/web/assets/chevron-up-DSv2auz_.js +0 -1
  185. package/dist/web/assets/git-branch-zKnZdQiX.js +0 -1
  186. package/dist/web/assets/index-CQ3CPVHZ.css +0 -1
  187. package/dist/web/assets/index-CuoGlf-W.js +0 -1
  188. package/dist/web/assets/square-ju7fWa0W.js +0 -1
@@ -11,7 +11,7 @@ import {
11
11
  truncatePatch,
12
12
  uniqueSortedPaths,
13
13
  workspaceImageContentType
14
- } from "./chunk-7C4OIFOC.js";
14
+ } from "./chunk-TGM5IPYO.js";
15
15
  import {
16
16
  AGENT_PROTOCOL_VERSION,
17
17
  AGENT_RPC_METHODS,
@@ -35,13 +35,13 @@ import {
35
35
  event,
36
36
  now,
37
37
  textFromUnknown
38
- } from "./chunk-NPNIL6SQ.js";
38
+ } from "./chunk-AN2EYCN3.js";
39
39
  import {
40
40
  getBundledRuntimeVersion,
41
41
  loadOpenPondAccountContext,
42
42
  loadOpenPondHostedModels,
43
43
  streamOpenPondHostedChatTurn
44
- } from "./chunk-FEOLMLYU.js";
44
+ } from "./chunk-EFET7LB7.js";
45
45
  import {
46
46
  ActivateRefinerReleaseRequestSchema,
47
47
  AppPreferencesSchema,
@@ -58,6 +58,8 @@ import {
58
58
  ChatProviderSchema,
59
59
  ConnectedAppToolCallRequestSchema,
60
60
  ContextUsageSnapshotSchema,
61
+ ContinualBenchIssueReviewSchema,
62
+ ContinualLearningDailyBatchSchema,
61
63
  CreateHostedSavedWorkRequestSchema,
62
64
  CreateImproveActionShapeSchema,
63
65
  CreateImproveEvidenceSnapshotSchema,
@@ -94,6 +96,9 @@ import {
94
96
  LearnedPreferenceRewardBindingSchema,
95
97
  ModelArtifactLineageSchema,
96
98
  ModelBindingSchema,
99
+ ModelComparisonSeriesEntrySchema,
100
+ ModelComparisonSeriesSchema,
101
+ ModelCurrencySnapshotSchema,
97
102
  ModelProjectSchema as ModelProjectSchema2,
98
103
  ModelRunSchema,
99
104
  ModelUsageRecordSchema,
@@ -171,7 +176,7 @@ import {
171
176
  runProfileSkillCommand,
172
177
  sidebarFileBookmarkId,
173
178
  workOutputMediaTypesCompatible
174
- } from "./chunk-MMRJNSWY.js";
179
+ } from "./chunk-6G6MDZLM.js";
175
180
  import {
176
181
  PROJECT_ACTION_CONFIG_PATH,
177
182
  createLocalActionRunner,
@@ -295,7 +300,7 @@ import {
295
300
  uniqueEventRefs,
296
301
  validateConnectedAppProviderOperationRequest,
297
302
  verifyRequiredOutputs
298
- } from "./chunk-BLFIIAWZ.js";
303
+ } from "./chunk-NTK22KJD.js";
299
304
  import {
300
305
  DEFAULT_OPENPOND_API_BASE_URL,
301
306
  apiFetch,
@@ -851,7 +856,7 @@ function createLogger(options) {
851
856
  }
852
857
 
853
858
  // ../server/src/harness/local-harness-workspace-service.ts
854
- import { randomUUID as randomUUID2 } from "node:crypto";
859
+ import { randomUUID as randomUUID3 } from "node:crypto";
855
860
  import { constants as fsConstants, promises as fs4 } from "node:fs";
856
861
  import path7 from "node:path";
857
862
 
@@ -1048,6 +1053,8 @@ async function persistStoreData(data, writer) {
1048
1053
  }
1049
1054
 
1050
1055
  // ../server/src/store/store-taskset-drafts.ts
1056
+ import { randomUUID as randomUUID2 } from "node:crypto";
1057
+ import { cp, lstat, mkdir as mkdir3, readFile as readFile3, readdir as readdir2, rename, rm, stat } from "node:fs/promises";
1051
1058
  import path6 from "node:path";
1052
1059
 
1053
1060
  // ../../packages/taskset-sdk/dist/drafts.js
@@ -1103,13 +1110,13 @@ function validateGraderFixtures(taskset, issues) {
1103
1110
  const required = /* @__PURE__ */ new Set(["positive", "negative", "boundary", "adversarial", "prompt_injection", "infrastructure_failure"]);
1104
1111
  for (const fixture of taskset.graderFixtures) {
1105
1112
  if (!taskset.datasetArtifact && !taskIds2.has(fixture.taskId))
1106
- issues.push({ code: "grader_fixture_task_missing", severity: "error", message: `Fixture ${fixture.id} references missing task ${fixture.taskId}.`, path: `graderFixtures.${fixture.id}.taskId` });
1113
+ issues.push({ code: "grader_fixture_task_missing", severity: "warning", message: `Fixture ${fixture.id} references a task outside this Taskset revision (${fixture.taskId}).`, path: `graderFixtures.${fixture.id}.taskId` });
1107
1114
  required.delete(fixture.label);
1108
1115
  if (fixture.label === "infrastructure_failure" && !fixture.infrastructureError)
1109
1116
  issues.push({ code: "infrastructure_fixture_error_missing", severity: "error", message: `Infrastructure fixture ${fixture.id} must declare an infrastructure error.`, path: `graderFixtures.${fixture.id}.infrastructureError` });
1110
1117
  }
1111
1118
  for (const label of required)
1112
- issues.push({ code: "grader_fixture_missing", severity: "error", message: `Taskset requires a ${label} grader fixture.`, path: "graderFixtures" });
1119
+ issues.push({ code: "grader_fixture_missing", severity: "warning", message: `Taskset does not include the optional ${label} grader calibration fixture.`, path: "graderFixtures" });
1113
1120
  }
1114
1121
  function validateDatasetArtifact(taskset, issues) {
1115
1122
  const artifact = taskset.datasetArtifact;
@@ -1359,10 +1366,10 @@ function validateGraders(taskset, issues) {
1359
1366
  issues.push({ code: "grader_duplicate", severity: "error", message: `Duplicate grader id ${grader.id}.`, path: "graders" });
1360
1367
  ids.add(grader.id);
1361
1368
  if (grader.kind === "model_judge" && grader.rewardEligible && grader.calibrationStatus !== "passed") {
1362
- issues.push({ code: "judge_not_calibrated", severity: "error", message: `Model judge ${grader.id} cannot contribute reward before calibration passes.`, path: `graders.${grader.id}` });
1369
+ issues.push({ code: "judge_calibration_pending", severity: "warning", message: `Model judge ${grader.id} is selected for reward without a passing advisory calibration report.`, path: `graders.${grader.id}` });
1363
1370
  }
1364
1371
  if (grader.kind === "model_judge" && grader.calibrationStatus === "passed" && typeof grader.metadata.calibrationEvidenceHash !== "string") {
1365
- issues.push({ code: "judge_calibration_evidence_missing", severity: "error", message: `Model judge ${grader.id} declares calibration without an OpenPond fixture evidence hash.`, path: `graders.${grader.id}.metadata.calibrationEvidenceHash` });
1372
+ issues.push({ code: "judge_calibration_evidence_missing", severity: "warning", message: `Model judge ${grader.id} declares calibration without an OpenPond fixture evidence hash.`, path: `graders.${grader.id}.metadata.calibrationEvidenceHash` });
1366
1373
  }
1367
1374
  if (grader.kind === "human" && grader.rewardEligible) {
1368
1375
  issues.push({ code: "human_online_reward", severity: "error", message: `Human grader ${grader.id} cannot be an online optimizer reward.`, path: `graders.${grader.id}` });
@@ -2538,7 +2545,7 @@ import { promises as fs3 } from "node:fs";
2538
2545
  import path5 from "node:path";
2539
2546
 
2540
2547
  // ../server/src/store/store-schema.ts
2541
- var CURRENT_SQLITE_SCHEMA_VERSION = 50;
2548
+ var CURRENT_SQLITE_SCHEMA_VERSION = 56;
2542
2549
  var SQLITE_CREATE_SCHEMA_SQL = `
2543
2550
  CREATE TABLE IF NOT EXISTS sessions (
2544
2551
  id TEXT PRIMARY KEY,
@@ -3065,7 +3072,7 @@ var SQLITE_CREATE_SCHEMA_SQL = `
3065
3072
  CREATE TABLE IF NOT EXISTS model_runs (
3066
3073
  id TEXT PRIMARY KEY,
3067
3074
  model_id TEXT NOT NULL,
3068
- model_version_id TEXT NOT NULL,
3075
+ model_version_id TEXT,
3069
3076
  profile_id TEXT NOT NULL,
3070
3077
  taskset_id TEXT NOT NULL,
3071
3078
  status TEXT NOT NULL,
@@ -3077,6 +3084,33 @@ var SQLITE_CREATE_SCHEMA_SQL = `
3077
3084
  CREATE INDEX IF NOT EXISTS model_runs_model_updated_idx ON model_runs(model_id, updated_at DESC);
3078
3085
  CREATE INDEX IF NOT EXISTS model_runs_taskset_updated_idx ON model_runs(taskset_id, updated_at DESC);
3079
3086
 
3087
+ CREATE TABLE IF NOT EXISTS model_comparison_series (
3088
+ id TEXT PRIMARY KEY,
3089
+ profile_id TEXT NOT NULL,
3090
+ model_project_id TEXT NOT NULL,
3091
+ status TEXT NOT NULL,
3092
+ payload TEXT NOT NULL,
3093
+ created_at TEXT NOT NULL,
3094
+ updated_at TEXT NOT NULL
3095
+ );
3096
+ CREATE INDEX IF NOT EXISTS model_comparison_series_profile_updated_idx ON model_comparison_series(profile_id, updated_at DESC);
3097
+ CREATE INDEX IF NOT EXISTS model_comparison_series_project_updated_idx ON model_comparison_series(model_project_id, updated_at DESC);
3098
+
3099
+ CREATE TABLE IF NOT EXISTS model_comparison_series_entries (
3100
+ id TEXT PRIMARY KEY,
3101
+ series_id TEXT NOT NULL,
3102
+ profile_id TEXT NOT NULL,
3103
+ model_project_id TEXT NOT NULL,
3104
+ ordinal INTEGER NOT NULL,
3105
+ status TEXT NOT NULL,
3106
+ payload TEXT NOT NULL,
3107
+ created_at TEXT NOT NULL,
3108
+ updated_at TEXT NOT NULL,
3109
+ UNIQUE(series_id, ordinal)
3110
+ );
3111
+ CREATE INDEX IF NOT EXISTS model_comparison_entries_series_ordinal_idx ON model_comparison_series_entries(series_id, ordinal ASC);
3112
+ CREATE INDEX IF NOT EXISTS model_comparison_entries_project_updated_idx ON model_comparison_series_entries(model_project_id, updated_at DESC);
3113
+
3080
3114
  CREATE TABLE IF NOT EXISTS reward_model_versions (
3081
3115
  id TEXT PRIMARY KEY,
3082
3116
  model_id TEXT NOT NULL,
@@ -3484,6 +3518,43 @@ async function createSidebarFileBookmarkTables(exec) {
3484
3518
  `);
3485
3519
  }
3486
3520
 
3521
+ // ../server/src/store/store-chat-workflow-schema.ts
3522
+ async function createChatWorkflowTables(exec) {
3523
+ await exec(`
3524
+ CREATE TABLE IF NOT EXISTS chat_workflows (
3525
+ id TEXT PRIMARY KEY,
3526
+ session_id TEXT NOT NULL,
3527
+ enabled INTEGER NOT NULL,
3528
+ next_run_at TEXT,
3529
+ payload TEXT NOT NULL,
3530
+ created_at TEXT NOT NULL,
3531
+ updated_at TEXT NOT NULL
3532
+ );
3533
+
3534
+ CREATE INDEX IF NOT EXISTS chat_workflows_session_idx
3535
+ ON chat_workflows(session_id, created_at DESC);
3536
+ CREATE INDEX IF NOT EXISTS chat_workflows_due_idx
3537
+ ON chat_workflows(enabled, next_run_at);
3538
+
3539
+ CREATE TABLE IF NOT EXISTS chat_workflow_runs (
3540
+ id TEXT PRIMARY KEY,
3541
+ workflow_id TEXT NOT NULL,
3542
+ session_id TEXT NOT NULL,
3543
+ scheduled_for TEXT NOT NULL,
3544
+ trigger TEXT NOT NULL,
3545
+ status TEXT NOT NULL,
3546
+ payload TEXT NOT NULL,
3547
+ created_at TEXT NOT NULL,
3548
+ updated_at TEXT NOT NULL
3549
+ );
3550
+
3551
+ CREATE UNIQUE INDEX IF NOT EXISTS chat_workflow_runs_occurrence_idx
3552
+ ON chat_workflow_runs(workflow_id, scheduled_for, trigger);
3553
+ CREATE INDEX IF NOT EXISTS chat_workflow_runs_workflow_idx
3554
+ ON chat_workflow_runs(workflow_id, created_at DESC);
3555
+ `);
3556
+ }
3557
+
3487
3558
  // ../server/src/store/store-harness-workspace-schema.ts
3488
3559
  async function createHarnessWorkspaceTables(exec) {
3489
3560
  await exec(`
@@ -4041,6 +4112,31 @@ var SQLITE_MIGRATIONS = [
4041
4112
  {
4042
4113
  version: 50,
4043
4114
  run: (store) => store.repairUnverifiableLearnedPreferenceBindings()
4115
+ },
4116
+ {
4117
+ version: 51,
4118
+ run: (store) => store.createTrainingTables()
4119
+ },
4120
+ {
4121
+ version: 52,
4122
+ run: (store) => store.allowModelRunsWithoutVersion()
4123
+ },
4124
+ {
4125
+ version: 53,
4126
+ run: (store) => store.createTrainingTables()
4127
+ },
4128
+ {
4129
+ version: 54,
4130
+ run: (store) => store.createTrainingTables()
4131
+ },
4132
+ {
4133
+ // Add persisted daily Evals intake/review batches to existing stores.
4134
+ version: 55,
4135
+ run: (store) => store.createTrainingTables()
4136
+ },
4137
+ {
4138
+ version: 56,
4139
+ run: (store) => store.createChatWorkflowTables()
4044
4140
  }
4045
4141
  ];
4046
4142
 
@@ -4118,6 +4214,33 @@ async function createModelProjectTables(database) {
4118
4214
  DROP TABLE IF EXISTS model_build_drafts;
4119
4215
  `);
4120
4216
  }
4217
+ async function allowModelRunsWithoutVersion(database) {
4218
+ await database.exec(`
4219
+ ALTER TABLE model_runs RENAME TO model_runs_before_nullable_version;
4220
+ CREATE TABLE model_runs (
4221
+ id TEXT PRIMARY KEY,
4222
+ model_id TEXT NOT NULL,
4223
+ model_version_id TEXT,
4224
+ profile_id TEXT NOT NULL,
4225
+ taskset_id TEXT NOT NULL,
4226
+ status TEXT NOT NULL,
4227
+ payload TEXT NOT NULL,
4228
+ created_at TEXT NOT NULL,
4229
+ updated_at TEXT NOT NULL
4230
+ );
4231
+ INSERT INTO model_runs (
4232
+ id, model_id, model_version_id, profile_id, taskset_id, status, payload,
4233
+ created_at, updated_at
4234
+ )
4235
+ SELECT id, model_id, model_version_id, profile_id, taskset_id, status,
4236
+ payload, created_at, updated_at
4237
+ FROM model_runs_before_nullable_version;
4238
+ DROP TABLE model_runs_before_nullable_version;
4239
+ CREATE INDEX model_runs_profile_updated_idx ON model_runs(profile_id, updated_at DESC);
4240
+ CREATE INDEX model_runs_model_updated_idx ON model_runs(model_id, updated_at DESC);
4241
+ CREATE INDEX model_runs_taskset_updated_idx ON model_runs(taskset_id, updated_at DESC);
4242
+ `);
4243
+ }
4121
4244
 
4122
4245
  // ../server/src/store/store-model-project-training-setup-migration.ts
4123
4246
  var EMPTY_SETUP = {
@@ -4278,7 +4401,7 @@ async function createModelLifecycleTables(database) {
4278
4401
  CREATE TABLE IF NOT EXISTS model_runs (
4279
4402
  id TEXT PRIMARY KEY,
4280
4403
  model_id TEXT NOT NULL,
4281
- model_version_id TEXT NOT NULL,
4404
+ model_version_id TEXT,
4282
4405
  profile_id TEXT NOT NULL,
4283
4406
  taskset_id TEXT NOT NULL,
4284
4407
  status TEXT NOT NULL,
@@ -4534,10 +4657,23 @@ var TRAINING_TABLES_SQL = `
4534
4657
  CREATE TABLE IF NOT EXISTS model_versions (id TEXT PRIMARY KEY, model_id TEXT NOT NULL, profile_id TEXT NOT NULL, version_number INTEGER NOT NULL, kind TEXT NOT NULL, payload TEXT NOT NULL, created_at TEXT NOT NULL, UNIQUE(model_id, version_number));
4535
4658
  CREATE INDEX IF NOT EXISTS model_versions_profile_created_idx ON model_versions(profile_id, created_at DESC);
4536
4659
  CREATE INDEX IF NOT EXISTS model_versions_model_idx ON model_versions(model_id, version_number DESC);
4537
- CREATE TABLE IF NOT EXISTS model_runs (id TEXT PRIMARY KEY, model_id TEXT NOT NULL, model_version_id TEXT NOT NULL, profile_id TEXT NOT NULL, taskset_id TEXT NOT NULL, status TEXT NOT NULL, payload TEXT NOT NULL, created_at TEXT NOT NULL, updated_at TEXT NOT NULL);
4660
+ CREATE TABLE IF NOT EXISTS model_runs (id TEXT PRIMARY KEY, model_id TEXT NOT NULL, model_version_id TEXT, profile_id TEXT NOT NULL, taskset_id TEXT NOT NULL, status TEXT NOT NULL, payload TEXT NOT NULL, created_at TEXT NOT NULL, updated_at TEXT NOT NULL);
4538
4661
  CREATE INDEX IF NOT EXISTS model_runs_profile_updated_idx ON model_runs(profile_id, updated_at DESC);
4539
4662
  CREATE INDEX IF NOT EXISTS model_runs_model_updated_idx ON model_runs(model_id, updated_at DESC);
4540
4663
  CREATE INDEX IF NOT EXISTS model_runs_taskset_updated_idx ON model_runs(taskset_id, updated_at DESC);
4664
+ CREATE TABLE IF NOT EXISTS model_comparison_series (id TEXT PRIMARY KEY, profile_id TEXT NOT NULL, model_project_id TEXT NOT NULL, status TEXT NOT NULL, payload TEXT NOT NULL, created_at TEXT NOT NULL, updated_at TEXT NOT NULL);
4665
+ CREATE INDEX IF NOT EXISTS model_comparison_series_profile_updated_idx ON model_comparison_series(profile_id, updated_at DESC);
4666
+ CREATE INDEX IF NOT EXISTS model_comparison_series_project_updated_idx ON model_comparison_series(model_project_id, updated_at DESC);
4667
+ CREATE TABLE IF NOT EXISTS model_comparison_series_entries (id TEXT PRIMARY KEY, series_id TEXT NOT NULL, profile_id TEXT NOT NULL, model_project_id TEXT NOT NULL, ordinal INTEGER NOT NULL, status TEXT NOT NULL, payload TEXT NOT NULL, created_at TEXT NOT NULL, updated_at TEXT NOT NULL, UNIQUE(series_id, ordinal));
4668
+ CREATE INDEX IF NOT EXISTS model_comparison_entries_series_ordinal_idx ON model_comparison_series_entries(series_id, ordinal ASC);
4669
+ CREATE INDEX IF NOT EXISTS model_comparison_entries_project_updated_idx ON model_comparison_series_entries(model_project_id, updated_at DESC);
4670
+ CREATE TABLE IF NOT EXISTS model_currency_snapshots (id TEXT PRIMARY KEY, series_id TEXT NOT NULL, entry_id TEXT NOT NULL, evidence_state TEXT NOT NULL, content_hash TEXT NOT NULL, payload TEXT NOT NULL, created_at TEXT NOT NULL, UNIQUE(entry_id, content_hash));
4671
+ CREATE INDEX IF NOT EXISTS model_currency_snapshots_series_created_idx ON model_currency_snapshots(series_id, created_at DESC);
4672
+ CREATE INDEX IF NOT EXISTS model_currency_snapshots_entry_created_idx ON model_currency_snapshots(entry_id, created_at DESC);
4673
+ CREATE TABLE IF NOT EXISTS continual_bench_issue_reviews (id TEXT PRIMARY KEY, series_id TEXT NOT NULL, pass_label TEXT NOT NULL, status TEXT NOT NULL, revision INTEGER NOT NULL, payload TEXT NOT NULL, created_at TEXT NOT NULL, updated_at TEXT NOT NULL, UNIQUE(series_id, pass_label));
4674
+ CREATE INDEX IF NOT EXISTS continual_bench_issue_reviews_series_updated_idx ON continual_bench_issue_reviews(series_id, updated_at DESC);
4675
+ CREATE TABLE IF NOT EXISTS continual_learning_daily_batches (id TEXT PRIMARY KEY, series_id TEXT NOT NULL, schedule_entry_id TEXT NOT NULL, day_ordinal INTEGER NOT NULL, status TEXT NOT NULL, revision INTEGER NOT NULL, payload TEXT NOT NULL, created_at TEXT NOT NULL, updated_at TEXT NOT NULL, UNIQUE(series_id, day_ordinal), UNIQUE(series_id, schedule_entry_id));
4676
+ CREATE INDEX IF NOT EXISTS continual_learning_daily_batches_series_ordinal_idx ON continual_learning_daily_batches(series_id, day_ordinal ASC);
4541
4677
  CREATE TABLE IF NOT EXISTS reward_model_versions (id TEXT PRIMARY KEY, model_id TEXT NOT NULL, profile_id TEXT NOT NULL, version_number INTEGER NOT NULL, taskset_id TEXT NOT NULL, status TEXT NOT NULL, payload TEXT NOT NULL, created_at TEXT NOT NULL, UNIQUE(model_id, version_number));
4542
4678
  CREATE INDEX IF NOT EXISTS reward_model_versions_profile_created_idx ON reward_model_versions(profile_id, created_at DESC);
4543
4679
  CREATE INDEX IF NOT EXISTS reward_model_versions_taskset_created_idx ON reward_model_versions(taskset_id, created_at DESC);
@@ -4983,6 +5119,9 @@ var SqliteStoreCore = class {
4983
5119
  ON local_agent_schedule_runs(schedule_id, created_at DESC);
4984
5120
  `);
4985
5121
  }
5122
+ async createChatWorkflowTables() {
5123
+ return createChatWorkflowTables((sql) => this.exec(sql));
5124
+ }
4986
5125
  async createSubagentTables() {
4987
5126
  await this.exec(`
4988
5127
  CREATE TABLE IF NOT EXISTS subagent_runs (
@@ -5080,18 +5219,20 @@ var SqliteStoreCore = class {
5080
5219
  `);
5081
5220
  }
5082
5221
  async createModelProjectTables() {
5083
- await createModelProjectTables({
5084
- all: (sql, params = []) => this.all(sql, params),
5085
- exec: (sql) => this.exec(sql),
5086
- run: (sql, params = []) => this.run(sql, params)
5087
- });
5222
+ await createModelProjectTables(this.modelProjectMigrationStore());
5223
+ }
5224
+ async allowModelRunsWithoutVersion() {
5225
+ await allowModelRunsWithoutVersion(this.modelProjectMigrationStore());
5088
5226
  }
5089
5227
  async consolidateModelProjectTrainingSetup() {
5090
- await consolidateModelProjectTrainingSetup({
5228
+ await consolidateModelProjectTrainingSetup(this.modelProjectMigrationStore());
5229
+ }
5230
+ modelProjectMigrationStore() {
5231
+ return {
5091
5232
  all: (sql, params = []) => this.all(sql, params),
5092
5233
  exec: (sql) => this.exec(sql),
5093
5234
  run: (sql, params = []) => this.run(sql, params)
5094
- });
5235
+ };
5095
5236
  }
5096
5237
  async repairUnverifiableLearnedPreferenceBindings() {
5097
5238
  await repairUnverifiableLearnedPreferenceBindings({
@@ -5443,6 +5584,253 @@ var SqliteStoreCore = class {
5443
5584
 
5444
5585
  // ../server/src/store/store-training-models.ts
5445
5586
  var SqliteTrainingModelStore = class extends SqliteStoreCore {
5587
+ async saveModelCurrencySnapshot(snapshotInput2) {
5588
+ const snapshot = ModelCurrencySnapshotSchema.parse(snapshotInput2);
5589
+ const existing = await this.getModelCurrencySnapshot(snapshot.id);
5590
+ if (existing) {
5591
+ if (existing.contentHash === snapshot.contentHash && JSON.stringify(existing) === JSON.stringify(snapshot)) return existing;
5592
+ throw new Error("An immutable Model Currency Snapshot cannot be replaced.");
5593
+ }
5594
+ await this.upsertPayload(
5595
+ `INSERT INTO model_currency_snapshots
5596
+ (id, series_id, entry_id, evidence_state, content_hash, payload, created_at)
5597
+ VALUES (?, ?, ?, ?, ?, ?, ?)`,
5598
+ [snapshot.id, snapshot.seriesId, snapshot.entryId, snapshot.evidenceState, snapshot.contentHash, JSON.stringify(snapshot), snapshot.projectedAt]
5599
+ );
5600
+ return snapshot;
5601
+ }
5602
+ async getModelCurrencySnapshot(id) {
5603
+ return this.getParsedPayload("SELECT payload FROM model_currency_snapshots WHERE id = ?", [id], ModelCurrencySnapshotSchema.parse);
5604
+ }
5605
+ async listModelCurrencySnapshots(input = {}) {
5606
+ if (input.entryId) return this.listParsedPayloads("SELECT payload FROM model_currency_snapshots WHERE entry_id = ? ORDER BY created_at DESC", [input.entryId], ModelCurrencySnapshotSchema.parse);
5607
+ if (input.seriesId) return this.listParsedPayloads("SELECT payload FROM model_currency_snapshots WHERE series_id = ? ORDER BY created_at DESC", [input.seriesId], ModelCurrencySnapshotSchema.parse);
5608
+ return this.listParsedPayloads("SELECT payload FROM model_currency_snapshots ORDER BY created_at DESC", [], ModelCurrencySnapshotSchema.parse);
5609
+ }
5610
+ async saveModelComparisonSeries(seriesInput) {
5611
+ const series = ModelComparisonSeriesSchema.parse(seriesInput);
5612
+ const existing = await this.getModelComparisonSeries(series.id);
5613
+ if (existing && (existing.profileId !== series.profileId || existing.modelProjectId !== series.modelProjectId || existing.createdAt !== series.createdAt)) {
5614
+ throw new Error("A Model Comparison Series cannot change its immutable ownership.");
5615
+ }
5616
+ if (existing && series.revision !== existing.revision + 1) {
5617
+ if (JSON.stringify(existing) === JSON.stringify(series)) return existing;
5618
+ throw new Error("A Model Comparison Series update requires the next revision.");
5619
+ }
5620
+ if (existing?.scheduleSealedAt && !sameSealedSeriesDefinition(existing, series)) {
5621
+ throw new Error("A sealed Model Comparison Series definition is immutable.");
5622
+ }
5623
+ await this.upsertPayload(
5624
+ `INSERT INTO model_comparison_series
5625
+ (id, profile_id, model_project_id, status, payload, created_at, updated_at)
5626
+ VALUES (?, ?, ?, ?, ?, ?, ?)
5627
+ ON CONFLICT(id) DO UPDATE SET
5628
+ status = excluded.status,
5629
+ payload = excluded.payload,
5630
+ updated_at = excluded.updated_at`,
5631
+ [
5632
+ series.id,
5633
+ series.profileId,
5634
+ series.modelProjectId,
5635
+ series.status,
5636
+ JSON.stringify(series),
5637
+ series.createdAt,
5638
+ series.updatedAt
5639
+ ]
5640
+ );
5641
+ return series;
5642
+ }
5643
+ async getModelComparisonSeries(id) {
5644
+ return this.getParsedPayload(
5645
+ "SELECT payload FROM model_comparison_series WHERE id = ?",
5646
+ [id],
5647
+ ModelComparisonSeriesSchema.parse
5648
+ );
5649
+ }
5650
+ async listModelComparisonSeries(input = {}) {
5651
+ if (input.modelProjectId) {
5652
+ return this.listParsedPayloads(
5653
+ "SELECT payload FROM model_comparison_series WHERE model_project_id = ? ORDER BY updated_at DESC",
5654
+ [input.modelProjectId],
5655
+ ModelComparisonSeriesSchema.parse
5656
+ );
5657
+ }
5658
+ if (input.profileId) {
5659
+ return this.listParsedPayloads(
5660
+ "SELECT payload FROM model_comparison_series WHERE profile_id = ? ORDER BY updated_at DESC",
5661
+ [input.profileId],
5662
+ ModelComparisonSeriesSchema.parse
5663
+ );
5664
+ }
5665
+ return this.listParsedPayloads(
5666
+ "SELECT payload FROM model_comparison_series ORDER BY updated_at DESC",
5667
+ [],
5668
+ ModelComparisonSeriesSchema.parse
5669
+ );
5670
+ }
5671
+ async saveModelComparisonSeriesEntry(entryInput) {
5672
+ const entry = ModelComparisonSeriesEntrySchema.parse(entryInput);
5673
+ const existing = await this.getModelComparisonSeriesEntry(entry.id);
5674
+ if (existing && !sameEntryLineage(existing, entry)) {
5675
+ throw new Error("A Model Comparison Series Entry cannot change its immutable release lineage.");
5676
+ }
5677
+ if (existing && !validEntryEvidenceEvolution(existing, entry)) {
5678
+ throw new Error("A Model Comparison Series Entry cannot replace linked evidence or artifact lineage.");
5679
+ }
5680
+ await this.upsertPayload(
5681
+ `INSERT INTO model_comparison_series_entries
5682
+ (id, series_id, profile_id, model_project_id, ordinal, status, payload, created_at, updated_at)
5683
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
5684
+ ON CONFLICT(id) DO UPDATE SET
5685
+ status = excluded.status,
5686
+ payload = excluded.payload,
5687
+ updated_at = excluded.updated_at`,
5688
+ [
5689
+ entry.id,
5690
+ entry.seriesId,
5691
+ entry.profileId,
5692
+ entry.modelProjectId,
5693
+ entry.ordinal,
5694
+ entry.status,
5695
+ JSON.stringify(entry),
5696
+ entry.createdAt,
5697
+ entry.updatedAt
5698
+ ]
5699
+ );
5700
+ return entry;
5701
+ }
5702
+ async getModelComparisonSeriesEntry(id) {
5703
+ return this.getParsedPayload(
5704
+ "SELECT payload FROM model_comparison_series_entries WHERE id = ?",
5705
+ [id],
5706
+ ModelComparisonSeriesEntrySchema.parse
5707
+ );
5708
+ }
5709
+ async listModelComparisonSeriesEntries(input = {}) {
5710
+ if (input.seriesId) {
5711
+ return this.listParsedPayloads(
5712
+ "SELECT payload FROM model_comparison_series_entries WHERE series_id = ? ORDER BY ordinal ASC",
5713
+ [input.seriesId],
5714
+ ModelComparisonSeriesEntrySchema.parse
5715
+ );
5716
+ }
5717
+ if (input.modelProjectId) {
5718
+ return this.listParsedPayloads(
5719
+ "SELECT payload FROM model_comparison_series_entries WHERE model_project_id = ? ORDER BY updated_at DESC",
5720
+ [input.modelProjectId],
5721
+ ModelComparisonSeriesEntrySchema.parse
5722
+ );
5723
+ }
5724
+ return this.listParsedPayloads(
5725
+ "SELECT payload FROM model_comparison_series_entries ORDER BY updated_at DESC",
5726
+ [],
5727
+ ModelComparisonSeriesEntrySchema.parse
5728
+ );
5729
+ }
5730
+ async commitModelComparisonSeriesMutation(input) {
5731
+ const nextSeries = ModelComparisonSeriesSchema.parse(input.series);
5732
+ const nextEntry = ModelComparisonSeriesEntrySchema.parse(input.entry);
5733
+ await this.ready;
5734
+ let result2 = { series: nextSeries, entry: nextEntry };
5735
+ const write = this.writeQueue.then(async () => {
5736
+ await this.exec("BEGIN IMMEDIATE");
5737
+ try {
5738
+ const seriesRow = await this.get(
5739
+ "SELECT payload FROM model_comparison_series WHERE id = ?",
5740
+ [nextSeries.id]
5741
+ );
5742
+ if (!seriesRow) throw new Error("Model Comparison Series not found.");
5743
+ const currentSeries = ModelComparisonSeriesSchema.parse(JSON.parse(seriesRow.payload));
5744
+ if (currentSeries.revision !== input.expectedSeriesRevision) {
5745
+ throw new Error(`Comparison Series revision changed; expected ${input.expectedSeriesRevision} and found ${currentSeries.revision}.`);
5746
+ }
5747
+ if (nextSeries.revision !== currentSeries.revision + 1) {
5748
+ throw new Error("A Comparison Series mutation must advance exactly one revision.");
5749
+ }
5750
+ if (currentSeries.scheduleSealedAt && !sameSealedSeriesDefinition(currentSeries, nextSeries)) {
5751
+ throw new Error("A sealed Model Comparison Series definition is immutable.");
5752
+ }
5753
+ const entryRow = await this.get(
5754
+ "SELECT payload FROM model_comparison_series_entries WHERE id = ?",
5755
+ [nextEntry.id]
5756
+ );
5757
+ const currentEntry = entryRow ? ModelComparisonSeriesEntrySchema.parse(JSON.parse(entryRow.payload)) : null;
5758
+ if ((currentEntry?.status ?? null) !== input.expectedEntryStatus) {
5759
+ throw new Error("The Comparison Series Entry changed before the mutation could be applied.");
5760
+ }
5761
+ if (currentEntry && !sameEntryLineage(currentEntry, nextEntry)) {
5762
+ throw new Error("A Model Comparison Series Entry cannot change its immutable release lineage.");
5763
+ }
5764
+ if (currentEntry && !validEntryEvidenceEvolution(currentEntry, nextEntry)) {
5765
+ throw new Error("A Model Comparison Series Entry cannot replace linked evidence or artifact lineage.");
5766
+ }
5767
+ await this.run(
5768
+ `INSERT INTO model_comparison_series_entries
5769
+ (id, series_id, profile_id, model_project_id, ordinal, status, payload, created_at, updated_at)
5770
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
5771
+ ON CONFLICT(id) DO UPDATE SET status = excluded.status, payload = excluded.payload, updated_at = excluded.updated_at`,
5772
+ [
5773
+ nextEntry.id,
5774
+ nextEntry.seriesId,
5775
+ nextEntry.profileId,
5776
+ nextEntry.modelProjectId,
5777
+ nextEntry.ordinal,
5778
+ nextEntry.status,
5779
+ JSON.stringify(nextEntry),
5780
+ nextEntry.createdAt,
5781
+ nextEntry.updatedAt
5782
+ ]
5783
+ );
5784
+ await this.run(
5785
+ `UPDATE model_comparison_series SET status = ?, payload = ?, updated_at = ? WHERE id = ?`,
5786
+ [nextSeries.status, JSON.stringify(nextSeries), nextSeries.updatedAt, nextSeries.id]
5787
+ );
5788
+ await this.exec("COMMIT");
5789
+ result2 = { series: nextSeries, entry: nextEntry };
5790
+ } catch (error) {
5791
+ await this.exec("ROLLBACK").catch(() => void 0);
5792
+ throw error;
5793
+ }
5794
+ });
5795
+ this.writeQueue = write.catch(() => void 0);
5796
+ await write;
5797
+ return result2;
5798
+ }
5799
+ async compareAndSwapModelComparisonSeriesEntry(input) {
5800
+ const next = ModelComparisonSeriesEntrySchema.parse(input.entry);
5801
+ await this.ready;
5802
+ const write = this.writeQueue.then(async () => {
5803
+ await this.exec("BEGIN IMMEDIATE");
5804
+ try {
5805
+ const row = await this.get(
5806
+ "SELECT payload FROM model_comparison_series_entries WHERE id = ?",
5807
+ [next.id]
5808
+ );
5809
+ if (!row) throw new Error("Model Comparison Series Entry not found.");
5810
+ const current = ModelComparisonSeriesEntrySchema.parse(JSON.parse(row.payload));
5811
+ if (current.status !== input.expectedStatus) {
5812
+ throw new Error(`Comparison entry state changed; expected ${input.expectedStatus} and found ${current.status}.`);
5813
+ }
5814
+ if (!sameEntryLineage(current, next)) {
5815
+ throw new Error("A Model Comparison Series Entry cannot change its immutable release lineage.");
5816
+ }
5817
+ if (!validEntryEvidenceEvolution(current, next)) {
5818
+ throw new Error("A Model Comparison Series Entry cannot replace linked evidence or artifact lineage.");
5819
+ }
5820
+ await this.run(
5821
+ "UPDATE model_comparison_series_entries SET status = ?, payload = ?, updated_at = ? WHERE id = ?",
5822
+ [next.status, JSON.stringify(next), next.updatedAt, next.id]
5823
+ );
5824
+ await this.exec("COMMIT");
5825
+ } catch (error) {
5826
+ await this.exec("ROLLBACK").catch(() => void 0);
5827
+ throw error;
5828
+ }
5829
+ });
5830
+ this.writeQueue = write.catch(() => void 0);
5831
+ await write;
5832
+ return next;
5833
+ }
5446
5834
  async saveRewardModelVersion(versionInput) {
5447
5835
  const version = RewardModelVersionSchema.parse(versionInput);
5448
5836
  const existing = await this.getRewardModelVersion(version.id);
@@ -5615,7 +6003,7 @@ var SqliteTrainingModelStore = class extends SqliteStoreCore {
5615
6003
  async saveModelRun(runInput) {
5616
6004
  const modelRun = ModelRunSchema.parse(runInput);
5617
6005
  const existing = await this.getModelRun(modelRun.id);
5618
- if (existing && (existing.modelId !== modelRun.modelId || existing.modelVersionId !== modelRun.modelVersionId || existing.profileId !== modelRun.profileId || existing.taskset.id !== modelRun.taskset.id)) {
6006
+ if (existing && (existing.modelId !== modelRun.modelId || existing.modelVersionId !== modelRun.modelVersionId || existing.profileId !== modelRun.profileId || existing.taskset.id !== modelRun.taskset.id || JSON.stringify(existing.comparisonSeriesEntry ?? null) !== JSON.stringify(modelRun.comparisonSeriesEntry ?? null))) {
5619
6007
  throw new Error("A Model Run cannot change its immutable lineage.");
5620
6008
  }
5621
6009
  if (existing && ["succeeded", "failed", "cancelled"].includes(existing.status) && JSON.stringify(existing) !== JSON.stringify(modelRun) && !isCheckpointResumeTransition(existing, modelRun)) {
@@ -5852,6 +6240,83 @@ var SqliteTrainingModelStore = class extends SqliteStoreCore {
5852
6240
  return row ? parse2(JSON.parse(row.payload)) : null;
5853
6241
  }
5854
6242
  };
6243
+ function sameSealedSeriesDefinition(left, right) {
6244
+ const definition = (series) => ({
6245
+ id: series.id,
6246
+ profileId: series.profileId,
6247
+ modelProjectId: series.modelProjectId,
6248
+ name: series.name,
6249
+ objective: series.objective,
6250
+ productionBinding: series.productionBinding,
6251
+ baseModel: series.baseModel,
6252
+ seedTaskset: series.seedTaskset,
6253
+ eligibleTaskPool: series.eligibleTaskPool,
6254
+ evaluationTasksets: series.evaluationTasksets,
6255
+ grader: series.grader,
6256
+ benchmarkProtocol: series.benchmarkProtocol,
6257
+ automaticEvaluation: series.automaticEvaluation,
6258
+ residualProfile: series.residualProfile,
6259
+ schedule: series.schedule,
6260
+ scheduleSealedAt: series.scheduleSealedAt,
6261
+ advancementPolicy: series.advancementPolicy,
6262
+ executionPolicy: series.executionPolicy,
6263
+ createdBy: series.createdBy,
6264
+ createdAt: series.createdAt
6265
+ });
6266
+ return JSON.stringify(definition(left)) === JSON.stringify(definition(right));
6267
+ }
6268
+ function sameEntryLineage(left, right) {
6269
+ const lineage = (entry) => ({
6270
+ seriesId: entry.seriesId,
6271
+ profileId: entry.profileId,
6272
+ modelProjectId: entry.modelProjectId,
6273
+ scheduleEntryId: entry.scheduleEntryId,
6274
+ releaseHash: entry.releaseHash,
6275
+ ordinal: entry.ordinal,
6276
+ label: entry.label,
6277
+ role: entry.role,
6278
+ branch: entry.branch,
6279
+ parent: entry.parent,
6280
+ taskset: entry.taskset,
6281
+ sourceTasksets: entry.sourceTasksets,
6282
+ taskSelection: entry.taskSelection,
6283
+ trainableRank: entry.trainableRank,
6284
+ serializedEnvelopeRank: entry.serializedEnvelopeRank,
6285
+ enabledCumulativeRank: entry.enabledCumulativeRank,
6286
+ trainableBlockId: entry.trainableBlockId,
6287
+ residualBlocks: entry.residualBlocks.map(({ artifactLineageId: _artifactLineageId, ...block }) => block),
6288
+ createdAt: entry.createdAt
6289
+ });
6290
+ return JSON.stringify(lineage(left)) === JSON.stringify(lineage(right));
6291
+ }
6292
+ function validEntryEvidenceEvolution(current, next) {
6293
+ if (validEntryRetryEvolution(current, next)) return true;
6294
+ const appendOnlyId = (before, after) => before === null || before === after;
6295
+ if (current.attemptOrdinal !== next.attemptOrdinal || JSON.stringify(current.priorRunAttempts) !== JSON.stringify(next.priorRunAttempts) || !appendOnlyId(current.trainingPlanId, next.trainingPlanId) || !appendOnlyId(current.modelRunId, next.modelRunId) || !appendOnlyId(current.modelVersionId, next.modelVersionId) || !appendOnlyId(current.promotionBindingId, next.promotionBindingId) || current.decision !== null && JSON.stringify(current.decision) !== JSON.stringify(next.decision)) return false;
6296
+ const nextEvaluations = new Map(next.evaluations.map((evaluation) => [evaluation.evaluationRunId, evaluation]));
6297
+ if (current.evaluations.some((evaluation) => JSON.stringify(nextEvaluations.get(evaluation.evaluationRunId)) !== JSON.stringify(evaluation))) return false;
6298
+ const nextBlocks = new Map(next.residualBlocks.map((block) => [block.id, block]));
6299
+ return current.residualBlocks.every((block) => {
6300
+ if (!block.artifactLineageId) return true;
6301
+ return nextBlocks.get(block.id)?.artifactLineageId === block.artifactLineageId;
6302
+ });
6303
+ }
6304
+ function validEntryRetryEvolution(current, next) {
6305
+ if (current.status !== "failed" && current.status !== "cancelled" || next.status !== "ready" || current.modelVersionId !== null || current.evaluations.length !== 0 || current.decision !== null || current.promotionBindingId !== null || current.residualBlocks.some(
6306
+ (block) => block.id === current.trainableBlockId && block.artifactLineageId !== null
6307
+ ) || next.trainingPlanId !== null || next.modelRunId !== null || next.modelVersionId !== null || next.evaluations.length !== 0 || next.decision !== null || next.promotionBindingId !== null || next.queuedAt !== null || next.startedAt !== null || next.completedAt !== null || JSON.stringify(current.residualBlocks) !== JSON.stringify(next.residualBlocks)) return false;
6308
+ const hasAttempt = Boolean(current.trainingPlanId || current.modelRunId);
6309
+ const expectedAttempts = hasAttempt ? [...current.priorRunAttempts, {
6310
+ attemptOrdinal: current.attemptOrdinal,
6311
+ trainingPlanId: current.trainingPlanId,
6312
+ modelRunId: current.modelRunId,
6313
+ terminalStatus: current.status,
6314
+ queuedAt: current.queuedAt,
6315
+ startedAt: current.startedAt,
6316
+ completedAt: current.completedAt ?? next.updatedAt
6317
+ }] : current.priorRunAttempts;
6318
+ return next.attemptOrdinal === current.attemptOrdinal + (hasAttempt ? 1 : 0) && JSON.stringify(next.priorRunAttempts) === JSON.stringify(expectedAttempts);
6319
+ }
5855
6320
  function isCheckpointResumeTransition(existing, candidate) {
5856
6321
  if (existing.kind !== "evaluation" || !["failed", "cancelled"].includes(existing.status) || candidate.status !== "running" || candidate.receipt !== null || candidate.failure !== null || candidate.completedAt !== null || !existing.evaluation) {
5857
6322
  return false;
@@ -5881,8 +6346,57 @@ function isCheckpointResumeTransition(existing, candidate) {
5881
6346
  }) === JSON.stringify(candidate);
5882
6347
  }
5883
6348
 
6349
+ // ../server/src/store/store-continual-support-reviews.ts
6350
+ var SqliteContinualBenchReviewStore = class extends SqliteTrainingModelStore {
6351
+ async saveContinualLearningDailyBatch(batchInput) {
6352
+ const batch = ContinualLearningDailyBatchSchema.parse(batchInput);
6353
+ const existing = await this.getContinualLearningDailyBatch(batch.id);
6354
+ if (existing) {
6355
+ if (existing.seriesId !== batch.seriesId || existing.scheduleEntryId !== batch.scheduleEntryId || existing.dayOrdinal !== batch.dayOrdinal || JSON.stringify(existing.sourceTaskset) !== JSON.stringify(batch.sourceTaskset) || batch.revision !== existing.revision + 1) {
6356
+ if (JSON.stringify(existing) === JSON.stringify(batch)) return existing;
6357
+ throw new Error("A daily learning batch update must preserve its intake identity and use the next revision.");
6358
+ }
6359
+ }
6360
+ await this.upsertPayload(
6361
+ `INSERT INTO continual_learning_daily_batches
6362
+ (id, series_id, schedule_entry_id, day_ordinal, status, revision, payload, created_at, updated_at)
6363
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
6364
+ ON CONFLICT(id) DO UPDATE SET status = excluded.status, revision = excluded.revision, payload = excluded.payload, updated_at = excluded.updated_at`,
6365
+ [batch.id, batch.seriesId, batch.scheduleEntryId, batch.dayOrdinal, batch.status, batch.revision, JSON.stringify(batch), batch.createdAt, batch.updatedAt]
6366
+ );
6367
+ return batch;
6368
+ }
6369
+ async getContinualLearningDailyBatch(id) {
6370
+ return this.getParsedPayload("SELECT payload FROM continual_learning_daily_batches WHERE id = ?", [id], ContinualLearningDailyBatchSchema.parse);
6371
+ }
6372
+ async listContinualLearningDailyBatches(input = {}) {
6373
+ return input.seriesId ? this.listParsedPayloads("SELECT payload FROM continual_learning_daily_batches WHERE series_id = ? ORDER BY day_ordinal ASC", [input.seriesId], ContinualLearningDailyBatchSchema.parse) : this.listParsedPayloads("SELECT payload FROM continual_learning_daily_batches ORDER BY series_id, day_ordinal ASC", [], ContinualLearningDailyBatchSchema.parse);
6374
+ }
6375
+ async saveContinualBenchIssueReview(reviewInput) {
6376
+ const review = ContinualBenchIssueReviewSchema.parse(reviewInput);
6377
+ const existing = await this.getContinualBenchIssueReview(review.id);
6378
+ if (existing && (existing.seriesId !== review.seriesId || existing.passLabel !== review.passLabel || existing.packet.contentHash !== review.packet.contentHash || review.revision !== existing.revision + 1)) {
6379
+ if (JSON.stringify(existing) === JSON.stringify(review)) return existing;
6380
+ throw new Error("A Continual Support review update must preserve its sealed packet and use the next revision.");
6381
+ }
6382
+ await this.upsertPayload(
6383
+ `INSERT INTO continual_bench_issue_reviews (id, series_id, pass_label, status, revision, payload, created_at, updated_at)
6384
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
6385
+ ON CONFLICT(id) DO UPDATE SET status = excluded.status, revision = excluded.revision, payload = excluded.payload, updated_at = excluded.updated_at`,
6386
+ [review.id, review.seriesId, review.passLabel, review.status, review.revision, JSON.stringify(review), review.createdAt, review.updatedAt]
6387
+ );
6388
+ return review;
6389
+ }
6390
+ async getContinualBenchIssueReview(id) {
6391
+ return this.getParsedPayload("SELECT payload FROM continual_bench_issue_reviews WHERE id = ?", [id], ContinualBenchIssueReviewSchema.parse);
6392
+ }
6393
+ async listContinualBenchIssueReviews(input = {}) {
6394
+ return input.seriesId ? this.listParsedPayloads("SELECT payload FROM continual_bench_issue_reviews WHERE series_id = ? ORDER BY updated_at DESC", [input.seriesId], ContinualBenchIssueReviewSchema.parse) : this.listParsedPayloads("SELECT payload FROM continual_bench_issue_reviews ORDER BY updated_at DESC", [], ContinualBenchIssueReviewSchema.parse);
6395
+ }
6396
+ };
6397
+
5884
6398
  // ../server/src/store/store-datasets.ts
5885
- var SqliteDatasetStore = class extends SqliteTrainingModelStore {
6399
+ var SqliteDatasetStore = class extends SqliteContinualBenchReviewStore {
5886
6400
  async listDatasetCatalogTasksets(profileId) {
5887
6401
  await this.ready;
5888
6402
  await this.writeQueue;
@@ -6412,6 +6926,91 @@ var SqliteTasksetDraftStore = class extends SqlitePreferenceComparisonStore {
6412
6926
  await this.savePointer(pointer);
6413
6927
  return persistedDraft;
6414
6928
  }
6929
+ async importTasksetDraftPackage(input) {
6930
+ const sourcePath = path6.resolve(input.packagePath);
6931
+ const sourceStats = await stat(sourcePath);
6932
+ const sourceDirectory = sourceStats.isDirectory() ? sourcePath : path6.dirname(sourcePath);
6933
+ await assertRegularPackageTree(sourceDirectory);
6934
+ const sourceHash = await hashTasksetDraftPackage(sourceDirectory);
6935
+ const sourceDraft = await readTasksetDraftPackage(sourceDirectory);
6936
+ const existing = await this.getTasksetDraft(sourceDraft.id);
6937
+ if (existing) {
6938
+ const imported = existing.metadata.importedTasksetPackage;
6939
+ if (imported && typeof imported === "object" && !Array.isArray(imported) && imported.packageHash === sourceHash && existing.profileId === input.profileId) {
6940
+ return existing;
6941
+ }
6942
+ throw new Error(
6943
+ `Taskset draft ${sourceDraft.id} already exists. Import a package with a distinct Taskset id.`
6944
+ );
6945
+ }
6946
+ const importedDraft = TasksetDraftSchema.parse({
6947
+ ...sourceDraft,
6948
+ profileId: input.profileId,
6949
+ status: "draft",
6950
+ revision: 1,
6951
+ publishedTasksetRef: null,
6952
+ metadata: {
6953
+ ...sourceDraft.metadata,
6954
+ importedTasksetPackage: {
6955
+ packageHash: sourceHash,
6956
+ importedAt: (/* @__PURE__ */ new Date()).toISOString()
6957
+ }
6958
+ },
6959
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
6960
+ });
6961
+ const workspacePath = this.workspacePath(importedDraft.id);
6962
+ const temporaryPath = `${workspacePath}.import-${process.pid}-${Date.now()}`;
6963
+ await mkdir3(path6.dirname(workspacePath), { recursive: true });
6964
+ try {
6965
+ await cp(sourceDirectory, temporaryPath, {
6966
+ recursive: true,
6967
+ errorOnExist: true,
6968
+ force: false,
6969
+ preserveTimestamps: true
6970
+ });
6971
+ await writeTasksetDraftPackage(importedDraft, temporaryPath);
6972
+ await rename(temporaryPath, workspacePath);
6973
+ } catch (error) {
6974
+ await rm(temporaryPath, { recursive: true, force: true });
6975
+ throw error;
6976
+ }
6977
+ const pointer = TasksetDraftPointerSchema.parse({
6978
+ schemaVersion: "openpond.tasksetDraftPointer.v1",
6979
+ id: importedDraft.id,
6980
+ profileId: importedDraft.profileId,
6981
+ status: importedDraft.status,
6982
+ revision: importedDraft.revision,
6983
+ workspacePath,
6984
+ packageHash: await hashTasksetDraftPackage(workspacePath),
6985
+ publishedTasksetRef: importedDraft.publishedTasksetRef,
6986
+ createdAt: importedDraft.createdAt,
6987
+ updatedAt: importedDraft.updatedAt
6988
+ });
6989
+ await this.savePointer(pointer);
6990
+ return importedDraft;
6991
+ }
6992
+ async materializePublishedTasksetPackage(input) {
6993
+ const workspace = await this.getTasksetDraftWorkspace(input.draftId);
6994
+ if (!workspace) {
6995
+ throw new Error(`Taskset draft ${input.draftId} workspace was not found.`);
6996
+ }
6997
+ await assertRegularPackageTree(workspace.workspacePath);
6998
+ const tasksetRoot = path6.join(
6999
+ path6.dirname(this.storePath),
7000
+ "training",
7001
+ "tasksets",
7002
+ input.taskset.id
7003
+ );
7004
+ await mkdir3(tasksetRoot, { recursive: true });
7005
+ await cp(workspace.workspacePath, tasksetRoot, {
7006
+ recursive: true,
7007
+ force: true,
7008
+ preserveTimestamps: true
7009
+ });
7010
+ await buildTaskset(input.taskset, tasksetRoot);
7011
+ await verifyPublishedTasksetAssets(tasksetRoot, input.taskset);
7012
+ return tasksetRoot;
7013
+ }
6415
7014
  async getTasksetDraft(id) {
6416
7015
  const stored = await this.getParsedPayload(
6417
7016
  "SELECT payload FROM taskset_drafts WHERE id = ?",
@@ -6447,7 +7046,24 @@ var SqliteTasksetDraftStore = class extends SqlitePreferenceComparisonStore {
6447
7046
  }
6448
7047
  async deleteTasksetDraft(id) {
6449
7048
  await this.ready;
6450
- const write = this.writeQueue.then(() => this.run("DELETE FROM taskset_drafts WHERE id = ?", [id]));
7049
+ const workspacePath = this.workspacePath(id);
7050
+ const recoverablePath = `${workspacePath}.delete-${randomUUID2()}`;
7051
+ let movedWorkspace = false;
7052
+ try {
7053
+ await rename(workspacePath, recoverablePath);
7054
+ movedWorkspace = true;
7055
+ } catch (error) {
7056
+ if (error.code !== "ENOENT") throw error;
7057
+ }
7058
+ const write = this.writeQueue.then(async () => {
7059
+ try {
7060
+ await this.run("DELETE FROM taskset_drafts WHERE id = ?", [id]);
7061
+ } catch (error) {
7062
+ if (movedWorkspace) await rename(recoverablePath, workspacePath).catch(() => void 0);
7063
+ throw error;
7064
+ }
7065
+ if (movedWorkspace) await rm(recoverablePath, { recursive: true, force: true });
7066
+ });
6451
7067
  this.writeQueue = write.catch(() => void 0);
6452
7068
  await write;
6453
7069
  }
@@ -6509,6 +7125,41 @@ var SqliteTasksetDraftStore = class extends SqlitePreferenceComparisonStore {
6509
7125
  );
6510
7126
  }
6511
7127
  };
7128
+ async function assertRegularPackageTree(directory) {
7129
+ const entries = await readdir2(directory, { withFileTypes: true });
7130
+ for (const entry of entries) {
7131
+ const entryPath = path6.join(directory, entry.name);
7132
+ if (entry.isSymbolicLink()) {
7133
+ throw new Error(`Taskset packages cannot contain symbolic links: ${entryPath}`);
7134
+ }
7135
+ if (entry.isDirectory()) {
7136
+ await assertRegularPackageTree(entryPath);
7137
+ continue;
7138
+ }
7139
+ if (!entry.isFile()) {
7140
+ throw new Error(`Taskset packages may contain only files and directories: ${entryPath}`);
7141
+ }
7142
+ }
7143
+ }
7144
+ async function verifyPublishedTasksetAssets(tasksetRoot, taskset) {
7145
+ const assetRoot = path6.resolve(tasksetRoot, "assets");
7146
+ for (const task of taskset.tasks) {
7147
+ for (const asset3 of task.assets ?? []) {
7148
+ const assetPath = path6.resolve(tasksetRoot, asset3.artifactRef);
7149
+ if (assetPath === assetRoot || !assetPath.startsWith(`${assetRoot}${path6.sep}`)) {
7150
+ throw new Error(`Taskset asset ${asset3.id} escapes the package assets directory.`);
7151
+ }
7152
+ const status = await lstat(assetPath);
7153
+ if (!status.isFile() || status.isSymbolicLink()) {
7154
+ throw new Error(`Taskset asset ${asset3.id} is not a regular file.`);
7155
+ }
7156
+ const bytes = await readFile3(assetPath);
7157
+ if (bytes.byteLength !== asset3.sizeBytes || sha256(bytes) !== asset3.sha256) {
7158
+ throw new Error(`Taskset asset ${asset3.id} does not match its immutable manifest.`);
7159
+ }
7160
+ }
7161
+ }
7162
+ }
6512
7163
 
6513
7164
  // ../server/src/store/store-training-search.ts
6514
7165
  function trainingChatSearchResult(query, offset, limit, total, rows, indexedChats, totalChats) {
@@ -7088,6 +7739,10 @@ var SqliteTrainingStore = class extends SqliteTasksetDraftStore {
7088
7739
  }
7089
7740
  async saveTrainingPlan(planInput) {
7090
7741
  const plan2 = TrainingPlanSchema.parse(planInput);
7742
+ const existing = await this.getTrainingPlan(plan2.id);
7743
+ if (existing && existing.contentHash !== plan2.contentHash) {
7744
+ throw new Error(`Training Plan ${plan2.id} is immutable and already has different content.`);
7745
+ }
7091
7746
  await this.upsertPayload(
7092
7747
  `INSERT INTO training_plans (id, taskset_id, destination_id, payload, created_at) VALUES (?, ?, ?, ?, ?)
7093
7748
  ON CONFLICT(id) DO UPDATE SET taskset_id = excluded.taskset_id, destination_id = excluded.destination_id, payload = excluded.payload`,
@@ -8885,7 +9540,7 @@ async function createLocalHarnessWorkspaceFromInitializer(input) {
8885
9540
  const paths = localHarnessWorkspacePaths(input.storeDir, input.id);
8886
9541
  const parent = path7.dirname(paths.root);
8887
9542
  await fs4.mkdir(parent, { recursive: true });
8888
- const temporaryRoot = path7.join(parent, `.${path7.basename(paths.root)}.creating-${randomUUID2()}`);
9543
+ const temporaryRoot = path7.join(parent, `.${path7.basename(paths.root)}.creating-${randomUUID3()}`);
8889
9544
  const temporarySource = path7.join(temporaryRoot, "source");
8890
9545
  try {
8891
9546
  await input.initializeSource(temporarySource);
@@ -9032,7 +9687,7 @@ async function materializeLocalHarnessRelease(input) {
9032
9687
  const releasesRoot = path7.join(input.storeDir, "harnesses", "releases");
9033
9688
  const destination = path7.join(releasesRoot, input.compiled.harnessRelease.contentHash);
9034
9689
  await fs4.mkdir(releasesRoot, { recursive: true });
9035
- const temporary = path7.join(releasesRoot, `.${input.compiled.harnessRelease.contentHash}.materializing-${randomUUID2()}`);
9690
+ const temporary = path7.join(releasesRoot, `.${input.compiled.harnessRelease.contentHash}.materializing-${randomUUID3()}`);
9036
9691
  try {
9037
9692
  await fs4.mkdir(path7.join(temporary, "source"), { recursive: true });
9038
9693
  for (const file of input.compiled.sourceFiles) {
@@ -9404,7 +10059,7 @@ function safeSegment(value) {
9404
10059
  }
9405
10060
 
9406
10061
  // ../server/src/harness/local-harness-refiner.ts
9407
- import { randomUUID as randomUUID3 } from "node:crypto";
10062
+ import { randomUUID as randomUUID4 } from "node:crypto";
9408
10063
  import { promises as fs5 } from "node:fs";
9409
10064
  import { stripTypeScriptTypes } from "node:module";
9410
10065
  import path8 from "node:path";
@@ -9452,7 +10107,7 @@ async function applyLocalHarnessRefinerProposal(input) {
9452
10107
  `Harness source is ${current.sourceRevision}; workspace expects ${workspace.sourceRevision}. Record or revert the source change before refinement.`
9453
10108
  );
9454
10109
  }
9455
- const candidateSource = path8.join(paths.root, `.source-candidate-${randomUUID3()}`);
10110
+ const candidateSource = path8.join(paths.root, `.source-candidate-${randomUUID4()}`);
9456
10111
  await fs5.cp(paths.source, candidateSource, {
9457
10112
  recursive: true,
9458
10113
  force: false,
@@ -9497,7 +10152,7 @@ async function applyLocalHarnessRefinerProposal(input) {
9497
10152
  now: timestamp
9498
10153
  });
9499
10154
  }
9500
- const backupSource = path8.join(paths.root, `.source-backup-${randomUUID3()}`);
10155
+ const backupSource = path8.join(paths.root, `.source-backup-${randomUUID4()}`);
9501
10156
  const journalPath = path8.join(paths.root, "source-swap.json");
9502
10157
  await writeSwapJournal(journalPath, {
9503
10158
  schemaVersion: "openpond.localHarnessSourceSwap.v1",
@@ -9572,7 +10227,7 @@ async function rollbackLocalHarnessWorkspaceRelease(input) {
9572
10227
  if (current.sourceRevision !== workspace.sourceRevision) {
9573
10228
  throw new Error("Harness source changed before rollback.");
9574
10229
  }
9575
- const candidateSource = path8.join(paths.root, `.source-rollback-${randomUUID3()}`);
10230
+ const candidateSource = path8.join(paths.root, `.source-rollback-${randomUUID4()}`);
9576
10231
  await fs5.cp(path8.join(target.bundlePath, "source"), candidateSource, {
9577
10232
  recursive: true,
9578
10233
  force: false,
@@ -9588,7 +10243,7 @@ async function rollbackLocalHarnessWorkspaceRelease(input) {
9588
10243
  throw new Error("Harness rollback bundle does not reproduce its registered source revision.");
9589
10244
  }
9590
10245
  const timestamp = (input.now ?? (() => (/* @__PURE__ */ new Date()).toISOString()))();
9591
- const backupSource = path8.join(paths.root, `.source-backup-${randomUUID3()}`);
10246
+ const backupSource = path8.join(paths.root, `.source-backup-${randomUUID4()}`);
9592
10247
  const journalPath = path8.join(paths.root, "source-swap.json");
9593
10248
  await writeSwapJournal(journalPath, {
9594
10249
  schemaVersion: "openpond.localHarnessSourceSwap.v1",
@@ -9647,7 +10302,7 @@ async function validateLocalHarnessRefinerProposal(input) {
9647
10302
  "Refiner proposal source revision no longer matches the Local Harness workspace."
9648
10303
  );
9649
10304
  }
9650
- const candidateSource = path8.join(paths.root, `.validation-candidate-${randomUUID3()}`);
10305
+ const candidateSource = path8.join(paths.root, `.validation-candidate-${randomUUID4()}`);
9651
10306
  await fs5.cp(paths.source, candidateSource, {
9652
10307
  recursive: true,
9653
10308
  force: false,
@@ -9999,7 +10654,7 @@ function containedPath(root, relativePath) {
9999
10654
  return target;
10000
10655
  }
10001
10656
  async function writeSwapJournal(filePath, value) {
10002
- const temporary = `${filePath}.${randomUUID3()}.tmp`;
10657
+ const temporary = `${filePath}.${randomUUID4()}.tmp`;
10003
10658
  await fs5.writeFile(temporary, `${JSON.stringify(value, null, 2)}
10004
10659
  `, { flag: "wx" });
10005
10660
  await fs5.rename(temporary, filePath);
@@ -11530,7 +12185,7 @@ async function loadRefinerReleaseContext(input) {
11530
12185
  }
11531
12186
 
11532
12187
  // ../server/src/refiner/refiner-profile-service.ts
11533
- import { randomUUID as randomUUID4 } from "node:crypto";
12188
+ import { randomUUID as randomUUID5 } from "node:crypto";
11534
12189
  import { promises as fs8 } from "node:fs";
11535
12190
  import path12 from "node:path";
11536
12191
  var CORE_PROMPT_IDENTITY = "OpenPond Refiner Core: evidence admission, privacy, ownership, validation, and immutable activation boundaries.";
@@ -11691,7 +12346,7 @@ async function transition2(paths, release, input) {
11691
12346
  const releaseRef = immutableRef(release);
11692
12347
  const receiptWithoutHash = {
11693
12348
  schemaVersion: "openpond.refinerTransitionReceipt.v1",
11694
- id: `refiner-transition-${randomUUID4()}`,
12349
+ id: `refiner-transition-${randomUUID5()}`,
11695
12350
  operation: input.operation,
11696
12351
  bindingChanged: input.bindingChanged,
11697
12352
  previousRelease: previous?.release ?? null,
@@ -11746,7 +12401,7 @@ async function exists(filePath) {
11746
12401
  async function atomicWrite(filePath, contents, preserveExisting = false) {
11747
12402
  await fs8.mkdir(path12.dirname(filePath), { recursive: true, mode: 448 });
11748
12403
  if (preserveExisting && await exists(filePath)) return;
11749
- const temporaryPath = `${filePath}.${randomUUID4()}.tmp`;
12404
+ const temporaryPath = `${filePath}.${randomUUID5()}.tmp`;
11750
12405
  await fs8.writeFile(temporaryPath, contents, { encoding: "utf8", mode: 384 });
11751
12406
  await fs8.rename(temporaryPath, filePath);
11752
12407
  }
@@ -14066,7 +14721,7 @@ function expectedMemoryRevision2(proposal, key) {
14066
14721
  }
14067
14722
 
14068
14723
  // ../server/src/runtime/model-usage-recorder.ts
14069
- import { randomUUID as randomUUID5 } from "node:crypto";
14724
+ import { randomUUID as randomUUID6 } from "node:crypto";
14070
14725
 
14071
14726
  // ../server/src/openpond/openai-compatible-provider.ts
14072
14727
  import { createHash as createHash3 } from "node:crypto";
@@ -14603,17 +15258,19 @@ async function* streamOpenAiSubscriptionResponses(input) {
14603
15258
  saveChatGptSubscriptionCredential: input.saveChatGptSubscriptionCredential
14604
15259
  });
14605
15260
  if (!credential.accessToken) throw new Error("OpenAI ChatGPT subscription credential has no access token.");
15261
+ const promptCacheKey = normalizedPromptCacheKey(input.promptCacheKey);
14606
15262
  const requestSignal = createProviderRequestSignal(input.signal, input.requestTimeoutMs);
14607
15263
  try {
14608
15264
  const response = await fetch(OPENAI_CODEX_RESPONSES_ENDPOINT, {
14609
15265
  method: "POST",
14610
- headers: subscriptionHeaders(credential, input.requestId),
15266
+ headers: subscriptionHeaders(credential, promptCacheKey ?? input.requestId),
14611
15267
  body: JSON.stringify(buildResponsesBody({
14612
15268
  model: input.provider.model,
14613
15269
  messages: input.messages,
14614
15270
  tools: input.tools,
14615
15271
  toolChoice: input.toolChoice,
14616
- reasoningEffort: input.reasoningEffort
15272
+ reasoningEffort: input.reasoningEffort,
15273
+ promptCacheKey
14617
15274
  })),
14618
15275
  signal: requestSignal.signal
14619
15276
  });
@@ -14733,6 +15390,7 @@ function buildResponsesBody(input) {
14733
15390
  store: false
14734
15391
  };
14735
15392
  if (projected.instructions) body.instructions = projected.instructions;
15393
+ if (input.promptCacheKey) body.prompt_cache_key = input.promptCacheKey;
14736
15394
  body.reasoning = {
14737
15395
  ...input.reasoningEffort ? { effort: input.reasoningEffort } : {},
14738
15396
  summary: "auto"
@@ -14746,6 +15404,11 @@ function buildResponsesBody(input) {
14746
15404
  if (toolChoice !== void 0) body.tool_choice = toolChoice;
14747
15405
  return body;
14748
15406
  }
15407
+ function normalizedPromptCacheKey(value) {
15408
+ const trimmed = value?.trim();
15409
+ if (!trimmed) return void 0;
15410
+ return trimmed.length <= 64 ? trimmed : createHash3("sha256").update(trimmed).digest("hex");
15411
+ }
14749
15412
  function responsesInputFromMessages(messages) {
14750
15413
  const instructions = [];
14751
15414
  const input = [];
@@ -15430,7 +16093,7 @@ function createProviderRequestUsageRecord(input) {
15430
16093
  const completedAt = input.completedAt;
15431
16094
  const errorMessage4 = input.error ? textFromUnknown(input.error) || null : null;
15432
16095
  return {
15433
- id: `usage_${randomUUID5()}`,
16096
+ id: `usage_${randomUUID6()}`,
15434
16097
  requestId: input.requestId,
15435
16098
  requestOrdinal: input.requestOrdinal,
15436
16099
  sessionId: input.session.id,
@@ -16060,7 +16723,7 @@ import path15 from "node:path";
16060
16723
 
16061
16724
  // ../server/src/runtime/bundled-authoring-skills.ts
16062
16725
  import { createHash as createHash4 } from "node:crypto";
16063
- import { access as access2, readFile as readFile3 } from "node:fs/promises";
16726
+ import { access as access2, readFile as readFile4 } from "node:fs/promises";
16064
16727
  import path14 from "node:path";
16065
16728
  import { fileURLToPath } from "node:url";
16066
16729
  var BUNDLED_AUTHORING_SKILL_NAMES = [
@@ -16125,8 +16788,8 @@ async function readBundledAuthoringProfileSkill(name, repoRoot = process.cwd())
16125
16788
  async function loadBundledAuthoringSkillBundle(name, repoRoot = process.cwd()) {
16126
16789
  const root = await resolveBundledAuthoringSkillRoot(name, repoRoot);
16127
16790
  const [skill, ...references] = await Promise.all([
16128
- readFile3(path14.join(root, "SKILL.md"), "utf8"),
16129
- ...REFERENCE_FILES[name].map((relativePath) => readFile3(path14.join(root, relativePath), "utf8"))
16791
+ readFile4(path14.join(root, "SKILL.md"), "utf8"),
16792
+ ...REFERENCE_FILES[name].map((relativePath) => readFile4(path14.join(root, relativePath), "utf8"))
16130
16793
  ]);
16131
16794
  return [
16132
16795
  skill.trim(),
@@ -16489,7 +17152,7 @@ function containedSourcePath2(sourceRoot, relativePath) {
16489
17152
  // ../server/src/openpond/command-access.ts
16490
17153
  var import_shell_quote = __toESM(require_shell_quote(), 1);
16491
17154
  import { spawn } from "node:child_process";
16492
- import { randomUUID as randomUUID6 } from "node:crypto";
17155
+ import { randomUUID as randomUUID7 } from "node:crypto";
16493
17156
  import path16 from "node:path";
16494
17157
 
16495
17158
  // ../server/src/workspace/workspace-execution-target.ts
@@ -16660,7 +17323,7 @@ function createOpenPondCommandAccessService(deps) {
16660
17323
  }
16661
17324
  async function requestCommandApproval(input) {
16662
17325
  const approval = {
16663
- id: `approval_${randomUUID6()}`,
17326
+ id: `approval_${randomUUID7()}`,
16664
17327
  sessionId: input.input.session.id,
16665
17328
  turnId: input.input.turnId ?? null,
16666
17329
  providerRequestId: input.input.providerRequestId ?? input.input.turnId ?? input.input.session.id,
@@ -17183,6 +17846,13 @@ function errorMessage(error) {
17183
17846
  import { promises as fs13 } from "node:fs";
17184
17847
  import path20 from "node:path";
17185
17848
 
17849
+ // ../server/src/work/managed-local-work.ts
17850
+ function isManagedLocalWorkSession(session) {
17851
+ return Boolean(
17852
+ session.experience === "work" && !session.workspaceKind && !session.localProjectId && !session.cloudProjectId && session.metadata?.workspaceTarget === "local" && session.cwd
17853
+ );
17854
+ }
17855
+
17186
17856
  // ../server/src/openpond/context-usage.ts
17187
17857
  var ESTIMATED_CHARS_PER_TOKEN = 4;
17188
17858
  var DEFAULT_HOSTED_CONTEXT_TOKENS = 128e3;
@@ -18137,8 +18807,8 @@ function buildRepositoryInstructionContext(resolution) {
18137
18807
  async function canonicalDirectory(inputPath) {
18138
18808
  try {
18139
18809
  const resolved = await fs12.realpath(path19.resolve(inputPath));
18140
- const stat = await fs12.stat(resolved);
18141
- return stat.isDirectory() ? resolved : null;
18810
+ const stat2 = await fs12.stat(resolved);
18811
+ return stat2.isDirectory() ? resolved : null;
18142
18812
  } catch {
18143
18813
  return null;
18144
18814
  }
@@ -18188,14 +18858,14 @@ async function readInstructionCandidate(input) {
18188
18858
  };
18189
18859
  }
18190
18860
  try {
18191
- const stat = await fs12.stat(realPath);
18192
- if (!stat.isFile()) {
18861
+ const stat2 = await fs12.stat(realPath);
18862
+ if (!stat2.isFile()) {
18193
18863
  return {
18194
18864
  status: "rejected",
18195
18865
  diagnostic: `Skipped repository instruction path that is not a file: ${candidatePath}`
18196
18866
  };
18197
18867
  }
18198
- if (stat.size > MAX_REPOSITORY_INSTRUCTION_FILE_BYTES) {
18868
+ if (stat2.size > MAX_REPOSITORY_INSTRUCTION_FILE_BYTES) {
18199
18869
  return {
18200
18870
  status: "rejected",
18201
18871
  diagnostic: `Skipped repository instruction file larger than ${MAX_REPOSITORY_INSTRUCTION_FILE_BYTES} bytes: ${candidatePath}`
@@ -18227,7 +18897,12 @@ function isWithinDirectory(rootPath, candidatePath) {
18227
18897
  }
18228
18898
 
18229
18899
  // ../server/src/runtime/experience-policy.ts
18230
- var CHAT_MODEL_TOOLS = /* @__PURE__ */ new Set(["view_image", "web_fetch", "web_search"]);
18900
+ var CHAT_MODEL_TOOLS = /* @__PURE__ */ new Set([
18901
+ "schedule_work",
18902
+ "view_image",
18903
+ "web_fetch",
18904
+ "web_search"
18905
+ ]);
18231
18906
  var WORK_MODEL_TOOLS = /* @__PURE__ */ new Set([
18232
18907
  "ask_user",
18233
18908
  "connected_app_read",
@@ -18409,7 +19084,7 @@ function createHostedTurnHelpers(deps) {
18409
19084
  }
18410
19085
  repositoryInstructionContext = buildRepositoryInstructionContext(resolution);
18411
19086
  }
18412
- const workspaceContext = experience === "chat" ? buildChatExperienceContext() : experience === "work" && !repositoryWork ? buildWorkExperienceContext(session) : session.workspaceKind === "local_project" ? await looksLikeSandboxTemplateRepo(session.cwd) ? buildLocalSandboxTemplateTurnContext(
19087
+ const workspaceContext = experience === "chat" ? buildChatExperienceContext() : experience === "work" && !repositoryWork ? buildWorkExperienceContext(session) : isManagedLocalWorkSession(session) ? buildManagedLocalWorkTurnContext(session.cwd) : session.workspaceKind === "local_project" ? await looksLikeSandboxTemplateRepo(session.cwd) ? buildLocalSandboxTemplateTurnContext(
18413
19088
  session.cwd,
18414
19089
  toolInstructionMode
18415
19090
  ) : buildLocalProjectTurnContext(session.cwd, toolInstructionMode) : session.workspaceKind === "sandbox" || session.workspaceKind === "sandbox_template" ? isHybridSession ? buildHybridSandboxTurnContext(
@@ -18513,6 +19188,7 @@ function buildOpenPondCapabilityIndexContext(input = {}) {
18513
19188
  ] : [],
18514
19189
  "- web_fetch: fetch and read a known HTTP(S) URL when the user provides a link or exact page; use web_search for discovery by query.",
18515
19190
  "- web_search: search current or external information when web search is available and the answer depends on current facts.",
19191
+ "- schedule_work: create a durable one-time or recurring workflow attached to the current chat when the user asks to schedule work. Resolve the exact cadence, local date/time, and timezone, then call schedule_work; future runs and their output return to the attached chat. This is an app-native tool, not a profile skill.",
18516
19192
  "- action_run: search and run scoped project or profile actions from the allowed action catalog.",
18517
19193
  "- profile_skill: load existing profile skills for reusable instruction workflows, not app-native controls or permissions.",
18518
19194
  "- Capability names are not slash commands. Use available native tools or server-confirmed workflow state, and do not claim a workflow started unless server state confirms it."
@@ -18656,6 +19332,16 @@ function buildWorkExperienceContext(session) {
18656
19332
  "- Repository, git, interactive terminal, source-promotion, and deployment capabilities require repository-aware Work and are not available in this projectless run."
18657
19333
  ].join("\n");
18658
19334
  }
19335
+ function buildManagedLocalWorkTurnContext(workspacePath) {
19336
+ return [
19337
+ "Local Work experience:",
19338
+ workspacePath ? `- Managed task workspace: ${workspacePath}.` : null,
19339
+ "- Work directly in this app-managed task directory. It is not a user-selected software repository.",
19340
+ "- Keep scratch files organized, and do not read or write outside this task directory unless the user explicitly asks.",
19341
+ "- In the final response, link every finished file the user should keep or download. Linked files are validated and copied into durable Outputs storage at turn completion.",
19342
+ "- Do not label a file as downloadable unless it exists in this task directory and is ready for review."
19343
+ ].filter(Boolean).join("\n");
19344
+ }
18659
19345
  function buildLocalProjectTurnContext(workspacePath, toolInstructionMode) {
18660
19346
  if (toolInstructionMode !== "full_text_fallback") {
18661
19347
  return [
@@ -22707,7 +23393,7 @@ function hostedWebBaseUrl(env = process.env) {
22707
23393
  }
22708
23394
 
22709
23395
  // ../server/src/api/server-payload-helpers.ts
22710
- import { randomUUID as randomUUID7 } from "node:crypto";
23396
+ import { randomUUID as randomUUID8 } from "node:crypto";
22711
23397
 
22712
23398
  // ../server/src/openpond/organizations.ts
22713
23399
  var DEFAULT_OPENPOND_API_BASE_URL3 = "https://api.openpond.ai";
@@ -22951,25 +23637,25 @@ async function selectLocalProjectSourceFiles(project) {
22951
23637
  continue;
22952
23638
  }
22953
23639
  try {
22954
- const stat = await fs14.lstat(absolutePath);
22955
- if (!stat.isFile()) {
23640
+ const stat2 = await fs14.lstat(absolutePath);
23641
+ if (!stat2.isFile()) {
22956
23642
  skipped.push({ path: normalizedPath, reason: "not_file" });
22957
23643
  continue;
22958
23644
  }
22959
- if (stat.size > MAX_SOURCE_UPLOAD_FILE_BYTES) {
22960
- skipped.push({ path: normalizedPath, reason: "too_large", sizeBytes: stat.size });
23645
+ if (stat2.size > MAX_SOURCE_UPLOAD_FILE_BYTES) {
23646
+ skipped.push({ path: normalizedPath, reason: "too_large", sizeBytes: stat2.size });
22961
23647
  continue;
22962
23648
  }
22963
- if (totalBytes + stat.size > MAX_SOURCE_UPLOAD_TOTAL_BYTES) {
22964
- skipped.push({ path: normalizedPath, reason: "total_limit", sizeBytes: stat.size });
23649
+ if (totalBytes + stat2.size > MAX_SOURCE_UPLOAD_TOTAL_BYTES) {
23650
+ skipped.push({ path: normalizedPath, reason: "total_limit", sizeBytes: stat2.size });
22965
23651
  continue;
22966
23652
  }
22967
23653
  files.push({
22968
23654
  path: normalizedPath,
22969
23655
  absolutePath,
22970
- sizeBytes: stat.size
23656
+ sizeBytes: stat2.size
22971
23657
  });
22972
- totalBytes += stat.size;
23658
+ totalBytes += stat2.size;
22973
23659
  } catch {
22974
23660
  skipped.push({ path: normalizedPath, reason: "read_error" });
22975
23661
  }
@@ -23438,7 +24124,7 @@ function codexHistoryThreadReadOptions(requestUrl) {
23438
24124
  };
23439
24125
  }
23440
24126
  function nextCodexHistoryTurnId(sessionId) {
23441
- return `${sessionId}_turn_attachment_${randomUUID7()}`;
24127
+ return `${sessionId}_turn_attachment_${randomUUID8()}`;
23442
24128
  }
23443
24129
  function positiveIntegerParam(value) {
23444
24130
  if (!value) return void 0;
@@ -24707,7 +25393,7 @@ function stringValue4(value) {
24707
25393
  }
24708
25394
 
24709
25395
  // ../server/src/runtime/background-worker-queue.ts
24710
- import { randomUUID as randomUUID8 } from "node:crypto";
25396
+ import { randomUUID as randomUUID9 } from "node:crypto";
24711
25397
  var MAX_RETAINED_RECEIPTS = 200;
24712
25398
  function createBackgroundWorkerQueue(options) {
24713
25399
  const maxRetainedReceipts = options.maxRetainedReceipts ?? MAX_RETAINED_RECEIPTS;
@@ -24716,7 +25402,7 @@ function createBackgroundWorkerQueue(options) {
24716
25402
  let tail = Promise.resolve();
24717
25403
  function enqueue(job, work) {
24718
25404
  const receipt = {
24719
- id: randomUUID8(),
25405
+ id: randomUUID9(),
24720
25406
  queueId: options.queueId,
24721
25407
  label: job.label,
24722
25408
  enqueuedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -24783,12 +25469,17 @@ function createServerWorkQueues(logger) {
24783
25469
  queueId: "local-agent-schedule",
24784
25470
  logger
24785
25471
  });
25472
+ const chatWorkflow = createBackgroundWorkerQueue({
25473
+ queueId: "chat-workflow",
25474
+ logger
25475
+ });
24786
25476
  const subagent = createBackgroundWorkerQueue({ queueId: "subagent", logger });
24787
25477
  const subagentLifecycle = createBackgroundWorkerQueue({ queueId: "subagent-lifecycle", logger });
24788
25478
  const byId = {
24789
25479
  "turn-follow-up": turnFollowUp,
24790
25480
  "checkpoint-diff": checkpointDiff,
24791
25481
  "provider-runtime-ingestion": providerRuntimeIngestion,
25482
+ "chat-workflow": chatWorkflow,
24792
25483
  "local-agent-schedule": localAgentSchedule,
24793
25484
  subagent,
24794
25485
  "subagent-lifecycle": subagentLifecycle
@@ -24797,6 +25488,7 @@ function createServerWorkQueues(logger) {
24797
25488
  turnFollowUp,
24798
25489
  checkpointDiff,
24799
25490
  providerRuntimeIngestion,
25491
+ chatWorkflow,
24800
25492
  localAgentSchedule,
24801
25493
  subagent,
24802
25494
  subagentLifecycle,
@@ -24880,8 +25572,8 @@ async function nearestExistingParent(targetPath, root) {
24880
25572
  while (current !== path23.dirname(current)) {
24881
25573
  if (current === resolvedRoot || current.startsWith(`${resolvedRoot}${path23.sep}`)) {
24882
25574
  try {
24883
- const stat = await fs16.lstat(current);
24884
- if (stat.isDirectory()) return current;
25575
+ const stat2 = await fs16.lstat(current);
25576
+ if (stat2.isDirectory()) return current;
24885
25577
  } catch (error) {
24886
25578
  if (error.code !== "ENOENT") throw error;
24887
25579
  }
@@ -24927,8 +25619,8 @@ async function readWorkspaceFiles(repoPath, paths) {
24927
25619
  const files = [];
24928
25620
  for (const filePath of paths) {
24929
25621
  const { relativePath, targetPath } = await resolveForRead(repoPath, filePath);
24930
- const stat = await fs16.lstat(targetPath);
24931
- if (!stat.isFile()) throw new Error(`Not a file: ${relativePath}`);
25622
+ const stat2 = await fs16.lstat(targetPath);
25623
+ if (!stat2.isFile()) throw new Error(`Not a file: ${relativePath}`);
24932
25624
  const content = await fs16.readFile(targetPath, "utf8");
24933
25625
  files.push({
24934
25626
  path: relativePath,
@@ -24981,8 +25673,8 @@ async function editWorkspaceFile(repoPath, filePath, oldText, newText, options =
24981
25673
  }
24982
25674
  async function deleteWorkspaceFile(repoPath, filePath) {
24983
25675
  const { relativePath, targetPath } = await resolveForRead(repoPath, filePath);
24984
- const stat = await fs16.lstat(targetPath);
24985
- if (!stat.isFile()) throw new Error(`Not a file: ${relativePath}`);
25676
+ const stat2 = await fs16.lstat(targetPath);
25677
+ if (!stat2.isFile()) throw new Error(`Not a file: ${relativePath}`);
24986
25678
  await fs16.unlink(targetPath);
24987
25679
  return { path: relativePath };
24988
25680
  }
@@ -24994,8 +25686,8 @@ import path24 from "node:path";
24994
25686
  async function readExistingFile(repoPath, filePath) {
24995
25687
  const { targetPath } = await resolveForPreview(repoPath, filePath);
24996
25688
  try {
24997
- const stat = await fs17.lstat(targetPath);
24998
- if (!stat.isFile()) throw new Error(`Not a file: ${filePath}`);
25689
+ const stat2 = await fs17.lstat(targetPath);
25690
+ if (!stat2.isFile()) throw new Error(`Not a file: ${filePath}`);
24999
25691
  return await fs17.readFile(targetPath, "utf8");
25000
25692
  } catch (error) {
25001
25693
  if (error.code === "ENOENT") return null;
@@ -25083,8 +25775,8 @@ async function previewWorkspaceEditFile(repoPath, filePath, oldText, newText, op
25083
25775
  }
25084
25776
  async function previewWorkspaceDeleteFile(repoPath, filePath) {
25085
25777
  const { relativePath, targetPath } = await resolveForRead(repoPath, filePath);
25086
- const stat = await fs17.lstat(targetPath);
25087
- if (!stat.isFile()) throw new Error(`Not a file: ${relativePath}`);
25778
+ const stat2 = await fs17.lstat(targetPath);
25779
+ if (!stat2.isFile()) throw new Error(`Not a file: ${relativePath}`);
25088
25780
  const file = await previewFileChange(repoPath, relativePath, null);
25089
25781
  return {
25090
25782
  filesChanged: 1,
@@ -25151,9 +25843,9 @@ async function ensureWorkspaceGitRepository(repoPath, branch = "main") {
25151
25843
  if (init.code !== 0) {
25152
25844
  throw new Error(init.stderr.trim() || init.stdout.trim() || "git init failed");
25153
25845
  }
25154
- const rename = await runCommand("git", ["branch", "-M", branch], repoPath);
25155
- if (rename.code !== 0) {
25156
- throw new Error(rename.stderr.trim() || rename.stdout.trim() || "git branch setup failed");
25846
+ const rename2 = await runCommand("git", ["branch", "-M", branch], repoPath);
25847
+ if (rename2.code !== 0) {
25848
+ throw new Error(rename2.stderr.trim() || rename2.stdout.trim() || "git branch setup failed");
25157
25849
  }
25158
25850
  }
25159
25851
  }
@@ -25180,8 +25872,8 @@ async function lastFetchAt(repoPath) {
25180
25872
  const fetchHead = await runCommand("git", ["rev-parse", "--git-path", "FETCH_HEAD"], repoPath);
25181
25873
  const fetchHeadPath = fetchHead.code === 0 && fetchHead.stdout.trim() ? path25.resolve(repoPath, fetchHead.stdout.trim()) : path25.join(repoPath, ".git", "FETCH_HEAD");
25182
25874
  try {
25183
- const stat = await fs18.stat(fetchHeadPath);
25184
- return stat.mtime.toISOString();
25875
+ const stat2 = await fs18.stat(fetchHeadPath);
25876
+ return stat2.mtime.toISOString();
25185
25877
  } catch {
25186
25878
  return null;
25187
25879
  }
@@ -25641,10 +26333,10 @@ async function readWorkspaceSearchText(repoPath, filePath) {
25641
26333
  if (BINARY_EXTENSIONS.has(path26.extname(filePath).toLowerCase())) return null;
25642
26334
  try {
25643
26335
  const { targetPath } = await resolveForRead(repoPath, filePath);
25644
- const stat = await fs19.lstat(targetPath);
25645
- if (!stat.isFile()) return null;
25646
- const text = await readTextSample(targetPath, stat.size);
25647
- return text.includes("\0") ? null : { text, truncated: stat.size > WORKSPACE_SEARCH_MAX_BYTES };
26336
+ const stat2 = await fs19.lstat(targetPath);
26337
+ if (!stat2.isFile()) return null;
26338
+ const text = await readTextSample(targetPath, stat2.size);
26339
+ return text.includes("\0") ? null : { text, truncated: stat2.size > WORKSPACE_SEARCH_MAX_BYTES };
25648
26340
  } catch {
25649
26341
  return null;
25650
26342
  }
@@ -26197,15 +26889,15 @@ function parseResourceRef(ref) {
26197
26889
  async function readWorkspaceFileResource(repoPath, identifier, request) {
26198
26890
  const filePath = normalizeRequiredWorkspacePath(identifier);
26199
26891
  const targetPath = await resolveWorkspacePath(repoPath, filePath);
26200
- const stat = await fs20.lstat(targetPath);
26201
- if (!stat.isFile()) throw new Error(`Not a file resource: ${filePath}`);
26892
+ const stat2 = await fs20.lstat(targetPath);
26893
+ if (!stat2.isFile()) throw new Error(`Not a file resource: ${filePath}`);
26202
26894
  const contentType = contentTypeForPath(filePath);
26203
26895
  const maxBytes = normalizeMaxBytes(request.maxBytes);
26204
26896
  const binary = await isBinaryFile(targetPath, filePath);
26205
26897
  const metadata = {
26206
26898
  path: filePath,
26207
- sizeBytes: stat.size,
26208
- modifiedAt: stat.mtime.toISOString(),
26899
+ sizeBytes: stat2.size,
26900
+ modifiedAt: stat2.mtime.toISOString(),
26209
26901
  binary
26210
26902
  };
26211
26903
  if (request.mode === "metadata" || binary) {
@@ -26218,13 +26910,13 @@ async function readWorkspaceFileResource(repoPath, identifier, request) {
26218
26910
  relatedRefs: [],
26219
26911
  truncation: {
26220
26912
  truncated: false,
26221
- originalBytes: stat.size,
26913
+ originalBytes: stat2.size,
26222
26914
  returnedBytes: 0,
26223
26915
  reason: binary ? "binary" : void 0
26224
26916
  }
26225
26917
  };
26226
26918
  }
26227
- const content = await readTextWithLimit(targetPath, stat.size, maxBytes);
26919
+ const content = await readTextWithLimit(targetPath, stat2.size, maxBytes);
26228
26920
  return {
26229
26921
  ref: workspaceFileRef2(filePath),
26230
26922
  kind: "workspace.file",
@@ -26242,8 +26934,8 @@ async function readWorkspaceFileResource(repoPath, identifier, request) {
26242
26934
  async function readWorkspaceDirectoryResource(repoPath, identifier, request) {
26243
26935
  const dirPath = normalizeOptionalWorkspacePath(identifier);
26244
26936
  const targetPath = await resolveWorkspacePath(repoPath, dirPath);
26245
- const stat = await fs20.lstat(targetPath);
26246
- if (!stat.isDirectory()) throw new Error(`Not a directory resource: ${dirPath || "."}`);
26937
+ const stat2 = await fs20.lstat(targetPath);
26938
+ if (!stat2.isDirectory()) throw new Error(`Not a directory resource: ${dirPath || "."}`);
26247
26939
  const entries = await fs20.readdir(targetPath, { withFileTypes: true });
26248
26940
  const visible = entries.map((entry) => {
26249
26941
  const entryPath = dirPath ? `${dirPath}/${entry.name}` : entry.name;
@@ -26268,7 +26960,7 @@ async function readWorkspaceDirectoryResource(repoPath, identifier, request) {
26268
26960
  path: dirPath,
26269
26961
  entryCount: visible.length,
26270
26962
  entries: visible,
26271
- modifiedAt: stat.mtime.toISOString()
26963
+ modifiedAt: stat2.mtime.toISOString()
26272
26964
  },
26273
26965
  relatedRefs: visible.slice(0, 50).map((entry) => entry.ref),
26274
26966
  truncation: content.truncation
@@ -27701,13 +28393,13 @@ function notificationMethod(name) {
27701
28393
  }
27702
28394
 
27703
28395
  // ../server/src/harness/local-harness-evaluation-review-model.ts
27704
- import { randomUUID as randomUUID9 } from "node:crypto";
28396
+ import { randomUUID as randomUUID10 } from "node:crypto";
27705
28397
  function createLocalHarnessEvaluationReviewModelStream(streamOpenPondHostedChatTurn2) {
27706
28398
  return async function* ({ messages, signal }) {
27707
28399
  for await (const delta of streamOpenPondHostedChatTurn2({
27708
28400
  model: DEFAULT_HARNESS_REFINER_MODEL,
27709
28401
  messages,
27710
- requestId: `harness-continuous-review:${randomUUID9()}`,
28402
+ requestId: `harness-continuous-review:${randomUUID10()}`,
27711
28403
  reasoningEffort: "medium",
27712
28404
  maxTokens: DEFAULT_EVALUATION_REVIEW_MAX_OUTPUT_TOKENS,
27713
28405
  signal
@@ -27956,7 +28648,7 @@ function uniqueObjects(values) {
27956
28648
  }
27957
28649
 
27958
28650
  // ../server/src/training/task-authoring-skill.ts
27959
- import { access as access3, readFile as readFile4 } from "node:fs/promises";
28651
+ import { access as access3, readFile as readFile5 } from "node:fs/promises";
27960
28652
  import { createHash as createHash5 } from "node:crypto";
27961
28653
  import path29 from "node:path";
27962
28654
  import { fileURLToPath as fileURLToPath2 } from "node:url";
@@ -27969,7 +28661,7 @@ async function loadTasksetAuthoringSkillBundle(repoRoot = process.cwd()) {
27969
28661
  async function loadTasksetAuthoringSkillArtifact(repoRoot = process.cwd()) {
27970
28662
  const skillRoot = await resolveTasksetAuthoringSkillRoot(repoRoot);
27971
28663
  const parsed = JSON.parse(
27972
- await readFile4(path29.join(skillRoot, SKILL_ARTIFACT_FILE), "utf8")
28664
+ await readFile5(path29.join(skillRoot, SKILL_ARTIFACT_FILE), "utf8")
27973
28665
  );
27974
28666
  if (parsed.schemaVersion !== 1 || parsed.skillName !== SKILL_DIRECTORY || !parsed.artifactVersion || !parsed.bundle || !/^[a-f0-9]{64}$/.test(parsed.contentHash)) {
27975
28667
  throw new Error("Bundled Taskset Authoring artifact is invalid.");
@@ -28038,7 +28730,7 @@ async function resolveTasksetAuthoringSkillRoot(repoRoot = process.cwd(), execut
28038
28730
  }
28039
28731
 
28040
28732
  // ../server/src/training/task-creator.ts
28041
- import { randomUUID as randomUUID11 } from "node:crypto";
28733
+ import { randomUUID as randomUUID12 } from "node:crypto";
28042
28734
  import path31 from "node:path";
28043
28735
 
28044
28736
  // ../server/src/training/privacy.ts
@@ -28128,7 +28820,7 @@ import { Buffer as Buffer3 } from "node:buffer";
28128
28820
  import { execFile as execFile2, spawn as spawn2 } from "node:child_process";
28129
28821
  import { tmpdir } from "node:os";
28130
28822
  import readline from "node:readline";
28131
- import { randomUUID as randomUUID10 } from "node:crypto";
28823
+ import { randomUUID as randomUUID11 } from "node:crypto";
28132
28824
  import { promisify as promisify2 } from "node:util";
28133
28825
  var execFileAsync2 = promisify2(execFile2);
28134
28826
  var DEFAULT_MAX_MEMORY_BYTES = 256 * 1024 * 1024;
@@ -28234,7 +28926,7 @@ var PersistentPythonSandbox = class {
28234
28926
  if (this.closed) throw new Error("Python sandbox is closed.");
28235
28927
  if (Buffer.byteLength(code, "utf8") > 1e4) throw new Error("Python code exceeds the 10,000-byte limit.");
28236
28928
  if (signal?.aborted) throw abortError(signal);
28237
- const id = `python_${randomUUID10()}`;
28929
+ const id = `python_${randomUUID11()}`;
28238
28930
  const result2 = new Promise((resolve, reject) => {
28239
28931
  const timer = setTimeout(() => {
28240
28932
  this.pending.delete(id);
@@ -30548,7 +31240,7 @@ function createTaskCreatorService(deps) {
30548
31240
  state: "failed",
30549
31241
  blockedReason: "OpenPond restarted during Taskset authoring. The reviewed evidence and proposal were preserved; start authoring again to continue.",
30550
31242
  transcript: [...snapshot.transcript, {
30551
- id: `task_message_${randomUUID11()}`,
31243
+ id: `task_message_${randomUUID12()}`,
30552
31244
  role: "assistant",
30553
31245
  text: "Taskset authoring stopped when OpenPond restarted. The reviewed evidence and any completed proposal were preserved.",
30554
31246
  createdAt: timestamp
@@ -30567,7 +31259,7 @@ function createTaskCreatorService(deps) {
30567
31259
  const timestamp = now();
30568
31260
  const source = TrainingSourceRefSchema.parse({
30569
31261
  schemaVersion: "openpond.trainingSource.v1",
30570
- id: `training_source_${randomUUID11()}`,
31262
+ id: `training_source_${randomUUID12()}`,
30571
31263
  profileId: input.profileId,
30572
31264
  sessionId: input.sessionId,
30573
31265
  turnIds,
@@ -30622,10 +31314,10 @@ function createTaskCreatorService(deps) {
30622
31314
  const sources = await requireSources(input.profileId, input.sourceIds);
30623
31315
  assertSourcesEligible(sources);
30624
31316
  const timestamp = now();
30625
- const disclosureApprovalId = input.analysisModel && sources.length ? `task_disclosure_${randomUUID11()}` : null;
31317
+ const disclosureApprovalId = input.analysisModel && sources.length ? `task_disclosure_${randomUUID12()}` : null;
30626
31318
  const request = TaskCreationRequestSchema.parse({
30627
31319
  schemaVersion: "openpond.taskCreationRequest.v1",
30628
- id: `task_creation_request_${randomUUID11()}`,
31320
+ id: `task_creation_request_${randomUUID12()}`,
30629
31321
  profileId: input.profileId,
30630
31322
  surface: input.surface,
30631
31323
  mode: input.mode,
@@ -30660,13 +31352,13 @@ function createTaskCreatorService(deps) {
30660
31352
  });
30661
31353
  const needsDisclosure = request.disclosure.status === "pending";
30662
31354
  const blockingQuestions = [
30663
- ...!request.objective && request.mode === "customize" ? [{ id: `task_question_${randomUUID11()}`, kind: "objective", prompt: "What repeatable capability should this Taskset teach or evaluate?", answer: null }] : [],
30664
- ...!sources.length && !input.buildSpecification ? [{ id: `task_question_${randomUUID11()}`, kind: "success_signal", prompt: "Add at least one successful example, correction, reviewer choice, or outcome-bearing run so the authoring model can ground this capability without fabricating demonstrations.", answer: null }] : []
31355
+ ...!request.objective && request.mode === "customize" ? [{ id: `task_question_${randomUUID12()}`, kind: "objective", prompt: "What repeatable capability should this Taskset teach or evaluate?", answer: null }] : [],
31356
+ ...!sources.length && !input.buildSpecification ? [{ id: `task_question_${randomUUID12()}`, kind: "success_signal", prompt: "Add at least one successful example, correction, reviewer choice, or outcome-bearing run so the authoring model can ground this capability without fabricating demonstrations.", answer: null }] : []
30665
31357
  ];
30666
31358
  const initialState = blockingQuestions.length ? "awaiting_questions" : needsDisclosure ? "awaiting_disclosure_approval" : "planning";
30667
31359
  let snapshot = TaskCreationSnapshotSchema.parse({
30668
31360
  schemaVersion: "openpond.taskCreationSnapshot.v1",
30669
- id: `task_creation_${randomUUID11()}`,
31361
+ id: `task_creation_${randomUUID12()}`,
30670
31362
  request,
30671
31363
  state: initialState,
30672
31364
  proposal: null,
@@ -30674,7 +31366,7 @@ function createTaskCreatorService(deps) {
30674
31366
  disclosureApprovalId,
30675
31367
  materializationApprovalId: null,
30676
31368
  blockingQuestions,
30677
- transcript: [{ id: `task_message_${randomUUID11()}`, role: "user", text: request.objective ?? "Create a Taskset from the selected conversations.", createdAt: timestamp }],
31369
+ transcript: [{ id: `task_message_${randomUUID12()}`, role: "user", text: request.objective ?? "Create a Taskset from the selected conversations.", createdAt: timestamp }],
30678
31370
  blockedReason: null,
30679
31371
  createdAt: timestamp,
30680
31372
  updatedAt: timestamp
@@ -30717,7 +31409,7 @@ function createTaskCreatorService(deps) {
30717
31409
  state: "planning",
30718
31410
  blockedReason: null,
30719
31411
  transcript: [...snapshot.transcript, {
30720
- id: `task_message_${randomUUID11()}`,
31412
+ id: `task_message_${randomUUID12()}`,
30721
31413
  role: "user",
30722
31414
  text: "Retry Taskset authoring with the same approved evidence and authoring configuration.",
30723
31415
  createdAt: timestamp
@@ -30770,7 +31462,7 @@ function createTaskCreatorService(deps) {
30770
31462
  );
30771
31463
  applying = await persist({ ...applying, proposal, updatedAt: now() });
30772
31464
  const taskset = await materializeTaskset(applying, proposal, sources);
30773
- return persist({ ...applying, state: "ready", materializedTasksetId: taskset.id, blockedReason: null, updatedAt: now(), transcript: [...applying.transcript, { id: `task_message_${randomUUID11()}`, role: "assistant", text: `Materialized ${taskset.name} with ${taskset.tasks.length} tasks and ${taskset.graders.length} graders.`, createdAt: now() }] });
31465
+ return persist({ ...applying, state: "ready", materializedTasksetId: taskset.id, blockedReason: null, updatedAt: now(), transcript: [...applying.transcript, { id: `task_message_${randomUUID12()}`, role: "assistant", text: `Materialized ${taskset.name} with ${taskset.tasks.length} tasks and ${taskset.graders.length} graders.`, createdAt: now() }] });
30774
31466
  } catch (error) {
30775
31467
  return persist({ ...applying, state: "failed", blockedReason: error instanceof Error ? error.message : String(error), updatedAt: now() });
30776
31468
  }
@@ -30782,7 +31474,7 @@ function createTaskCreatorService(deps) {
30782
31474
  if (!snapshot.request.analysisModel || !deps.authorProposal) throw new Error("Task Creator chat requires a configured authoring model.");
30783
31475
  if (["materializing", "validating", "ready", "cancelled"].includes(snapshot.state)) throw new Error(`Task Creator cannot revise a ${snapshot.state} creation.`);
30784
31476
  const timestamp = now();
30785
- const chatting = TaskCreationSnapshotSchema.parse({ ...snapshot, state: "planning", blockedReason: null, transcript: [...snapshot.transcript, { id: `task_message_${randomUUID11()}`, role: "user", text: instruction, createdAt: timestamp }], updatedAt: timestamp });
31477
+ const chatting = TaskCreationSnapshotSchema.parse({ ...snapshot, state: "planning", blockedReason: null, transcript: [...snapshot.transcript, { id: `task_message_${randomUUID12()}`, role: "user", text: instruction, createdAt: timestamp }], updatedAt: timestamp });
30786
31478
  await persist(chatting);
30787
31479
  const sources = await requireSources(snapshot.request.profileId, snapshot.request.sourceIds);
30788
31480
  try {
@@ -30796,7 +31488,7 @@ function createTaskCreatorService(deps) {
30796
31488
  });
30797
31489
  }
30798
31490
  }
30799
- async function rename(id, name) {
31491
+ async function rename2(id, name) {
30800
31492
  const snapshot = await requireSnapshot(id);
30801
31493
  if (!snapshot.proposal) throw new Error("Task Creator has no proposal to rename.");
30802
31494
  if (["materializing", "validating", "ready", "cancelled"].includes(snapshot.state)) throw new Error(`Task Creator cannot rename a ${snapshot.state} creation.`);
@@ -30820,7 +31512,7 @@ function createTaskCreatorService(deps) {
30820
31512
  ...manual ? [manual.evidence] : []
30821
31513
  ];
30822
31514
  if (snapshot.request.analysisModel) assertHostedAuthoringEvidenceBudget(evidence);
30823
- const proposalId = `task_proposal_${randomUUID11()}`;
31515
+ const proposalId = `task_proposal_${randomUUID12()}`;
30824
31516
  const authored = snapshot.request.analysisModel && deps.authorProposal ? await deps.authorProposal({ id: proposalId, model: snapshot.request.analysisModel, reasoningEffort: snapshot.request.analysisReasoningEffort, evidence, buildIntent: snapshot.request.buildIntent, buildSpecification: snapshot.request.buildSpecification, methodHint: snapshot.request.methodHint, signal, instruction: instruction ?? snapshot.request.objective, currentProposal }) : heuristicProposal(proposalId, snapshot, effectiveSources, evidence);
30825
31517
  const proposal = "proposal" in authored ? authored.proposal : authored;
30826
31518
  const repairHistory = "proposal" in authored ? authored.repairHistory : [];
@@ -30842,8 +31534,8 @@ function createTaskCreatorService(deps) {
30842
31534
  proposal: reviewed,
30843
31535
  blockedReason: null,
30844
31536
  repairHistory: [...snapshot.repairHistory, ...repairHistory],
30845
- materializationApprovalId: `task_materialization_${randomUUID11()}`,
30846
- transcript: [...snapshot.transcript, { id: `task_message_${randomUUID11()}`, role: "assistant", text: `Proposed \u201C${reviewed.name}\u201D. Review what should be learned, what should remain context, and the evidence before creating a Taskset.`, createdAt: now() }],
31537
+ materializationApprovalId: `task_materialization_${randomUUID12()}`,
31538
+ transcript: [...snapshot.transcript, { id: `task_message_${randomUUID12()}`, role: "assistant", text: `Proposed \u201C${reviewed.name}\u201D. Review what should be learned, what should remain context, and the evidence before creating a Taskset.`, createdAt: now() }],
30847
31539
  updatedAt: now()
30848
31540
  });
30849
31541
  }
@@ -31002,7 +31694,7 @@ function createTaskCreatorService(deps) {
31002
31694
  });
31003
31695
  }));
31004
31696
  }
31005
- return { reconcileInterruptedCreations, addSessionSource, estimateSessionSources, start, approveDisclosure, retry, answerQuestions, approveMaterialization, chat, rename, cancel };
31697
+ return { reconcileInterruptedCreations, addSessionSource, estimateSessionSources, start, approveDisclosure, retry, answerQuestions, approveMaterialization, chat, rename: rename2, cancel };
31006
31698
  }
31007
31699
  function assertHostedAuthoringEvidenceBudget(evidence) {
31008
31700
  const estimatedTokens = evidence.reduce(
@@ -31295,6 +31987,7 @@ function artifactSplit(fixture) {
31295
31987
  function buildTasksetReadiness(input) {
31296
31988
  const validation = validateTaskset(input.taskset);
31297
31989
  const blockers = validation.issues.filter((issue) => issue.severity === "error").map((issue) => ({ code: issue.code, message: issue.message, path: issue.path }));
31990
+ const advisories = validation.issues.filter((issue) => issue.severity === "warning").map((issue) => ({ code: issue.code, message: issue.message, path: issue.path }));
31298
31991
  const authoredMethod = typeof input.taskset.metadata.trainingMethod === "string" ? input.taskset.metadata.trainingMethod : null;
31299
31992
  const authoredTrainingMethod = trainingPathMethod(authoredMethod);
31300
31993
  const requiresApprovedDemonstrations = authoredTrainingMethod === "sft";
@@ -31329,23 +32022,28 @@ function buildTasksetReadiness(input) {
31329
32022
  }
31330
32023
  const unapprovedTrainCount = artifact ? requiresApprovedDemonstrations && !artifactSignalApproved ? artifactTrainCount : 0 : unapprovedTrainTasks.length;
31331
32024
  if (requiresApprovedDemonstrations && unapprovedTrainCount) blockers.push({ code: "sft_demonstrations_unapproved", message: `${unapprovedTrainCount} training example${unapprovedTrainCount === 1 ? " is" : "s are"} not explicitly approved.`, path: artifact ? "metadata.approvedArtifactSignals" : "learningSignals.demonstrations" });
31332
- if (frozenTaskCount === 0) blockers.push({ code: "frozen_eval_missing", message: "At least one independent evaluation example is required.", path: artifact ? "datasetArtifact.splitCounts.frozen_eval" : "tasks" });
32025
+ if (frozenTaskCount === 0) advisories.push({ code: "frozen_eval_missing", message: "At least one independent evaluation example is recommended before making quality claims.", path: artifact ? "datasetArtifact.splitCounts.frozen_eval" : "tasks" });
31333
32026
  const trainClusters = new Set(trainTasks.map((task) => task.clusterKey));
31334
32027
  const frozenClusters = new Set(frozenTasks.map((task) => task.clusterKey));
31335
32028
  const artifactSplitIsolation = artifact && input.taskset.metadata.splitIsolationVerified === true;
31336
- if (artifact ? !artifactSplitIsolation || trainTaskCount === 0 || frozenTaskCount === 0 : trainClusters.size === 0 || frozenClusters.size === 0 || [...trainClusters].some((cluster) => frozenClusters.has(cluster))) blockers.push({ code: "independent_evaluation_missing", message: "Training and evaluation must use independent source clusters.", path: artifact ? "metadata.splitIsolationVerified" : "tasks" });
32029
+ if (artifact ? !artifactSplitIsolation || trainTaskCount === 0 || frozenTaskCount === 0 : trainClusters.size === 0 || frozenClusters.size === 0 || [...trainClusters].some((cluster) => frozenClusters.has(cluster))) advisories.push({ code: "independent_evaluation_missing", message: "Independent source clusters are recommended before using evaluation results for quality claims.", path: artifact ? "metadata.splitIsolationVerified" : "tasks" });
31337
32030
  if (artifact ? input.taskset.metadata.artifactRowsVerified !== true : input.taskset.tasks.some((task) => typeof task.metadata.exampleOrigin !== "string")) blockers.push({ code: "example_provenance_missing", message: "Every training and evaluation example must record whether it was extracted, corrected, synthetic, or expert-authored.", path: artifact ? "metadata.artifactRowsVerified" : "tasks.metadata.exampleOrigin" });
31338
32031
  const diagnosis = metadataRecord2(input.taskset.metadata.diagnosis);
31339
- if (!diagnosis || typeof diagnosis.summary !== "string" || !Array.isArray(diagnosis.stableBehavior)) blockers.push({ code: "capability_diagnosis_missing", message: "The Taskset must separate stable behavior from changing knowledge before training.", path: "metadata.diagnosis" });
31340
- if (diagnosis?.trainingEligible === false) blockers.push({ code: "training_not_recommended", message: "The capability diagnosis does not recommend storing this behavior in model weights.", path: "metadata.diagnosis.trainingEligible" });
31341
- if (!input.graderAudit) blockers.push({ code: "grader_audit_missing", message: "Run the positive, negative, boundary, adversarial, prompt-injection, and infrastructure grader fixtures.", path: "graderFixtures" });
31342
- if (input.graderAudit && input.graderAudit.tasksetHash !== input.taskset.contentHash) blockers.push({ code: "grader_audit_stale", message: "The Taskset changed after this grader audit. Run it again.", path: "graderFixtures" });
31343
- if (input.graderAudit && !input.graderAudit.passed) blockers.push({ code: "grader_audit_failed", message: "The evaluation grader did not pass all calibration fixtures.", path: "graderFixtures" });
31344
- if (input.graderAudit && !input.graderAudit.hackingChecksPassed) blockers.push({ code: "grader_hacking", message: "Grader hacking or prompt-injection checks failed.", path: "graders" });
31345
- if (input.graderAudit && !input.graderAudit.leakageChecksPassed) blockers.push({ code: "environment_leakage", message: "Environment or privileged-state leakage checks failed.", path: "environment" });
31346
- if (input.graderAudit && !input.graderAudit.infrastructureSafetyPassed) blockers.push({ code: "infrastructure_reward", message: "An infrastructure failure produced a score or eligible reward.", path: "graderFixtures" });
31347
- const hasRewardEligibleGrader = input.taskset.graders.some((grader) => grader.rewardEligible && (grader.kind !== "model_judge" || grader.calibrationStatus === "passed"));
31348
- if (requiresOnlineReward && !hasRewardEligibleGrader) blockers.push({ code: "online_reward_grader_missing", message: `${authoredTrainingMethod?.toUpperCase()} requires a calibrated reward-eligible grader.`, path: "graders" });
32032
+ if (!diagnosis || typeof diagnosis.summary !== "string" || !Array.isArray(diagnosis.stableBehavior)) advisories.push({ code: "capability_diagnosis_missing", message: "A capability diagnosis is recommended to separate stable behavior from changing knowledge.", path: "metadata.diagnosis" });
32033
+ if (diagnosis?.trainingEligible === false) advisories.push({ code: "training_not_recommended", message: "The capability diagnosis does not recommend storing this behavior in model weights.", path: "metadata.diagnosis.trainingEligible" });
32034
+ const graderAuditRequired = input.taskset.graders.some(
32035
+ (grader) => grader.rewardEligible && (grader.kind !== "model_judge" || grader.metadata.calibrationIsAdvisory !== true)
32036
+ );
32037
+ if (graderAuditRequired && !input.graderAudit) advisories.push({ code: "grader_audit_missing", message: "Optional grader calibration evidence has not been recorded.", path: "graderFixtures" });
32038
+ if (graderAuditRequired && input.graderAudit && input.graderAudit.tasksetHash !== input.taskset.contentHash) advisories.push({ code: "grader_audit_stale", message: "Optional grader calibration evidence predates this immutable Taskset revision.", path: "graderFixtures" });
32039
+ if (graderAuditRequired && input.graderAudit && !input.graderAudit.passed) advisories.push({ code: "grader_audit_failed", message: "The grader did not match every optional calibration fixture's expected outcome.", path: "graderFixtures" });
32040
+ if (graderAuditRequired && input.graderAudit && !input.graderAudit.hackingChecksPassed) advisories.push({ code: "grader_adversarial_calibration_failed", message: "Adversarial or prompt-injection calibration fixtures did not match their expected grader outcomes.", path: "graders" });
32041
+ if (graderAuditRequired && input.graderAudit && !input.graderAudit.leakageChecksPassed) blockers.push({ code: "environment_leakage", message: "Environment or privileged-state leakage checks failed.", path: "environment" });
32042
+ if (graderAuditRequired && input.graderAudit && !input.graderAudit.infrastructureSafetyPassed) blockers.push({ code: "infrastructure_reward", message: "An infrastructure failure produced a score or eligible reward.", path: "graderFixtures" });
32043
+ const hasRewardEligibleGrader = input.taskset.graders.some(
32044
+ (grader) => grader.rewardEligible
32045
+ );
32046
+ if (requiresOnlineReward && !hasRewardEligibleGrader) blockers.push({ code: "online_reward_grader_missing", message: `${authoredTrainingMethod?.toUpperCase()} requires a user-selected reward-eligible grader.`, path: "graders" });
31349
32047
  const recommendedMethod = authoredTrainingMethod ?? (trainTaskCount > 0 && input.taskset.capabilities.compatibleMethods.includes("sft") ? "sft" : "none");
31350
32048
  const demonstrationRefs = input.taskset.learningSignals.demonstrations.filter((signal) => signal.approved).map((signal) => signal.id);
31351
32049
  const trainingPath = recommendedMethod === "none" ? null : {
@@ -31407,6 +32105,7 @@ function buildTasksetReadiness(input) {
31407
32105
  methodReadiness,
31408
32106
  compatibleDestinationClasses: ready ? recommendedMethod === "grpo" ? ["export", "custom", "hosted_managed"] : ["export", "custom"] : ["export"],
31409
32107
  blockers,
32108
+ advisories,
31410
32109
  warnings: [
31411
32110
  ...validation.issues.filter((issue) => issue.severity === "warning").map((issue) => issue.message),
31412
32111
  ...recommendedMethod === "grpo" ? ["GRPO is readiness-compatible but not executable in the local CPU fixture."] : [],
@@ -31427,14 +32126,14 @@ function metadataStrings(value) {
31427
32126
  }
31428
32127
 
31429
32128
  // ../server/src/training/sandboxed-verifier.ts
31430
- import { readFile as readFile5, realpath } from "node:fs/promises";
32129
+ import { readFile as readFile6, realpath } from "node:fs/promises";
31431
32130
  import path32 from "node:path";
31432
32131
  import vm from "node:vm";
31433
32132
  async function runSandboxedVerifier(input) {
31434
32133
  const root = await realpath(input.allowedRoot);
31435
32134
  const modulePath = await realpath(path32.resolve(root, input.grader.module));
31436
32135
  if (modulePath !== root && !modulePath.startsWith(`${root}${path32.sep}`)) throw new Error("Verifier module is outside the approved Taskset root.");
31437
- const source = await readFile5(modulePath, "utf8");
32136
+ const source = await readFile6(modulePath, "utf8");
31438
32137
  assertSandboxableSource(source);
31439
32138
  const functionSource = verifierFunctionSource(source, input.grader.exportName);
31440
32139
  const context = vm.createContext(Object.freeze({
@@ -31673,7 +32372,7 @@ function failureClassFor(outcome) {
31673
32372
 
31674
32373
  // ../server/src/training/task-attempt-artifact-service.ts
31675
32374
  import path33 from "node:path";
31676
- import { mkdir as mkdir3, readFile as readFile6, writeFile as writeFile3 } from "node:fs/promises";
32375
+ import { mkdir as mkdir4, readFile as readFile7, writeFile as writeFile3 } from "node:fs/promises";
31677
32376
  async function persistJsonTaskAttemptArtifact(input) {
31678
32377
  const directory = path33.join(
31679
32378
  input.storeDir,
@@ -31691,7 +32390,7 @@ async function persistJsonTaskAttemptArtifact(input) {
31691
32390
  ...input.payload
31692
32391
  }, null, 2)}
31693
32392
  `, "utf8");
31694
- await mkdir3(directory, { recursive: true });
32393
+ await mkdir4(directory, { recursive: true });
31695
32394
  await writeFile3(file, bytes, { mode: 384 });
31696
32395
  return saveArtifact({
31697
32396
  ...input,
@@ -31706,7 +32405,7 @@ async function persistBinaryTaskAttemptArtifact(input) {
31706
32405
  throw new Error("Task Attempt artifact extension is invalid.");
31707
32406
  }
31708
32407
  const directory = path33.join(input.storeDir, "training", "evaluation-artifacts", input.tasksetId);
31709
- await mkdir3(directory, { recursive: true });
32408
+ await mkdir4(directory, { recursive: true });
31710
32409
  const file = path33.join(directory, `${input.attemptId}-${safeFileLabel(input.fileLabel)}.${extension}`);
31711
32410
  await writeFile3(file, input.bytes, { mode: 384 });
31712
32411
  return saveArtifact({ ...input, file });
@@ -31717,7 +32416,7 @@ function safeFileLabel(value) {
31717
32416
  return normalized;
31718
32417
  }
31719
32418
  async function persistTaskAttemptOutputArtifact(input) {
31720
- const bytes = await readFile6(input.path);
32419
+ const bytes = await readFile7(input.path);
31721
32420
  const checksum = sha256(bytes);
31722
32421
  if (bytes.byteLength !== input.expectedSizeBytes || checksum !== input.expectedSha256) {
31723
32422
  throw new Error(
@@ -32012,15 +32711,15 @@ async function discoverCommandArtifacts(result2, limit = 12) {
32012
32711
  );
32013
32712
  if (!contentType) continue;
32014
32713
  try {
32015
- const stat = await fs21.stat(resolved);
32016
- if (!stat.isFile()) continue;
32714
+ const stat2 = await fs21.stat(resolved);
32715
+ if (!stat2.isFile()) continue;
32017
32716
  seen.add(resolved);
32018
32717
  artifacts.push({
32019
32718
  artifactRef: resolved,
32020
32719
  path: resolved,
32021
32720
  title: path34.basename(resolved),
32022
32721
  contentType,
32023
- sizeBytes: stat.size,
32722
+ sizeBytes: stat2.size,
32024
32723
  binary: true
32025
32724
  });
32026
32725
  if (artifacts.length >= limit) break;
@@ -33748,7 +34447,7 @@ function numberValue3(value) {
33748
34447
  }
33749
34448
 
33750
34449
  // ../server/src/openpond/work-tool-registry.ts
33751
- import { randomUUID as randomUUID12 } from "node:crypto";
34450
+ import { randomUUID as randomUUID13 } from "node:crypto";
33752
34451
 
33753
34452
  // ../server/src/openpond/work-runtime-service.ts
33754
34453
  import { createHash as createHash7 } from "node:crypto";
@@ -34008,13 +34707,14 @@ function createWorkModelToolDefinitions(deps) {
34008
34707
  ...deps.createScheduledWork ? [
34009
34708
  {
34010
34709
  name: "schedule_work",
34011
- description: "Create durable recurring Work through the OpenPond control plane when the user directly asks to schedule the current or another task and provides an exact cadence, local date/time, and timezone. This capability does not depend on a scheduler daemon inside the sandbox. Use the conversation context to preserve the task prompt and ask only for genuinely unavailable required scheduling details. Delivery is not required: unless the user explicitly requests an external destination or format, default to managed in-app Work outputs; report-like work should create a polished PDF plus a concise in-app summary. The scheduled prompt must describe only the work to perform when the schedule fires, not the scheduling request itself.",
34710
+ description: "Create a durable recurring workflow attached to the current chat when the user directly asks to schedule the current or another task and provides an exact cadence, local date/time, and timezone. Every scheduled run is sent through the attached chat so its output appears in that conversation. Use the conversation context to preserve the task prompt and ask only for genuinely unavailable required scheduling details. The scheduled prompt must describe only the work to perform when the schedule fires, not the scheduling request itself.",
34012
34711
  parameters: savedWorkScheduleParameters(),
34013
34712
  execute: async (context) => {
34014
34713
  const input = CreateHostedSavedWorkRequestSchema.parse({
34015
34714
  ...context.args,
34016
34715
  clientRequestId: `${context.turnId}:${context.callId}`,
34017
34716
  sourceTurnId: context.turnId,
34717
+ targetSessionId: context.session.id,
34018
34718
  modelId: context.provider === "openpond" ? context.model : "openpond-chat"
34019
34719
  });
34020
34720
  const data = await deps.createScheduledWork(input);
@@ -34519,7 +35219,7 @@ function createWorkModelToolDefinitions(deps) {
34519
35219
  const url = validHttpUrl(context.args.url);
34520
35220
  const validation = Array.isArray(context.args.validation) ? context.args.validation : [];
34521
35221
  const identity = {
34522
- id: randomUUID12(),
35222
+ id: randomUUID13(),
34523
35223
  title,
34524
35224
  sourceTaskId: context.session.id,
34525
35225
  sourceTurnId: context.turnId,
@@ -34743,7 +35443,7 @@ function asRecord9(value) {
34743
35443
 
34744
35444
  // ../server/src/training/taskset-work-assets.ts
34745
35445
  import { createHash as createHash8 } from "node:crypto";
34746
- import { lstat, readFile as readFile7 } from "node:fs/promises";
35446
+ import { lstat as lstat2, readFile as readFile8 } from "node:fs/promises";
34747
35447
  import path36 from "node:path";
34748
35448
  var DEFAULT_MAX_WORK_INPUT_BYTES = 25e7;
34749
35449
  var MAX_WORK_INPUT_BYTES2 = 1e9;
@@ -34786,11 +35486,11 @@ async function resolveTasksetWorkAssets(input) {
34786
35486
  `Work asset ${asset3.id} must resolve inside the Taskset assets directory.`
34787
35487
  );
34788
35488
  }
34789
- const status = await lstat(target);
35489
+ const status = await lstat2(target);
34790
35490
  if (!status.isFile() || status.isSymbolicLink()) {
34791
35491
  throw new Error(`Work asset ${asset3.id} must be a regular file.`);
34792
35492
  }
34793
- const bytes = await readFile7(target);
35493
+ const bytes = await readFile8(target);
34794
35494
  const sha2562 = createHash8("sha256").update(bytes).digest("hex");
34795
35495
  if (bytes.byteLength !== asset3.sizeBytes) {
34796
35496
  throw new Error(
@@ -34826,6 +35526,44 @@ async function resolveTasksetWorkAssets(input) {
34826
35526
  }
34827
35527
  return resolved;
34828
35528
  }
35529
+ async function resolveTasksetTrainingAssetBytes(input) {
35530
+ const result2 = /* @__PURE__ */ new Map();
35531
+ for (const task of input.taskset.tasks.filter((candidate) => candidate.split === "train")) {
35532
+ for (const asset3 of await resolveTasksetWorkAssets({
35533
+ storeDir: input.storeDir,
35534
+ taskset: input.taskset,
35535
+ task
35536
+ })) {
35537
+ if (result2.has(asset3.artifactRef)) {
35538
+ throw new Error(
35539
+ `Training asset path ${asset3.artifactRef} is shared by multiple tasks.`
35540
+ );
35541
+ }
35542
+ result2.set(asset3.artifactRef, asset3.bytes);
35543
+ }
35544
+ }
35545
+ return result2;
35546
+ }
35547
+ async function resolveTasksetEvaluationAssetBytes(input) {
35548
+ const result2 = /* @__PURE__ */ new Map();
35549
+ for (const task of input.taskset.tasks.filter(
35550
+ (candidate) => candidate.split === "validation" || candidate.split === "frozen_eval"
35551
+ )) {
35552
+ for (const asset3 of await resolveTasksetWorkAssets({
35553
+ storeDir: input.storeDir,
35554
+ taskset: input.taskset,
35555
+ task
35556
+ })) {
35557
+ if (result2.has(asset3.artifactRef)) {
35558
+ throw new Error(
35559
+ `Evaluation asset path ${asset3.artifactRef} is shared by multiple tasks.`
35560
+ );
35561
+ }
35562
+ result2.set(asset3.artifactRef, asset3.bytes);
35563
+ }
35564
+ }
35565
+ return result2;
35566
+ }
34829
35567
  function assertEligibleSource(source, asset3) {
34830
35568
  if (isTrainingSourceRef(source)) {
34831
35569
  if (source.consent.status !== "granted") {
@@ -34861,7 +35599,7 @@ function assertEligibleSource(source, asset3) {
34861
35599
 
34862
35600
  // ../server/src/training/taskset-work-attempt-support.ts
34863
35601
  import path37 from "node:path";
34864
- import { readFile as readFile8 } from "node:fs/promises";
35602
+ import { readFile as readFile9 } from "node:fs/promises";
34865
35603
  var DEFAULT_MAX_WORK_TOOL_TURNS = 24;
34866
35604
  var MAX_WORK_TOOL_TURNS = 100;
34867
35605
  var MAX_MISSING_OUTPUT_RECOVERY_TURNS = 10;
@@ -34951,7 +35689,7 @@ async function validateSavedOutput(input) {
34951
35689
  }
34952
35690
  try {
34953
35691
  parsedJson = JSON.parse(
34954
- await readFile8(input.saved.artifactPath, "utf8")
35692
+ await readFile9(input.saved.artifactPath, "utf8")
34955
35693
  );
34956
35694
  } catch {
34957
35695
  return {
@@ -37803,32 +38541,20 @@ async function qualifyHarnessModelImprovement(input) {
37803
38541
  });
37804
38542
  return receipt;
37805
38543
  }
37806
- async function requireQualifiedModelImprovement(input) {
38544
+ async function resolveModelImprovementQualificationEvidence(input) {
38545
+ if (!input.qualificationRef) return null;
38546
+ const qualificationRef = input.qualificationRef;
37807
38547
  const receipt = (await input.store.listHarnessImprovementArtifacts(
37808
38548
  input.workspaceId,
37809
38549
  "training_qualification",
37810
38550
  1e3
37811
38551
  )).find(
37812
- (candidate) => candidate.id === input.qualificationRef.id && candidate.contentHash === input.qualificationRef.contentHash
38552
+ (candidate) => candidate.id === qualificationRef.id && candidate.contentHash === qualificationRef.contentHash
37813
38553
  );
37814
- if (!receipt || receipt.decision === "no_training") {
37815
- throw new Error("A qualified model-improvement receipt is required before planning training.");
37816
- }
37817
- const taskset = await input.store.getTaskset(input.tasksetId);
37818
- if (!taskset || taskset.metadata.harnessEvaluationReview === void 0) {
37819
- throw new Error("Qualified Taskset was not found.");
37820
- }
37821
- if (receipt.metadata.sourceTasksetId !== taskset.id || receipt.metadata.sourceTasksetHash !== taskset.contentHash) {
37822
- throw new Error("Model-improvement qualification does not match the current immutable Taskset.");
37823
- }
37824
- if (!recipeMatches(receipt.decision, input.recipe.method)) {
37825
- throw new Error("Training recipe method does not match the qualification decision.");
37826
- }
37827
- if (receipt.model.model !== input.baseModelId) {
37828
- throw new Error("Training base Model does not match the qualified baseline Model.");
37829
- }
37830
- if (input.maximumCostUsd !== null && input.maximumCostUsd !== void 0 && input.maximumCostUsd > receipt.maximumCostUsd) {
37831
- throw new Error("Training approval exceeds the qualified maximum cost.");
38554
+ if (!receipt) {
38555
+ throw new Error(
38556
+ "The supplied model-improvement qualification was not found at its immutable identity."
38557
+ );
37832
38558
  }
37833
38559
  return receipt;
37834
38560
  }
@@ -37983,12 +38709,6 @@ function hashMetadata(baseline, key) {
37983
38709
  if (typeof value !== "string") throw new Error(`Baseline Evaluation is missing ${key}.`);
37984
38710
  return value;
37985
38711
  }
37986
- function recipeMatches(decision, method) {
37987
- if (decision === "sft") return method === "sft";
37988
- if (decision === "preference") return method === "dpo";
37989
- if (decision === "rl") return method === "grpo" || method === "ppo";
37990
- return false;
37991
- }
37992
38712
  function sameRef(value, expected) {
37993
38713
  return isRecord5(value) && value.id === expected.id && value.contentHash === expected.contentHash;
37994
38714
  }
@@ -38482,6 +39202,8 @@ function createRuntimeEventBus({
38482
39202
  }
38483
39203
  async function openEventSubscriber(input) {
38484
39204
  const subscriber = {
39205
+ backpressured: false,
39206
+ drainListener: null,
38485
39207
  response: input.response,
38486
39208
  sessionId: input.sessionId,
38487
39209
  ready: false,
@@ -38516,7 +39238,14 @@ function createRuntimeEventBus({
38516
39238
  }
38517
39239
  }
38518
39240
  function addLiveSubscriber(response, sessionId = null) {
38519
- const subscriber = { response, sessionId, ready: true, pending: [] };
39241
+ const subscriber = {
39242
+ backpressured: false,
39243
+ drainListener: null,
39244
+ response,
39245
+ sessionId,
39246
+ ready: true,
39247
+ pending: []
39248
+ };
38520
39249
  subscribers.add(subscriber);
38521
39250
  return () => disconnectSubscriber(subscriber, false);
38522
39251
  }
@@ -38601,6 +39330,9 @@ function createRuntimeEventBus({
38601
39330
  subscribers.delete(subscriber);
38602
39331
  return false;
38603
39332
  }
39333
+ if (subscriber.backpressured) {
39334
+ return queueSubscriberEvent(subscriber, event2);
39335
+ }
38604
39336
  const encoded = `id: ${event2.sequence ?? ""}
38605
39337
  event: runtime
38606
39338
  data: ${JSON.stringify(event2)}
@@ -38608,8 +39340,14 @@ data: ${JSON.stringify(event2)}
38608
39340
  `;
38609
39341
  try {
38610
39342
  if (!subscriber.response.write(encoded)) {
38611
- disconnectSubscriber(subscriber);
38612
- return false;
39343
+ subscriber.backpressured = true;
39344
+ const onDrain = () => {
39345
+ subscriber.drainListener = null;
39346
+ subscriber.backpressured = false;
39347
+ flushSubscriberQueue(subscriber);
39348
+ };
39349
+ subscriber.drainListener = onDrain;
39350
+ subscriber.response.once("drain", onDrain);
38613
39351
  }
38614
39352
  return true;
38615
39353
  } catch {
@@ -38619,9 +39357,26 @@ data: ${JSON.stringify(event2)}
38619
39357
  }
38620
39358
  function disconnectSubscriber(subscriber, destroy = true) {
38621
39359
  subscribers.delete(subscriber);
39360
+ if (subscriber.drainListener) {
39361
+ subscriber.response.off("drain", subscriber.drainListener);
39362
+ subscriber.drainListener = null;
39363
+ }
39364
+ subscriber.backpressured = false;
38622
39365
  subscriber.pending = [];
38623
39366
  if (destroy && !subscriber.response.destroyed) subscriber.response.destroy();
38624
39367
  }
39368
+ function queueSubscriberEvent(subscriber, runtimeEvent) {
39369
+ subscriber.pending.push(runtimeEvent);
39370
+ if (subscriber.pending.length <= MAX_PENDING_SUBSCRIBER_EVENTS) return true;
39371
+ disconnectSubscriber(subscriber);
39372
+ return false;
39373
+ }
39374
+ function flushSubscriberQueue(subscriber) {
39375
+ while (subscribers.has(subscriber) && !subscriber.backpressured && subscriber.pending.length > 0) {
39376
+ const runtimeEvent = subscriber.pending.shift();
39377
+ if (!runtimeEvent || !writeSubscriberEvent(subscriber, runtimeEvent)) return;
39378
+ }
39379
+ }
38625
39380
  }
38626
39381
  function isCoalescibleAssistantDelta(runtimeEvent) {
38627
39382
  return runtimeEvent.name === "assistant.delta" && Boolean(runtimeEvent.output) && !runtimeEvent.action && !runtimeEvent.args && !runtimeEvent.status && !runtimeEvent.error && !runtimeEvent.relatedDeploymentId && runtimeEvent.data === void 0;
@@ -38636,7 +39391,7 @@ function assistantDeltaKey(runtimeEvent) {
38636
39391
  }
38637
39392
 
38638
39393
  // ../server/src/runtime/turn-runner.ts
38639
- import { createHash as createHash9, randomUUID as randomUUID17 } from "node:crypto";
39394
+ import { createHash as createHash9, randomUUID as randomUUID18 } from "node:crypto";
38640
39395
 
38641
39396
  // ../server/src/chat-attachments.ts
38642
39397
  import { promises as fs23 } from "node:fs";
@@ -38841,14 +39596,14 @@ async function readChatAttachmentImageFile(input) {
38841
39596
  if (target !== turnDir && !target.startsWith(`${turnDir}${path42.sep}`))
38842
39597
  return null;
38843
39598
  try {
38844
- const stat = await fs23.lstat(target);
38845
- if (!stat.isFile() || stat.size > MAX_CHAT_ATTACHMENT_IMAGE_BYTES)
39599
+ const stat2 = await fs23.lstat(target);
39600
+ if (!stat2.isFile() || stat2.size > MAX_CHAT_ATTACHMENT_IMAGE_BYTES)
38846
39601
  return null;
38847
39602
  return {
38848
39603
  path: storageName,
38849
39604
  contentType,
38850
39605
  bytes: await fs23.readFile(target),
38851
- sizeBytes: stat.size
39606
+ sizeBytes: stat2.size
38852
39607
  };
38853
39608
  } catch {
38854
39609
  return null;
@@ -38859,14 +39614,14 @@ async function readChatAttachmentTextFile(input) {
38859
39614
  if (!target || !chatAttachmentTextPreviewSupported(input.contentType, input.storageName))
38860
39615
  return null;
38861
39616
  try {
38862
- const stat = await fs23.lstat(target.absolutePath);
38863
- if (!stat.isFile() || stat.size > CHAT_ATTACHMENT_TEXT_PREVIEW_MAX_BYTES)
39617
+ const stat2 = await fs23.lstat(target.absolutePath);
39618
+ if (!stat2.isFile() || stat2.size > CHAT_ATTACHMENT_TEXT_PREVIEW_MAX_BYTES)
38864
39619
  return null;
38865
39620
  return {
38866
39621
  path: target.storageName,
38867
39622
  contentType: input.contentType,
38868
39623
  content: await fs23.readFile(target.absolutePath, "utf8"),
38869
- sizeBytes: stat.size
39624
+ sizeBytes: stat2.size
38870
39625
  };
38871
39626
  } catch {
38872
39627
  return null;
@@ -40117,7 +40872,7 @@ function resolveContextCompactionAdapter(provider) {
40117
40872
  }
40118
40873
 
40119
40874
  // ../server/src/openpond/context-compaction/index.ts
40120
- import { randomUUID as randomUUID13 } from "node:crypto";
40875
+ import { randomUUID as randomUUID14 } from "node:crypto";
40121
40876
 
40122
40877
  // ../server/src/openpond/context-compaction/file-paths.ts
40123
40878
  function extractCompactionFilePaths(value) {
@@ -40978,7 +41733,7 @@ async function runHostedContextCompaction(input) {
40978
41733
  [
40979
41734
  ...projectionEvents,
40980
41735
  {
40981
- id: `compaction-projection-${randomUUID13()}`,
41736
+ id: `compaction-projection-${randomUUID14()}`,
40982
41737
  name: "session.compaction.completed",
40983
41738
  data: {
40984
41739
  summary: result2.summary,
@@ -41023,7 +41778,7 @@ function hostedCompactionContextLimit(provider, model, maxContextTokens) {
41023
41778
  }
41024
41779
  async function streamCompactionSummary(input) {
41025
41780
  let text = "";
41026
- const requestId = `compact-${randomUUID13()}`;
41781
+ const requestId = `compact-${randomUUID14()}`;
41027
41782
  const streamCompactionChatTurn = input.streamCompactionChatTurn ?? defaultOpenPondCompactionStream;
41028
41783
  for await (const delta of streamCompactionChatTurn({
41029
41784
  provider: input.provider,
@@ -44960,7 +45715,7 @@ function assertCreateImproveMutationApproved(input) {
44960
45715
  }
44961
45716
 
44962
45717
  // ../server/src/runtime/create-pipeline-planner.ts
44963
- import { randomUUID as randomUUID14 } from "node:crypto";
45718
+ import { randomUUID as randomUUID15 } from "node:crypto";
44964
45719
  var PlannerQuestionOptionSchema = external_exports.object({
44965
45720
  id: external_exports.string().trim().min(1).optional(),
44966
45721
  label: external_exports.string().trim().min(1),
@@ -45130,8 +45885,8 @@ function createQuestionRun(run, decision, modelRef) {
45130
45885
  }
45131
45886
  function createPlanRun(run, decision, modelRef) {
45132
45887
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
45133
- const planId = `create_improve_plan_${randomUUID14()}`;
45134
- const approvalId = `approval_${randomUUID14()}`;
45888
+ const planId = `create_improve_plan_${randomUUID15()}`;
45889
+ const approvalId = `approval_${randomUUID15()}`;
45135
45890
  const target = plannedTarget(run.target, decision, run.objective);
45136
45891
  const sourceRoot = sourceRootForTarget(target);
45137
45892
  const actionShape = decision.actionShape;
@@ -45214,7 +45969,7 @@ function workflowCaptureForRun(run) {
45214
45969
  );
45215
45970
  return CreateImproveWorkflowCaptureSchema.parse({
45216
45971
  schemaVersion: "openpond.createImprove.workflowCapture.v1",
45217
- id: `workflow_capture_${randomUUID14()}`,
45972
+ id: `workflow_capture_${randomUUID15()}`,
45218
45973
  runId: run.id,
45219
45974
  command: run.command,
45220
45975
  objective: run.objective,
@@ -45662,12 +46417,12 @@ var KeyedRegistry = class {
45662
46417
 
45663
46418
  // ../server/src/runtime/local-create-pipeline.ts
45664
46419
  import { existsSync as existsSync2 } from "node:fs";
45665
- import { cp, mkdir as mkdir4, readFile as readFile10 } from "node:fs/promises";
46420
+ import { cp as cp2, mkdir as mkdir5, readFile as readFile11 } from "node:fs/promises";
45666
46421
  import path46 from "node:path";
45667
46422
 
45668
46423
  // ../server/src/runtime/local-create-pipeline-checks.ts
45669
46424
  import { existsSync } from "node:fs";
45670
- import { readFile as readFile9 } from "node:fs/promises";
46425
+ import { readFile as readFile10 } from "node:fs/promises";
45671
46426
  import path45 from "node:path";
45672
46427
  async function runLocalCreatePipelineChecks(input) {
45673
46428
  await assertLocalCreateSourceLayout(input.target);
@@ -45759,7 +46514,7 @@ async function assertLocalCreateSourceLayout(target) {
45759
46514
  `Codex did not update the profile manifest: ${profileManifestPath}`
45760
46515
  );
45761
46516
  }
45762
- const rootManifest = JSON.parse(await readFile9(rootManifestPath, "utf8"));
46517
+ const rootManifest = JSON.parse(await readFile10(rootManifestPath, "utf8"));
45763
46518
  const profileEntry = rootManifest.profiles?.[target.activeProfile];
45764
46519
  if (!profileEntry) {
45765
46520
  throw new Error(
@@ -45771,7 +46526,7 @@ async function assertLocalCreateSourceLayout(target) {
45771
46526
  `openpond-profile.json does not enable generated agent ${target.agentId}.`
45772
46527
  );
45773
46528
  }
45774
- const profileYaml = await readFile9(profileManifestPath, "utf8");
46529
+ const profileYaml = await readFile10(profileManifestPath, "utf8");
45775
46530
  if (!profileYaml.includes(`id: ${target.agentId}`) && !profileYaml.includes(`id: "${target.agentId}"`)) {
45776
46531
  throw new Error(
45777
46532
  `settings/profile.yaml does not register generated agent ${target.agentId}.`
@@ -45805,7 +46560,7 @@ async function assertGeneratedSdkArtifacts(target, requireEvalPass = true) {
45805
46560
  `Generated source did not produce eval results: ${evalResultsPath}`
45806
46561
  );
45807
46562
  }
45808
- const registry = JSON.parse(await readFile9(registryPath, "utf8"));
46563
+ const registry = JSON.parse(await readFile10(registryPath, "utf8"));
45809
46564
  const actions = Array.isArray(registry.actions) ? registry.actions : [];
45810
46565
  const actionIds = new Set(
45811
46566
  actions.map((action) => typeof action.id === "string" ? action.id : null).filter((id) => Boolean(id))
@@ -45838,7 +46593,7 @@ async function assertGeneratedSdkArtifacts(target, requireEvalPass = true) {
45838
46593
  )}. Mark built-in/local fixture requirements ready or optional when they are satisfied, or leave the pipeline blocked until the setup is configured.`
45839
46594
  );
45840
46595
  }
45841
- const evalResults = JSON.parse(await readFile9(evalResultsPath, "utf8"));
46596
+ const evalResults = JSON.parse(await readFile10(evalResultsPath, "utf8"));
45842
46597
  if (typeof evalResults.summary?.total !== "number" || evalResults.summary.total < 1) {
45843
46598
  throw new Error(
45844
46599
  "Generated source must define at least one deterministic SDK eval."
@@ -46310,7 +47065,7 @@ async function applyPreparedHarnessSourceApplication(snapshot, target, env = pro
46310
47065
  HARNESS_PREPARED_SOURCE_MANIFEST
46311
47066
  );
46312
47067
  if (!existsSync2(manifestPath)) return false;
46313
- const manifest = JSON.parse(await readFile10(manifestPath, "utf8"));
47068
+ const manifest = JSON.parse(await readFile11(manifestPath, "utf8"));
46314
47069
  const root = asRecord16(manifest);
46315
47070
  if (root?.schema !== "openpond.harnessPreparedSource.v1") {
46316
47071
  throw new Error(
@@ -46333,8 +47088,8 @@ async function applyPreparedHarnessSourceApplication(snapshot, target, env = pro
46333
47088
  `Prepared harness source does not exist: ${operation.source}`
46334
47089
  );
46335
47090
  }
46336
- await mkdir4(target.sourceRoot, { recursive: true });
46337
- await cp(sourcePath, target.sourceRoot, { recursive: true, force: true });
47091
+ await mkdir5(target.sourceRoot, { recursive: true });
47092
+ await cp2(sourcePath, target.sourceRoot, { recursive: true, force: true });
46338
47093
  for (const registration of operation.registrations ?? []) {
46339
47094
  const registrationSource = resolveHarnessManifestPath(
46340
47095
  target.workspaceRoot,
@@ -46351,8 +47106,8 @@ async function applyPreparedHarnessSourceApplication(snapshot, target, env = pro
46351
47106
  `Prepared harness registration source does not exist: ${registration.source}`
46352
47107
  );
46353
47108
  }
46354
- await mkdir4(path46.dirname(registrationTarget), { recursive: true });
46355
- await cp(registrationSource, registrationTarget, { force: true });
47109
+ await mkdir5(path46.dirname(registrationTarget), { recursive: true });
47110
+ await cp2(registrationSource, registrationTarget, { force: true });
46356
47111
  }
46357
47112
  return true;
46358
47113
  }
@@ -46426,7 +47181,7 @@ async function sourceLayoutFingerprint(target) {
46426
47181
  ];
46427
47182
  const parts = await Promise.all(
46428
47183
  paths.map(async (filePath) => {
46429
- const content = await readFile10(filePath, "utf8");
47184
+ const content = await readFile11(filePath, "utf8");
46430
47185
  return `${filePath}:${content.length}:${content}`;
46431
47186
  })
46432
47187
  );
@@ -46918,13 +47673,13 @@ function stringArray5(value) {
46918
47673
 
46919
47674
  // ../server/src/runtime/create-pipeline/agent-improvement-git.ts
46920
47675
  import { existsSync as existsSync4 } from "node:fs";
46921
- import { mkdir as mkdir6, realpath as realpath3, rm as rm2, writeFile as writeFile5 } from "node:fs/promises";
47676
+ import { mkdir as mkdir7, realpath as realpath3, rm as rm3, writeFile as writeFile5 } from "node:fs/promises";
46922
47677
  import os4 from "node:os";
46923
47678
  import path49 from "node:path";
46924
47679
 
46925
47680
  // ../server/src/runtime/create-pipeline/agent-improvement-git-helpers.ts
46926
47681
  import { existsSync as existsSync3 } from "node:fs";
46927
- import { cp as cp2, lstat as lstat2, mkdir as mkdir5, rm, symlink, writeFile as writeFile4 } from "node:fs/promises";
47682
+ import { cp as cp3, lstat as lstat3, mkdir as mkdir6, rm as rm2, symlink, writeFile as writeFile4 } from "node:fs/promises";
46928
47683
  import path48 from "node:path";
46929
47684
  function allowedAgentImprovementPaths(run, target) {
46930
47685
  const profilePath = normalizeRepoPath(target.profileRelativePath);
@@ -47016,7 +47771,7 @@ async function linkCandidateDependencies(target, worktreePath) {
47016
47771
  const destinationPath = path48.join(worktreePath, ...relativePath.split("/"));
47017
47772
  if (!await directoryExists(sourcePath) || existsSync3(destinationPath))
47018
47773
  continue;
47019
- await mkdir5(path48.dirname(destinationPath), { recursive: true });
47774
+ await mkdir6(path48.dirname(destinationPath), { recursive: true });
47020
47775
  await symlink(
47021
47776
  sourcePath,
47022
47777
  destinationPath,
@@ -47043,7 +47798,7 @@ async function snapshotActiveProfileChanges(input) {
47043
47798
  applied,
47044
47799
  "Unable to apply active Profile changes to the candidate baseline."
47045
47800
  );
47046
- await rm(patchPath, { force: true });
47801
+ await rm2(patchPath, { force: true });
47047
47802
  }
47048
47803
  const untracked = await input.command(
47049
47804
  "git",
@@ -47057,8 +47812,8 @@ async function snapshotActiveProfileChanges(input) {
47057
47812
  input.worktreePath,
47058
47813
  ...relativePath.split("/")
47059
47814
  );
47060
- await mkdir5(path48.dirname(destination), { recursive: true });
47061
- await cp2(source, destination, {
47815
+ await mkdir6(path48.dirname(destination), { recursive: true });
47816
+ await cp3(source, destination, {
47062
47817
  recursive: true,
47063
47818
  preserveTimestamps: true
47064
47819
  });
@@ -47102,7 +47857,7 @@ function gitIdentityEnv() {
47102
47857
  }
47103
47858
  async function directoryExists(value) {
47104
47859
  try {
47105
- return (await lstat2(value)).isDirectory();
47860
+ return (await lstat3(value)).isDirectory();
47106
47861
  } catch {
47107
47862
  return false;
47108
47863
  }
@@ -47281,7 +48036,7 @@ async function prepareAgentImprovementWorkspace(input) {
47281
48036
  safePathSegment(input.run.id)
47282
48037
  );
47283
48038
  const worktreePath = path49.join(workspaceRoot, "repo");
47284
- await mkdir6(workspaceRoot, { recursive: true });
48039
+ await mkdir7(workspaceRoot, { recursive: true });
47285
48040
  const existingBranch = await command(
47286
48041
  "git",
47287
48042
  ["show-ref", "--verify", "--quiet", `refs/heads/${branch}`],
@@ -47298,8 +48053,8 @@ async function prepareAgentImprovementWorkspace(input) {
47298
48053
  ["worktree", "remove", "--force", worktreePath],
47299
48054
  repoPath
47300
48055
  );
47301
- await rm2(workspaceRoot, { recursive: true, force: true });
47302
- await mkdir6(workspaceRoot, { recursive: true });
48056
+ await rm3(workspaceRoot, { recursive: true, force: true });
48057
+ await mkdir7(workspaceRoot, { recursive: true });
47303
48058
  }
47304
48059
  }
47305
48060
  if (!existsSync4(worktreePath)) {
@@ -47734,7 +48489,7 @@ async function applyAgentImprovementCandidateLocally(input) {
47734
48489
  }
47735
48490
  throw error;
47736
48491
  } finally {
47737
- await rm2(patchPath, { force: true }).catch(() => void 0);
48492
+ await rm3(patchPath, { force: true }).catch(() => void 0);
47738
48493
  }
47739
48494
  }
47740
48495
  async function cleanupAgentImprovementWorkspace(input) {
@@ -47750,7 +48505,7 @@ async function cleanupAgentImprovementWorkspace(input) {
47750
48505
  await command("git", ["branch", "-D", input.git.branch], input.repoPath);
47751
48506
  }
47752
48507
  if (input.git.worktreePath) {
47753
- await rm2(path49.dirname(input.git.worktreePath), {
48508
+ await rm3(path49.dirname(input.git.worktreePath), {
47754
48509
  recursive: true,
47755
48510
  force: true
47756
48511
  }).catch(() => void 0);
@@ -48861,7 +49616,7 @@ function uniqueEvidence2(run, evidence) {
48861
49616
  }
48862
49617
  async function verifyAppliedProfileCommit(input) {
48863
49618
  const command = input.command ?? (async (name, args, cwd, env) => {
48864
- const { runWorkspaceCommand } = await import("./workspaces-WXM72UZF.js");
49619
+ const { runWorkspaceCommand } = await import("./workspaces-XM5BY3MO.js");
48865
49620
  return runWorkspaceCommand(name, args, cwd, env);
48866
49621
  });
48867
49622
  const result2 = await command("git", ["rev-parse", "HEAD"], input.repoPath);
@@ -49202,6 +49957,7 @@ function createCreateImproveRuntime(deps) {
49202
49957
  modelId,
49203
49958
  messages,
49204
49959
  requestId: `${input.turn.id}:create-improve-planner`,
49960
+ promptCacheKey: input.session.id,
49205
49961
  signal: input.signal
49206
49962
  })
49207
49963
  });
@@ -50282,8 +51038,8 @@ function createSubagentWorkspaceRuntime(deps) {
50282
51038
  }
50283
51039
  const existing = [];
50284
51040
  for (const relDir of relDirs) {
50285
- const stat = await safeLstat(path52.join(parentRepoPath, ...relDir.split("/").filter(Boolean)));
50286
- if (stat?.isDirectory()) existing.push(relDir);
51041
+ const stat2 = await safeLstat(path52.join(parentRepoPath, ...relDir.split("/").filter(Boolean)));
51042
+ if (stat2?.isDirectory()) existing.push(relDir);
50287
51043
  }
50288
51044
  return existing;
50289
51045
  }
@@ -51348,7 +52104,7 @@ function sandboxRank(sandbox) {
51348
52104
  }
51349
52105
 
51350
52106
  // ../server/src/runtime/subagents/messaging-runtime.ts
51351
- import { randomUUID as randomUUID15 } from "node:crypto";
52107
+ import { randomUUID as randomUUID16 } from "node:crypto";
51352
52108
  function subagentActiveTurnIsDurablyTerminal(active, durableTurn) {
51353
52109
  return Boolean(
51354
52110
  active && durableTurn?.id === active.turn.id && durableTurn.status !== "in_progress"
@@ -51392,7 +52148,7 @@ function createSubagentMessagingRuntime(deps) {
51392
52148
  reason: delivered ? null : input.toRunId || input.toRole ? "No matching active child run was available for delivery." : "No target run or role was supplied."
51393
52149
  };
51394
52150
  let message = SubagentMessageSchema.parse({
51395
- id: randomUUID15(),
52151
+ id: randomUUID16(),
51396
52152
  fromRunId,
51397
52153
  toRunId: input.toRunId ?? null,
51398
52154
  toRole: input.toRole ?? null,
@@ -51467,7 +52223,7 @@ function createSubagentMessagingRuntime(deps) {
51467
52223
  reason: input.run.childSessionId ? null : "The child run has no child conversation."
51468
52224
  });
51469
52225
  const message = SubagentMessageSchema.parse({
51470
- id: randomUUID15(),
52226
+ id: randomUUID16(),
51471
52227
  fromRunId: input.context.session.subagentRunId ?? `parent:${input.context.session.id}`,
51472
52228
  toRunId: input.run.id,
51473
52229
  toRole: input.run.roleId,
@@ -52296,7 +53052,7 @@ function completionNotifications(run) {
52296
53052
  }
52297
53053
 
52298
53054
  // ../server/src/runtime/subagents/tool-runtime.ts
52299
- import { randomUUID as randomUUID16 } from "node:crypto";
53055
+ import { randomUUID as randomUUID17 } from "node:crypto";
52300
53056
  function createSubagentToolRuntime(deps) {
52301
53057
  const SUBAGENT_JOIN_WAIT_MS = 6e4;
52302
53058
  const SUBAGENT_JOIN_POLL_MS = 250;
@@ -52390,7 +53146,7 @@ function createSubagentToolRuntime(deps) {
52390
53146
  );
52391
53147
  }
52392
53148
  }
52393
- const runId = randomUUID16();
53149
+ const runId = randomUUID17();
52394
53150
  const createdAt = now();
52395
53151
  const childTurnPermissions = subagentChildTurnPermissions(
52396
53152
  context.turnPermissions,
@@ -53737,7 +54493,7 @@ function createTurnRunner(deps) {
53737
54493
  } : {}
53738
54494
  };
53739
54495
  const turn = {
53740
- id: randomUUID17(),
54496
+ id: randomUUID18(),
53741
54497
  sessionId,
53742
54498
  providerTurnId: null,
53743
54499
  modelRef: turnModelRef,
@@ -54075,6 +54831,7 @@ function createTurnRunner(deps) {
54075
54831
  modelId: runtimeModel,
54076
54832
  messages: streamInput.messages,
54077
54833
  requestId: streamInput.requestId,
54834
+ promptCacheKey: session.id,
54078
54835
  reasoningEffort: turnPermissions.codexReasoningEffort,
54079
54836
  signal: streamInput.signal ?? controller.signal
54080
54837
  })) {
@@ -54125,6 +54882,7 @@ function createTurnRunner(deps) {
54125
54882
  toolChoice: options?.toolChoice,
54126
54883
  maxOutputTokens: options?.maxOutputTokens,
54127
54884
  requestId: options?.requestId ?? turn.id,
54885
+ promptCacheKey: session.id,
54128
54886
  signal: controller.signal
54129
54887
  })) {
54130
54888
  if (delta.text) yield { text: delta.text, raw: delta.raw };
@@ -54364,7 +55122,7 @@ function createImproveLimit(value) {
54364
55122
  }
54365
55123
 
54366
55124
  // ../server/src/store/session-store.ts
54367
- import { randomUUID as randomUUID18 } from "node:crypto";
55125
+ import { randomUUID as randomUUID19 } from "node:crypto";
54368
55126
  function createSessionStore(deps) {
54369
55127
  const {
54370
55128
  store,
@@ -54377,7 +55135,7 @@ function createSessionStore(deps) {
54377
55135
  async function createSession(payload) {
54378
55136
  const input = CreateSessionRequestSchema.parse(payload);
54379
55137
  const createdAt = now();
54380
- const sessionId = randomUUID18();
55138
+ const sessionId = randomUUID19();
54381
55139
  const sessionCount = await store.sessionCount();
54382
55140
  const workspaceKind = input.workspaceKind ?? (input.appId ? "sandbox_app" : void 0);
54383
55141
  const openPondCommandAccessMode = input.openPondCommandAccessMode ?? (loadAppPreferences ? (await loadAppPreferences()).openPondCommandAccessMode : DEFAULT_OPENPOND_COMMAND_ACCESS_MODE);
@@ -54580,7 +55338,7 @@ function normalizeSession(session, sidebarPatch) {
54580
55338
  }
54581
55339
 
54582
55340
  // ../server/src/session-title-service.ts
54583
- import { randomUUID as randomUUID19 } from "node:crypto";
55341
+ import { randomUUID as randomUUID20 } from "node:crypto";
54584
55342
  var SESSION_TITLE_MODEL = "accounts/fireworks/models/deepseek-v4-flash";
54585
55343
  var SESSION_TITLE_REASONING_EFFORT = "low";
54586
55344
  var TITLE_TIMEOUT_MS = 12e3;
@@ -54644,7 +55402,7 @@ function createSessionTitleService(deps) {
54644
55402
  reasoningEffort: SESSION_TITLE_REASONING_EFFORT,
54645
55403
  maxTokens: 32,
54646
55404
  temperature: 0.2,
54647
- requestId: `session-title-${randomUUID19()}`,
55405
+ requestId: `session-title-${randomUUID20()}`,
54648
55406
  signal: controller.signal
54649
55407
  })) {
54650
55408
  if (delta.type === "text_delta" && delta.text) generated += delta.text;
@@ -54923,6 +55681,147 @@ var SqliteWorkEvidenceStore = class extends SqliteHarnessWorkspaceStore {
54923
55681
  }
54924
55682
  };
54925
55683
 
55684
+ // ../server/src/store/store-chat-workflows.ts
55685
+ var SqliteChatWorkflowStore = class extends SqliteWorkEvidenceStore {
55686
+ async listChatWorkflows(query = {}) {
55687
+ await this.ready;
55688
+ await this.writeQueue;
55689
+ const rows = await this.all(
55690
+ `SELECT * FROM chat_workflows
55691
+ ${query.sessionId ? "WHERE session_id = ?" : ""}
55692
+ ORDER BY created_at DESC`,
55693
+ query.sessionId ? [query.sessionId] : []
55694
+ );
55695
+ return rows.map((row) => JSON.parse(row.payload));
55696
+ }
55697
+ async listDueChatWorkflows(nowIso, limit = 25) {
55698
+ await this.ready;
55699
+ await this.writeQueue;
55700
+ const rows = await this.all(
55701
+ `SELECT * FROM chat_workflows
55702
+ WHERE enabled = 1 AND next_run_at IS NOT NULL AND next_run_at <= ?
55703
+ ORDER BY next_run_at ASC LIMIT ?`,
55704
+ [nowIso, Math.max(1, Math.min(100, Math.trunc(limit)))]
55705
+ );
55706
+ return rows.map((row) => JSON.parse(row.payload));
55707
+ }
55708
+ async getChatWorkflow(id) {
55709
+ await this.ready;
55710
+ await this.writeQueue;
55711
+ const row = await this.get("SELECT * FROM chat_workflows WHERE id = ?", [id]);
55712
+ return row ? JSON.parse(row.payload) : null;
55713
+ }
55714
+ async upsertChatWorkflow(workflow) {
55715
+ await this.ready;
55716
+ const write = this.writeQueue.then(async () => {
55717
+ await this.run(
55718
+ `INSERT INTO chat_workflows
55719
+ (id, session_id, enabled, next_run_at, payload, created_at, updated_at)
55720
+ VALUES (?, ?, ?, ?, ?, ?, ?)
55721
+ ON CONFLICT(id) DO UPDATE SET
55722
+ session_id = excluded.session_id,
55723
+ enabled = excluded.enabled,
55724
+ next_run_at = excluded.next_run_at,
55725
+ payload = excluded.payload,
55726
+ updated_at = excluded.updated_at`,
55727
+ [
55728
+ workflow.id,
55729
+ workflow.sessionId,
55730
+ workflow.enabled ? 1 : 0,
55731
+ workflow.nextRunAt,
55732
+ JSON.stringify(workflow),
55733
+ workflow.createdAt,
55734
+ workflow.updatedAt
55735
+ ]
55736
+ );
55737
+ });
55738
+ this.writeQueue = write.catch(() => void 0);
55739
+ await write;
55740
+ return await this.getChatWorkflow(workflow.id) ?? workflow;
55741
+ }
55742
+ async patchChatWorkflow(id, updater) {
55743
+ await this.ready;
55744
+ let updated = null;
55745
+ const write = this.writeQueue.then(async () => {
55746
+ const row = await this.get("SELECT * FROM chat_workflows WHERE id = ?", [id]);
55747
+ if (!row) return;
55748
+ updated = updater(JSON.parse(row.payload));
55749
+ await this.run(
55750
+ "UPDATE chat_workflows SET enabled = ?, next_run_at = ?, payload = ?, updated_at = ? WHERE id = ?",
55751
+ [updated.enabled ? 1 : 0, updated.nextRunAt, JSON.stringify(updated), updated.updatedAt, id]
55752
+ );
55753
+ });
55754
+ this.writeQueue = write.catch(() => void 0);
55755
+ await write;
55756
+ return updated;
55757
+ }
55758
+ async deleteChatWorkflow(id) {
55759
+ await this.ready;
55760
+ let changed = false;
55761
+ const write = this.writeQueue.then(async () => {
55762
+ const existing = await this.get("SELECT id FROM chat_workflows WHERE id = ?", [id]);
55763
+ if (!existing) return;
55764
+ await this.run("DELETE FROM chat_workflows WHERE id = ?", [id]);
55765
+ changed = true;
55766
+ });
55767
+ this.writeQueue = write.catch(() => void 0);
55768
+ await write;
55769
+ return changed;
55770
+ }
55771
+ async insertChatWorkflowRun(run) {
55772
+ await this.ready;
55773
+ const write = this.writeQueue.then(async () => {
55774
+ await this.run(
55775
+ `INSERT INTO chat_workflow_runs
55776
+ (id, workflow_id, session_id, scheduled_for, trigger, status, payload, created_at, updated_at)
55777
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
55778
+ [
55779
+ run.id,
55780
+ run.workflowId,
55781
+ run.sessionId,
55782
+ run.scheduledFor,
55783
+ run.trigger,
55784
+ run.status,
55785
+ JSON.stringify(run),
55786
+ run.createdAt,
55787
+ run.updatedAt
55788
+ ]
55789
+ );
55790
+ });
55791
+ this.writeQueue = write.catch(() => void 0);
55792
+ await write;
55793
+ return run;
55794
+ }
55795
+ async listChatWorkflowRuns(workflowId, limit = 100) {
55796
+ await this.ready;
55797
+ await this.writeQueue;
55798
+ const boundedLimit = Math.max(1, Math.min(500, Math.trunc(limit)));
55799
+ const rows = await this.all(
55800
+ `SELECT * FROM chat_workflow_runs
55801
+ ${workflowId ? "WHERE workflow_id = ?" : ""}
55802
+ ORDER BY created_at DESC LIMIT ?`,
55803
+ workflowId ? [workflowId, boundedLimit] : [boundedLimit]
55804
+ );
55805
+ return rows.map((row) => JSON.parse(row.payload));
55806
+ }
55807
+ async patchChatWorkflowRun(id, updater) {
55808
+ await this.ready;
55809
+ let updated = null;
55810
+ const write = this.writeQueue.then(async () => {
55811
+ const row = await this.get("SELECT * FROM chat_workflow_runs WHERE id = ?", [id]);
55812
+ if (!row) return;
55813
+ updated = updater(JSON.parse(row.payload));
55814
+ await this.run(
55815
+ "UPDATE chat_workflow_runs SET status = ?, payload = ?, updated_at = ? WHERE id = ?",
55816
+ [updated.status, JSON.stringify(updated), updated.updatedAt, id]
55817
+ );
55818
+ });
55819
+ this.writeQueue = write.catch(() => void 0);
55820
+ await write;
55821
+ return updated;
55822
+ }
55823
+ };
55824
+
54926
55825
  // ../server/src/store/session-runtime-summary.ts
54927
55826
  function sessionRuntimeSummaries(turns) {
54928
55827
  const mutableBySessionId = /* @__PURE__ */ new Map();
@@ -54968,7 +55867,7 @@ var NON_TERMINAL_SUBAGENT_STATUSES = [
54968
55867
  "running",
54969
55868
  "needs_resume"
54970
55869
  ];
54971
- var SqliteStore = class extends SqliteWorkEvidenceStore {
55870
+ var SqliteStore = class extends SqliteChatWorkflowStore {
54972
55871
  async snapshot() {
54973
55872
  await this.ready;
54974
55873
  await this.writeQueue;
@@ -56666,6 +57565,7 @@ export {
56666
57565
  createOpenPondCommandAccessService,
56667
57566
  commandResultForModel,
56668
57567
  createCloudConnectedAppToolExecutor,
57568
+ isManagedLocalWorkSession,
56669
57569
  trustedProviderContextLimit,
56670
57570
  appDataDir,
56671
57571
  providersConfigPath,
@@ -56732,17 +57632,21 @@ export {
56732
57632
  readTasksetAuthoringProfileSkill,
56733
57633
  createCrossSystemExpertBootstrapService,
56734
57634
  createTaskCreatorService,
57635
+ buildTasksetReadiness,
56735
57636
  persistBinaryTaskAttemptArtifact,
57637
+ NativeToolCallAccumulator,
56736
57638
  createWebFetchModelToolDefinition,
56737
57639
  createWebSearchModelToolDefinition,
56738
57640
  waitForWorkReceiptSettlement,
57641
+ resolveTasksetTrainingAssetBytes,
57642
+ resolveTasksetEvaluationAssetBytes,
56739
57643
  hostedTokenPricingFromValue,
56740
57644
  hostedUsageCostUsd,
56741
57645
  compileDesktopHarnessContext,
56742
57646
  persistCanonicalEvaluationEvidence,
56743
57647
  createTaskEvaluationService,
56744
57648
  qualifyHarnessModelImprovement,
56745
- requireQualifiedModelImprovement,
57649
+ resolveModelImprovementQualificationEvidence,
56746
57650
  retryableHostedError,
56747
57651
  hostedRetryDelayMs,
56748
57652
  abortableDelay,