@taskforcehq/taskforce 0.3.329 → 0.3.332

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 (363) hide show
  1. package/README.md +7 -2
  2. package/dist/Taskforce.module.css +290 -45
  3. package/dist/components/features/AiProfilesModule.js +3 -5
  4. package/dist/components/features/TaskSettings.js +70 -14
  5. package/dist/components/features/TaskforceAgentsModule.d.ts +1 -2
  6. package/dist/components/features/TaskforceAgentsModule.js +586 -116
  7. package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.d.ts +2 -2
  8. package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.js +2 -2
  9. package/dist/components/features/agentConnections/AgentConnectionControl.d.ts +15 -0
  10. package/dist/components/features/agentConnections/AgentConnectionControl.js +125 -0
  11. package/dist/components/features/agentConnections/ModelConnectionsPanel.d.ts +18 -0
  12. package/dist/components/features/agentConnections/ModelConnectionsPanel.js +393 -0
  13. package/dist/components/features/agentConnections/modelConnectionsApi.d.ts +65 -0
  14. package/dist/components/features/agentConnections/modelConnectionsApi.js +129 -0
  15. package/dist/components/features/planning/PlanningModule.js +15 -3
  16. package/dist/components/features/planning/planningMetadata.d.ts +10 -0
  17. package/dist/components/features/planning/planningMetadata.js +8 -0
  18. package/dist/components/features/taskforceAgentAssignments/AgentBehaviorAssignments.js +15 -24
  19. package/dist/components/features/taskforceAgentEditorModel.d.ts +2 -1
  20. package/dist/components/features/taskforceAgentEditorModel.js +3 -1
  21. package/dist/components/features/workflowManager/workflowManagerApi.d.ts +1 -1
  22. package/dist/components/features/workflowManager/workflowManagerApi.js +3 -0
  23. package/dist/components/task/TaskWorkflowAssignmentField.js +68 -10
  24. package/dist/components/views/StandaloneLayout.js +62 -27
  25. package/dist/components/views/panels/PlanningDrawer.d.ts +2 -1
  26. package/dist/components/views/panels/PlanningDrawer.js +12 -8
  27. package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +4 -3
  28. package/dist/components/views/standalone/modals/SyncStatusModal.js +33 -38
  29. package/dist/config/envSchema.js +55 -1
  30. package/dist/core/McpTokenService.d.ts +25 -1
  31. package/dist/core/McpTokenService.js +106 -15
  32. package/dist/core/TaskChecklistCommandService.d.ts +27 -0
  33. package/dist/core/TaskChecklistCommandService.js +83 -5
  34. package/dist/core/TaskLifecycleCommandService.d.ts +3 -1
  35. package/dist/core/TaskLifecycleCommandService.js +6 -2
  36. package/dist/core/Taskforce.d.ts +43 -3
  37. package/dist/core/Taskforce.js +158 -7
  38. package/dist/core/types.d.ts +9 -0
  39. package/dist/documentReviews/DocumentReviewCommentStore.d.ts +2 -0
  40. package/dist/documentReviews/DocumentReviewCommentStore.js +28 -9
  41. package/dist/documentReviews/commandService.d.ts +2 -1
  42. package/dist/documentReviews/commandService.js +6 -3
  43. package/dist/hooks/sync/orchestratorShared.d.ts +1 -0
  44. package/dist/hooks/sync/orchestratorShared.js +2 -0
  45. package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.d.ts +3 -0
  46. package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.js +85 -9
  47. package/dist/hooks/sync/useSyncStatusControls.d.ts +4 -1
  48. package/dist/hooks/sync/useSyncStatusControls.js +47 -11
  49. package/dist/hooks/useSyncOrchestrator.d.ts +3 -0
  50. package/dist/hooks/useSyncOrchestrator.js +111 -2
  51. package/dist/hooks/useTaskData.d.ts +31 -1
  52. package/dist/hooks/useTaskData.js +29 -7
  53. package/dist/hooks/useTaskMutations.d.ts +3 -1
  54. package/dist/hooks/useTaskMutations.js +46 -12
  55. package/dist/hooks/useTaskforce.d.ts +2 -0
  56. package/dist/hooks/useTaskforce.js +11 -2
  57. package/dist/mcp/clientRegistry.d.ts +2 -2
  58. package/dist/mcp/clientRegistry.js +1 -1
  59. package/dist/mcp/documentAssetRegistrar.js +9 -6
  60. package/dist/mcp/durableTaskMutationRouter.d.ts +4 -1
  61. package/dist/mcp/durableTaskMutationRouter.js +10 -0
  62. package/dist/mcp/durableTaskRelationshipMutationRouter.js +4 -0
  63. package/dist/mcp/httpProtocolRouting.d.ts +11 -0
  64. package/dist/mcp/httpProtocolRouting.js +22 -0
  65. package/dist/mcp/localCliHealth.d.ts +2 -2
  66. package/dist/mcp/localCliHealth.js +2 -2
  67. package/dist/mcp/localServiceProxy.d.ts +1 -0
  68. package/dist/mcp/localServiceProxy.js +530 -68
  69. package/dist/mcp/planningAttachmentCommandAdapter.d.ts +3 -1
  70. package/dist/mcp/planningAttachmentCommandAdapter.js +20 -2
  71. package/dist/mcp/runtime.d.ts +54 -79
  72. package/dist/mcp/runtime.js +408 -102
  73. package/dist/mcp/taskPlanningRegistrar.js +25 -6
  74. package/dist/mcp/toolProfiles.d.ts +2 -0
  75. package/dist/mcp/toolProfiles.js +11 -0
  76. package/dist/mcp/toolRegistry.d.ts +1 -0
  77. package/dist/mcp/toolRegistry.js +9 -8
  78. package/dist/mcp/workflowExecutionRegistrar.js +4 -4
  79. package/dist/migrations/taskSchemaMigrations.d.ts +5 -0
  80. package/dist/migrations/taskSchemaMigrations.js +415 -0
  81. package/dist/runtime/appGates.d.ts +2 -1
  82. package/dist/runtime/appGates.js +7 -0
  83. package/dist/server/buildInfo.d.ts +1 -0
  84. package/dist/server/buildInfo.js +5 -1
  85. package/dist/server/cloudMcpCapacityTelemetry.d.ts +68 -0
  86. package/dist/server/cloudMcpCapacityTelemetry.js +221 -0
  87. package/dist/server/index.d.ts +3 -0
  88. package/dist/server/index.js +108 -11
  89. package/dist/server/localDatabaseIdentity.js +4 -1
  90. package/dist/server/localServiceLease.js +2 -1
  91. package/dist/server/localServiceSessions.d.ts +14 -17
  92. package/dist/server/localServiceSessions.js +308 -94
  93. package/dist/server/localWorkspaceSyncServerRuntime.js +25 -19
  94. package/dist/server/routes/admin.d.ts +4 -0
  95. package/dist/server/routes/admin.js +126 -5
  96. package/dist/server/routes/agents.d.ts +7 -0
  97. package/dist/server/routes/agents.js +277 -24
  98. package/dist/server/routes/billing.js +5 -1
  99. package/dist/server/routes/durableTaskHttpRouters.d.ts +2 -0
  100. package/dist/server/routes/executorPhaseAApprovals.d.ts +19 -0
  101. package/dist/server/routes/executorPhaseAApprovals.js +140 -0
  102. package/dist/server/routes/executorPhaseAIssuerRedemptions.d.ts +11 -0
  103. package/dist/server/routes/executorPhaseAIssuerRedemptions.js +24 -0
  104. package/dist/server/routes/githubReviewEvidence.d.ts +19 -0
  105. package/dist/server/routes/githubReviewEvidence.js +116 -0
  106. package/dist/server/routes/localService.d.ts +15 -4
  107. package/dist/server/routes/localService.js +136 -40
  108. package/dist/server/routes/modelConnections.d.ts +24 -0
  109. package/dist/server/routes/modelConnections.js +205 -0
  110. package/dist/server/routes/shared.d.ts +22 -0
  111. package/dist/server/routes/shared.js +298 -182
  112. package/dist/server/routes/sync.js +1 -0
  113. package/dist/server/routes/syncAuxRoutes.js +5 -1
  114. package/dist/server/routes/syncPushRoutes.d.ts +1 -0
  115. package/dist/server/routes/syncPushRoutes.js +1 -0
  116. package/dist/server/routes/syncV3FeedRoutes.js +10 -1
  117. package/dist/server/routes/syncV3OperationRoutes.js +35 -9
  118. package/dist/server/routes/tasks.js +21 -2
  119. package/dist/server/routes/workflows.js +9 -1
  120. package/dist/server/routes.js +59 -0
  121. package/dist/service/localServiceCli.d.ts +2 -2
  122. package/dist/service/localServiceCli.js +4 -3
  123. package/dist/services/codexAppServerModelGateway.d.ts +54 -5
  124. package/dist/services/codexAppServerModelGateway.js +246 -21
  125. package/dist/services/codexDeviceCodeLoginManager.d.ts +39 -0
  126. package/dist/services/codexDeviceCodeLoginManager.js +265 -0
  127. package/dist/services/codexModelProviderConnectionLifecycle.d.ts +8 -0
  128. package/dist/services/codexModelProviderConnectionLifecycle.js +73 -0
  129. package/dist/services/executorPhaseAApprovalRuntime.d.ts +14 -0
  130. package/dist/services/executorPhaseAApprovalRuntime.js +24 -0
  131. package/dist/services/executorPhaseAApprovalService.d.ts +40 -0
  132. package/dist/services/executorPhaseAApprovalService.js +609 -0
  133. package/dist/services/executorPhaseADriftEvaluator.d.ts +78 -0
  134. package/dist/services/executorPhaseADriftEvaluator.js +93 -0
  135. package/dist/services/executorPhaseAIssuerCore.d.ts +139 -0
  136. package/dist/services/executorPhaseAIssuerCore.js +402 -0
  137. package/dist/services/executorPhaseAIssuerRedemptionService.d.ts +34 -0
  138. package/dist/services/executorPhaseAIssuerRedemptionService.js +158 -0
  139. package/dist/services/githubReviewEvidenceRuntime.d.ts +14 -0
  140. package/dist/services/githubReviewEvidenceRuntime.js +30 -0
  141. package/dist/services/githubReviewEvidenceService.d.ts +93 -0
  142. package/dist/services/githubReviewEvidenceService.js +336 -0
  143. package/dist/services/modelGateway.d.ts +7 -0
  144. package/dist/services/modelProviderConnectionService.d.ts +71 -0
  145. package/dist/services/modelProviderConnectionService.js +279 -0
  146. package/dist/services/modelProviderCredentialHome.d.ts +32 -0
  147. package/dist/services/modelProviderCredentialHome.js +271 -0
  148. package/dist/services/ownerScopedModelConnectionGateway.d.ts +12 -0
  149. package/dist/services/ownerScopedModelConnectionGateway.js +30 -0
  150. package/dist/services/taskforceAgentConnectionBindingService.d.ts +66 -0
  151. package/dist/services/taskforceAgentConnectionBindingService.js +185 -0
  152. package/dist/services/taskforceAgentMcpBridge.d.ts +2 -2
  153. package/dist/services/taskforceAgentMcpBridge.js +42 -29
  154. package/dist/shared/adminEdgeProxy.d.ts +5 -0
  155. package/dist/shared/adminEdgeProxy.js +94 -0
  156. package/dist/shared/adminProxySessionCookies.d.ts +16 -0
  157. package/dist/shared/adminProxySessionCookies.js +86 -0
  158. package/dist/shared/aiProfileColors.d.ts +31 -1
  159. package/dist/shared/aiProfileColors.js +14 -6
  160. package/dist/shared/executorPhaseAApprovalGoldenVector.json +269 -0
  161. package/dist/shared/executorPhaseAApprovalReceipt.d.ts +112 -0
  162. package/dist/shared/executorPhaseAApprovalReceipt.js +58 -0
  163. package/dist/shared/executorPhaseAApprovalTrustPolicy.json +10 -0
  164. package/dist/shared/executorPhaseADriftContracts.d.ts +37 -0
  165. package/dist/shared/executorPhaseADriftContracts.js +63 -0
  166. package/dist/shared/executorPhaseAIssuerContracts.d.ts +75 -0
  167. package/dist/shared/executorPhaseAIssuerContracts.js +90 -0
  168. package/dist/shared/executorPhaseARunAuthorization.d.ts +120 -0
  169. package/dist/shared/executorPhaseARunAuthorization.js +232 -0
  170. package/dist/shared/executorPhaseASchemaValidation.d.ts +7 -0
  171. package/dist/shared/executorPhaseASchemaValidation.js +53 -0
  172. package/dist/shared/executorPhaseASchemas/approval-receipt.schema.json +106 -0
  173. package/dist/shared/executorPhaseASchemas/drift-attestation.schema.json +54 -0
  174. package/dist/shared/executorPhaseASchemas/drift-request.schema.json +47 -0
  175. package/dist/shared/executorPhaseASchemas/foundation-manifest.schema.json +29 -0
  176. package/dist/shared/executorPhaseASchemas/issuer-audit-record.schema.json +24 -0
  177. package/dist/shared/executorPhaseASchemas/issuer-proof.schema.json +43 -0
  178. package/dist/shared/executorPhaseASchemas/issuer-redemption-request.schema.json +18 -0
  179. package/dist/shared/executorPhaseASchemas/issuer-redemption-response.schema.json +39 -0
  180. package/dist/shared/executorPhaseASchemas/logical-envelope.schema.json +149 -0
  181. package/dist/shared/executorPhaseASchemas/preflight-report.schema.json +216 -0
  182. package/dist/shared/executorPhaseASchemas/run-capability.schema.json +111 -0
  183. package/dist/shared/executorPhaseASchemas/sender-proof.schema.json +37 -0
  184. package/dist/shared/executorPhaseASchemas/workload-grant.schema.json +68 -0
  185. package/dist/shared/executorPhaseASchemas/workload-jwt-claims.schema.json +67 -0
  186. package/dist/shared/executorPhaseATiming.d.ts +1 -0
  187. package/dist/shared/executorPhaseATiming.js +1 -0
  188. package/dist/shared/planningIdentity.js +1 -1
  189. package/dist/shared/productLogoKeys.d.ts +2 -0
  190. package/dist/shared/productLogoKeys.js +18 -0
  191. package/dist/shared/taskforceAgentDefinition.d.ts +0 -1
  192. package/dist/shared/taskforceAgentDefinition.js +6 -9
  193. package/dist/shared/taskforceAgentModels.js +7 -3
  194. package/dist/shared/userFeatureGrants.d.ts +4 -0
  195. package/dist/shared/userFeatureGrants.js +7 -0
  196. package/dist/storage/executorPhaseAApprovalReceiptStore.d.ts +37 -0
  197. package/dist/storage/executorPhaseAApprovalReceiptStore.js +81 -0
  198. package/dist/storage/executorPhaseARunAuthorizationStore.d.ts +103 -0
  199. package/dist/storage/executorPhaseARunAuthorizationStore.js +492 -0
  200. package/dist/storage/githubReviewEvidenceInstallationStore.d.ts +26 -0
  201. package/dist/storage/githubReviewEvidenceInstallationStore.js +89 -0
  202. package/dist/storage/modelProviderConnectionStore.d.ts +99 -0
  203. package/dist/storage/modelProviderConnectionStore.js +446 -0
  204. package/dist/storage/postgresAdapter.d.ts +4 -0
  205. package/dist/storage/postgresAdapter.js +14 -1
  206. package/dist/storage/postgresRequestDiagnostics.d.ts +9 -1
  207. package/dist/storage/postgresRequestDiagnostics.js +15 -2
  208. package/dist/storage/postgresWorker.js +20 -2
  209. package/dist/storage/postgresWorkerProtocol.d.ts +7 -0
  210. package/dist/storage/taskforceAgentConnectionBindingStore.d.ts +31 -0
  211. package/dist/storage/taskforceAgentConnectionBindingStore.js +84 -0
  212. package/dist/storage/workflowStore.d.ts +2 -0
  213. package/dist/storage/workflowStore.js +39 -2
  214. package/dist/sync/cloudSyncApi.js +4 -2
  215. package/dist/sync/collaborationSyncState.js +5 -0
  216. package/dist/sync/coordinator/localSyncExecutionPermitStore.js +60 -29
  217. package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.d.ts +10 -0
  218. package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.js +29 -0
  219. package/dist/sync/coordinator/localWorkspaceSyncRunner.d.ts +3 -1
  220. package/dist/sync/coordinator/localWorkspaceSyncRunner.js +18 -0
  221. package/dist/sync/coordinator/localWorkspaceSyncRunnerState.d.ts +15 -1
  222. package/dist/sync/coordinator/localWorkspaceSyncRunnerState.js +99 -2
  223. package/dist/sync/coordinator/workspaceSyncCredentialBroker.d.ts +1 -0
  224. package/dist/sync/coordinator/workspaceSyncCredentialBroker.js +33 -4
  225. package/dist/sync/engine/workspaceSyncContentLifecycleAdapter.d.ts +2 -1
  226. package/dist/sync/engine/workspaceSyncContentVersionStore.d.ts +38 -0
  227. package/dist/sync/engine/workspaceSyncContentVersionStore.js +50 -1
  228. package/dist/sync/engine/workspaceSyncEngineLifecyclePolicy.js +6 -6
  229. package/dist/sync/engine/workspaceSyncEnginePushCompletion.d.ts +14 -0
  230. package/dist/sync/engine/workspaceSyncEnginePushCompletion.js +84 -0
  231. package/dist/sync/engine/workspaceSyncEngineRecovery.js +1 -0
  232. package/dist/sync/engine/workspaceSyncEngineRuntime.d.ts +1 -0
  233. package/dist/sync/engine/workspaceSyncEngineRuntime.js +1 -0
  234. package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +112 -38
  235. package/dist/sync/engine/workspaceSyncEngineServerSnapshotReader.js +6 -0
  236. package/dist/sync/engine/workspaceSyncEngineTransfers.js +3 -1
  237. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.d.ts +1 -0
  238. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.js +31 -0
  239. package/dist/sync/syncApplyHandlers.d.ts +3 -0
  240. package/dist/sync/syncApplyHandlers.js +81 -15
  241. package/dist/sync/syncService.d.ts +15 -0
  242. package/dist/sync/syncService.js +83 -18
  243. package/dist/sync/taskforceAgentSyncAuthorization.d.ts +16 -0
  244. package/dist/sync/taskforceAgentSyncAuthorization.js +20 -0
  245. package/dist/sync/v3/combinedFeedCapability.js +4 -0
  246. package/dist/sync/v3/durableInitiativeMutationRouter.js +18 -10
  247. package/dist/sync/v3/durableOperationReplay.d.ts +14 -0
  248. package/dist/sync/v3/durableOperationReplay.js +18 -0
  249. package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +3 -0
  250. package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +2 -1
  251. package/dist/sync/v3/durableTaskChecklistMutationRouter.js +58 -15
  252. package/dist/sync/v3/durableTaskCommentMutationRouter.js +3 -0
  253. package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +1 -1
  254. package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +10 -0
  255. package/dist/sync/v3/durableTaxonomyMutationRouter.js +5 -0
  256. package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.d.ts +18 -7
  257. package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.js +89 -23
  258. package/dist/sync/v3/durableWorkstreamMutationRouter.js +18 -10
  259. package/dist/sync/v3/durableWorkstreamTaskOrderMutationRouter.js +16 -5
  260. package/dist/sync/v3/localOutboxDispatchRuntime.js +2 -2
  261. package/dist/sync/v3/localOutboxRecoveryPreparationService.js +8 -2
  262. package/dist/sync/v3/localTaskChecklistOutboxHandler.js +16 -2
  263. package/dist/sync/v3/localTaskChecklistOutboxService.d.ts +4 -0
  264. package/dist/sync/v3/localTaskChecklistOutboxService.js +14 -1
  265. package/dist/sync/v3/localTaskCreateOutboxService.d.ts +3 -1
  266. package/dist/sync/v3/localTaskCreateOutboxService.js +6 -1
  267. package/dist/sync/v3/localTaskDeleteOutboxService.js +1 -0
  268. package/dist/sync/v3/localTaskLifecycleOutboxService.d.ts +2 -1
  269. package/dist/sync/v3/localTaskLifecycleOutboxService.js +5 -1
  270. package/dist/sync/v3/localTaskMetadataOutboxService.d.ts +2 -1
  271. package/dist/sync/v3/localTaskMetadataOutboxService.js +6 -2
  272. package/dist/sync/v3/localTaskStatusOutboxService.d.ts +10 -1
  273. package/dist/sync/v3/localTaskStatusOutboxService.js +238 -16
  274. package/dist/sync/v3/syncDurabilityStore.d.ts +36 -1
  275. package/dist/sync/v3/syncDurabilityStore.js +202 -8
  276. package/dist/sync/v3/taskChecklistMutationService.d.ts +11 -0
  277. package/dist/sync/v3/taskChecklistMutationService.js +44 -1
  278. package/dist/sync/v3/taskStatusMutationService.d.ts +29 -1
  279. package/dist/sync/v3/taskStatusMutationService.js +119 -3
  280. package/dist/sync/v3/workflowAssignmentSync.d.ts +5 -0
  281. package/dist/sync/v3/workflowAssignmentSync.js +27 -0
  282. package/dist/sync/v3/workflowRuntimeMutationService.d.ts +5 -0
  283. package/dist/sync/v3/workflowRuntimeMutationService.js +124 -71
  284. package/dist/sync/v3/workspaceSyncJournalReader.js +1 -1
  285. package/dist/sync/v3/workspaceSyncOperationRetentionService.d.ts +16 -0
  286. package/dist/sync/v3/workspaceSyncOperationRetentionService.js +83 -0
  287. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.d.ts +1 -0
  288. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +9 -2
  289. package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.js +25 -3
  290. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +7 -0
  291. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +44 -32
  292. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +9 -5
  293. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +54 -38
  294. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +10 -0
  295. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +70 -31
  296. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +2 -1
  297. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +16 -0
  298. package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +6 -0
  299. package/dist/sync/v3/workspaceSyncV3Feed.d.ts +1 -0
  300. package/dist/sync/v3/workspaceSyncV3Feed.js +6 -1
  301. package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.d.ts +2 -0
  302. package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.js +49 -18
  303. package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +3 -0
  304. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +5 -0
  305. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +36 -2
  306. package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.d.ts +17 -0
  307. package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.js +64 -0
  308. package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeApply.d.ts +1 -0
  309. package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeApply.js +50 -5
  310. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.d.ts +7 -0
  311. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.js +33 -0
  312. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.d.ts +7 -0
  313. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.js +8 -0
  314. package/dist/sync/workspaceRepair.d.ts +5 -2
  315. package/dist/sync/workspaceRepair.js +161 -6
  316. package/dist/sync/workspaceSyncModel.d.ts +21 -0
  317. package/dist/sync/workspaceSyncModel.js +35 -7
  318. package/dist/sync/workspaceSyncState.d.ts +1 -0
  319. package/dist/sync/workspaceSyncV2SnapshotBuilder.d.ts +6 -0
  320. package/dist/sync/workspaceSyncV2SnapshotBuilder.js +5 -0
  321. package/dist/ui/assets/AiIdentityRosterCard-CDMPtnbC.js +1 -0
  322. package/dist/ui/assets/AiProfilesModule-Cww85C4E.js +1 -0
  323. package/dist/ui/assets/{AnnotatedAttachmentWorkspace-B68Wg-RV.js → AnnotatedAttachmentWorkspace-Dt9TKYSH.js} +1 -1
  324. package/dist/ui/assets/{AssetTraySortControl-C8Rztyal.js → AssetTraySortControl-CKgapnxu.js} +1 -1
  325. package/dist/ui/assets/{ContextAttachmentManager-Cj3c7X9y.js → ContextAttachmentManager-T-cEVcOZ.js} +2 -2
  326. package/dist/ui/assets/{DocumentWorkspace-B5uvzems.js → DocumentWorkspace-HD4MUjAZ.js} +1 -1
  327. package/dist/ui/assets/{EntityActivityTimeline-BVFvCB5R.js → EntityActivityTimeline-_V0zfMuh.js} +1 -1
  328. package/dist/ui/assets/PlanningModule-mTkBygsB.js +1 -0
  329. package/dist/ui/assets/{PlansPage-AY4cGWco.js → PlansPage-Btiq06VO.js} +1 -1
  330. package/dist/ui/assets/{TaskContextUpload-DZxTVesW.js → TaskContextUpload-C00NVUpn.js} +1 -1
  331. package/dist/ui/assets/TaskSettings-Cp-L-4xh.js +12 -0
  332. package/dist/ui/assets/TaskforceAgentsModule-Coq9-PUp.js +24 -0
  333. package/dist/ui/assets/TaskforceAgentsModule-b-8R25cJ.css +1 -0
  334. package/dist/ui/assets/{WorkflowManagerModule-DEr5di_r.js → WorkflowManagerModule-CuqRzMmM.js} +1 -1
  335. package/dist/ui/assets/index-BZ-hdZSk.css +1 -0
  336. package/dist/ui/assets/index-DSQINwt9.js +7 -0
  337. package/dist/ui/assets/{vendor-icons-D9Lpw-j4.js → vendor-icons-Bsq-mcEn.js} +1 -1
  338. package/dist/ui/branding/logos/letterhead_dark.png +0 -0
  339. package/dist/ui/branding/logos/letterhead_light.png +0 -0
  340. package/dist/ui/branding/logos/signature_dark.png +0 -0
  341. package/dist/ui/branding/logos/signature_light.png +0 -0
  342. package/dist/ui/index.html +3 -3
  343. package/dist/utils/aiProfileDefaultLogo.js +16 -48
  344. package/dist/utils/httpSetCookie.d.ts +1 -0
  345. package/dist/utils/httpSetCookie.js +4 -1
  346. package/dist/utils/localRuntimeUrl.d.ts +1 -0
  347. package/dist/utils/localRuntimeUrl.js +14 -0
  348. package/dist/utils/productLogoRegistry.d.ts +2 -0
  349. package/dist/utils/productLogoRegistry.js +36 -0
  350. package/dist/utils/syncStatusPresentation.d.ts +4 -0
  351. package/dist/utils/syncStatusPresentation.js +17 -0
  352. package/dist/utils/taskEvents.d.ts +2 -0
  353. package/dist/utils/workspaceSyncPresentation.d.ts +1 -1
  354. package/dist/utils/workspaceSyncPresentation.js +23 -17
  355. package/package.json +24 -4
  356. package/dist/ui/assets/AiIdentityRosterCard-BZM4aQnM.js +0 -1
  357. package/dist/ui/assets/AiProfilesModule-BbAEWtHH.js +0 -1
  358. package/dist/ui/assets/PlanningModule-B5DWQOGz.js +0 -1
  359. package/dist/ui/assets/TaskSettings-BeWAuyZj.js +0 -12
  360. package/dist/ui/assets/TaskforceAgentsModule-BifCYtjR.js +0 -21
  361. package/dist/ui/assets/TaskforceAgentsModule-D6IC0S7Q.css +0 -1
  362. package/dist/ui/assets/index-I5zhdtgt.js +0 -7
  363. package/dist/ui/assets/index-VRFsx3wz.css +0 -1
@@ -203,11 +203,38 @@ export function normalizeTaskStatusOperationWithWorkflowAssignment(raw) {
203
203
  }
204
204
  originActor = { kind: 'ai-profile', profileId };
205
205
  }
206
+ let reviewHandoff;
207
+ if (source.reviewHandoff !== undefined) {
208
+ if (status.status !== 'review') {
209
+ throw new WorkflowAssignmentSyncError('reviewHandoff is valid only when status is review.');
210
+ }
211
+ const handoff = object(source.reviewHandoff, 'reviewHandoff');
212
+ if (Object.keys(handoff).join(',') !== 'comment') {
213
+ throw new WorkflowAssignmentSyncError('reviewHandoff must contain exactly comment.');
214
+ }
215
+ const comment = object(handoff.comment, 'reviewHandoff.comment');
216
+ if (Object.keys(comment).sort().join(',') !== 'author,id,submittedAuthor,text') {
217
+ throw new WorkflowAssignmentSyncError('reviewHandoff.comment must contain exactly id, author, submittedAuthor, and text.');
218
+ }
219
+ const author = text(comment.author, 'reviewHandoff.comment.author');
220
+ const submittedAuthor = text(comment.submittedAuthor, 'reviewHandoff.comment.submittedAuthor');
221
+ const commentText = text(comment.text, 'reviewHandoff.comment.text');
222
+ if (author !== submittedAuthor) {
223
+ throw new WorkflowAssignmentSyncError('reviewHandoff comment authorship is invalid.');
224
+ }
225
+ reviewHandoff = { comment: {
226
+ id: text(comment.id, 'reviewHandoff.comment.id'),
227
+ author,
228
+ submittedAuthor,
229
+ text: commentText,
230
+ } };
231
+ }
206
232
  return {
207
233
  ...status,
208
234
  ...(source.workflowAssignment === undefined
209
235
  ? {}
210
236
  : { workflowAssignment: normalizeWorkflowAssignmentSyncRecord(source.workflowAssignment) }),
237
+ ...(reviewHandoff ? { reviewHandoff } : {}),
211
238
  ...(originActor ? { originActor } : {}),
212
239
  ...(typeof source.expectedDetailRevision === 'string' && source.expectedDetailRevision.trim()
213
240
  ? { expectedDetailRevision: source.expectedDetailRevision.trim() }
@@ -53,6 +53,11 @@ export type PreparedWorkflowRuntimeMutation = {
53
53
  terminalEventId: string;
54
54
  taskActivityId: string;
55
55
  };
56
+ export declare class WorkflowRuntimeSemanticReplayError extends Error {
57
+ readonly code = "WORKFLOW_RUNTIME_SEMANTIC_REPLAY_REQUIRED";
58
+ readonly statusCode = 409;
59
+ constructor();
60
+ }
56
61
  export declare function prepareWorkflowRuntimeMutation(input: {
57
62
  workflowStore: WorkflowStore;
58
63
  workspaceId: string;
@@ -6,11 +6,42 @@ import { buildTaskActivityJournalEntry, serializeTaskActivityForSync, } from './
6
6
  import { fingerprintWorkspaceSyncPayload, WORKSPACE_SYNC_CONTRACT_VERSION, } from './syncDurabilityStore.js';
7
7
  import { buildWorkflowRuntimeEventId, buildWorkflowRuntimeTaskActivityId, } from './workflowRuntimeOperationIdentity.js';
8
8
  import { fingerprintWorkflowRuntimePayload, serializeWorkflowExecutionEventSyncPayload, serializeWorkflowExecutionRootSyncPayload, validateWorkflowRuntimeAuthoritativeResult, validateWorkflowRuntimeMutationCommand, } from './workflowRuntimeSync.js';
9
+ export class WorkflowRuntimeSemanticReplayError extends Error {
10
+ code = 'WORKFLOW_RUNTIME_SEMANTIC_REPLAY_REQUIRED';
11
+ statusCode = 409;
12
+ constructor() {
13
+ super('This workflow command was already completed by another synchronized runtime.');
14
+ this.name = 'WorkflowRuntimeSemanticReplayError';
15
+ }
16
+ }
17
+ function hasEquivalentCompletedStep(input) {
18
+ if (input.command.kind !== 'complete-step')
19
+ return false;
20
+ const events = input.workflowStore.listExecutionEvents(input.workspaceId, input.command.executionId);
21
+ const completed = events.find((event) => (event.idempotencyKey === `${input.command.idempotencyKey}:step-completed`));
22
+ const terminal = events.find((event) => (event.idempotencyKey === `${input.command.idempotencyKey}:step-started`
23
+ || event.idempotencyKey === `${input.command.idempotencyKey}:execution-completed`));
24
+ if (!completed || !terminal)
25
+ return false;
26
+ const evidence = completed.details.evidence;
27
+ const evidenceCommentId = evidence
28
+ && typeof evidence === 'object'
29
+ && !Array.isArray(evidence)
30
+ && evidence.type === 'comment'
31
+ ? String(evidence.commentId || '')
32
+ : '';
33
+ return completed.actorId === input.command.actorId
34
+ && terminal.actorId === input.command.actorId
35
+ && completed.stepId === input.command.expectedStepId
36
+ && evidenceCommentId === (input.command.evidenceCommentId || '');
37
+ }
9
38
  export function prepareWorkflowRuntimeMutation(input) {
10
39
  const before = input.workflowStore.getExecutionStateSnapshot(input.workspaceId, input.command.executionId);
11
40
  if (!before)
12
41
  throw new Error('Workflow execution not found.');
13
42
  if (before.execution.status !== input.command.expectedStatus) {
43
+ if (hasEquivalentCompletedStep(input))
44
+ throw new WorkflowRuntimeSemanticReplayError();
14
45
  throw new Error('Workflow execution has advanced beyond the expected status.');
15
46
  }
16
47
  if (input.command.kind === 'complete-step' && input.command.taskTarget.taskId !== before.execution.taskId) {
@@ -191,13 +222,25 @@ export function runDurableWorkflowRuntimeMutation(input) {
191
222
  response: JSON.parse(reservation.responseJson),
192
223
  };
193
224
  }
194
- const prepared = prepareWorkflowRuntimeMutation({
195
- workflowStore,
196
- workspaceId: input.workspaceId,
197
- clientId: input.clientId,
198
- operationId: input.operationId,
199
- command,
200
- });
225
+ let prepared;
226
+ try {
227
+ prepared = prepareWorkflowRuntimeMutation({
228
+ workflowStore,
229
+ workspaceId: input.workspaceId,
230
+ clientId: input.clientId,
231
+ operationId: input.operationId,
232
+ command,
233
+ });
234
+ }
235
+ catch (error) {
236
+ input.store.releaseFailedOperationReservation({
237
+ identity,
238
+ requestFingerprint,
239
+ leaseOwner: reservation.leaseOwner,
240
+ now: input.now,
241
+ });
242
+ throw error;
243
+ }
201
244
  const { before, willReassignTask, taskActivityId, eventIds } = prepared;
202
245
  const readTaskActivity = (result) => {
203
246
  const activity = result.taskActivity || input.core.getTaskEventForSync({
@@ -262,73 +305,83 @@ export function runDurableWorkflowRuntimeMutation(input) {
262
305
  },
263
306
  })),
264
307
  ];
265
- const accepted = input.store.acceptReservedOperationBatch({
266
- identity,
267
- requestFingerprint,
268
- leaseOwner: reservation.leaseOwner,
269
- now: input.now,
270
- entries,
271
- applyMutation: () => applyPreparedWorkflowRuntimeMutation({
272
- core: input.core,
273
- workflowStore,
274
- workspaceId: input.workspaceId,
275
- command,
276
- prepared,
277
- now: input.now,
278
- }),
279
- buildResponse: (result, revisions) => {
280
- const executionPayload = serializeWorkflowExecutionRootSyncPayload(result.executionResult.execution);
281
- const eventPayloads = result.executionResult.events.map(serializeWorkflowExecutionEventSyncPayload);
282
- const projectionRevisions = [
283
- {
284
- projection: 'workflow-execution/root-v1',
285
- ...revisionFor(revisions, 'workflow-execution', command.executionId),
286
- canonicalFingerprint: fingerprintWorkflowRuntimePayload(executionPayload),
287
- },
288
- ...result.newEvents.map((event) => {
289
- const payload = serializeWorkflowExecutionEventSyncPayload(event);
308
+ const accepted = (() => {
309
+ try {
310
+ return input.store.acceptReservedOperationBatch({
311
+ identity,
312
+ requestFingerprint,
313
+ leaseOwner: reservation.leaseOwner,
314
+ now: input.now,
315
+ entries,
316
+ applyMutation: () => applyPreparedWorkflowRuntimeMutation({
317
+ core: input.core,
318
+ workflowStore,
319
+ workspaceId: input.workspaceId,
320
+ command,
321
+ prepared,
322
+ now: input.now,
323
+ }),
324
+ buildResponse: (result, revisions) => {
325
+ const executionPayload = serializeWorkflowExecutionRootSyncPayload(result.executionResult.execution);
326
+ const eventPayloads = result.executionResult.events.map(serializeWorkflowExecutionEventSyncPayload);
327
+ const projectionRevisions = [
328
+ {
329
+ projection: 'workflow-execution/root-v1',
330
+ ...revisionFor(revisions, 'workflow-execution', command.executionId),
331
+ canonicalFingerprint: fingerprintWorkflowRuntimePayload(executionPayload),
332
+ },
333
+ ...result.newEvents.map((event) => {
334
+ const payload = serializeWorkflowExecutionEventSyncPayload(event);
335
+ return {
336
+ projection: 'workflow-execution-event/full-v1',
337
+ ...revisionFor(revisions, 'workflow-execution-event', event.id),
338
+ canonicalFingerprint: fingerprintWorkflowRuntimePayload(payload),
339
+ };
340
+ }),
341
+ ...(result.task ? [{
342
+ projection: 'task/root-v1',
343
+ ...revisionFor(revisions, 'task', result.task.id),
344
+ canonicalFingerprint: fingerprintWorkspaceSyncPayload(serializeTaskForSync(result.task)),
345
+ }, {
346
+ projection: 'entity-event/full-v1',
347
+ ...revisionFor(revisions, 'entity-event', readTaskActivity(result).id),
348
+ canonicalFingerprint: fingerprintWorkspaceSyncPayload(serializeTaskActivityForSync(readTaskActivity(result))),
349
+ }] : []),
350
+ ].sort((left, right) => BigInt(left.sequence) < BigInt(right.sequence) ? -1 : 1);
351
+ const authoritative = validateWorkflowRuntimeAuthoritativeResult({
352
+ execution: executionPayload,
353
+ events: eventPayloads,
354
+ acceptedEventIds: result.newEvents.map((event) => event.id),
355
+ ...(result.task ? {
356
+ task: {
357
+ payload: serializeTaskForSync(result.task),
358
+ activity: serializeTaskActivityForSync(readTaskActivity(result)),
359
+ },
360
+ } : {}),
361
+ revisions: projectionRevisions,
362
+ replayed: result.executionResult.replayed,
363
+ });
364
+ const executionRevision = revisionFor(revisions, 'workflow-execution', command.executionId);
290
365
  return {
291
- projection: 'workflow-execution-event/full-v1',
292
- ...revisionFor(revisions, 'workflow-execution-event', event.id),
293
- canonicalFingerprint: fingerprintWorkflowRuntimePayload(payload),
366
+ success: true,
367
+ contractVersion: WORKSPACE_SYNC_CONTRACT_VERSION,
368
+ workspaceId: input.workspaceId,
369
+ clientId: input.clientId,
370
+ operationId: input.operationId,
371
+ acceptedSequence: executionRevision.sequence,
372
+ operationHighWatermark: revisions.at(-1)?.sequence || executionRevision.sequence,
373
+ authoritative,
294
374
  };
295
- }),
296
- ...(result.task ? [{
297
- projection: 'task/root-v1',
298
- ...revisionFor(revisions, 'task', result.task.id),
299
- canonicalFingerprint: fingerprintWorkspaceSyncPayload(serializeTaskForSync(result.task)),
300
- }, {
301
- projection: 'entity-event/full-v1',
302
- ...revisionFor(revisions, 'entity-event', readTaskActivity(result).id),
303
- canonicalFingerprint: fingerprintWorkspaceSyncPayload(serializeTaskActivityForSync(readTaskActivity(result))),
304
- }] : []),
305
- ].sort((left, right) => BigInt(left.sequence) < BigInt(right.sequence) ? -1 : 1);
306
- const authoritative = validateWorkflowRuntimeAuthoritativeResult({
307
- execution: executionPayload,
308
- events: eventPayloads,
309
- acceptedEventIds: result.newEvents.map((event) => event.id),
310
- ...(result.task ? {
311
- task: {
312
- payload: serializeTaskForSync(result.task),
313
- activity: serializeTaskActivityForSync(readTaskActivity(result)),
314
- },
315
- } : {}),
316
- revisions: projectionRevisions,
317
- replayed: result.executionResult.replayed,
375
+ },
318
376
  });
319
- const executionRevision = revisionFor(revisions, 'workflow-execution', command.executionId);
320
- return {
321
- success: true,
322
- contractVersion: WORKSPACE_SYNC_CONTRACT_VERSION,
323
- workspaceId: input.workspaceId,
324
- clientId: input.clientId,
325
- operationId: input.operationId,
326
- acceptedSequence: executionRevision.sequence,
327
- operationHighWatermark: revisions.at(-1)?.sequence || executionRevision.sequence,
328
- authoritative,
329
- };
330
- },
331
- });
377
+ }
378
+ catch (error) {
379
+ if (hasEquivalentCompletedStep({ workflowStore, workspaceId: input.workspaceId, command })) {
380
+ throw new WorkflowRuntimeSemanticReplayError();
381
+ }
382
+ throw error;
383
+ }
384
+ })();
332
385
  const notify = (callback) => {
333
386
  if (!callback)
334
387
  return;
@@ -31,7 +31,7 @@ export class WorkspaceSyncJournalReader {
31
31
  CAST(lifecycle_revision AS TEXT) AS lifecycle_revision, content_sha256,
32
32
  CAST(size_bytes AS TEXT) AS size_bytes, payload_json, occurred_at FROM workspace_sync_journal
33
33
  WHERE tenant_id = ? AND workspace_id = ? AND sequence > ? AND sequence <= ?
34
- ORDER BY sequence ASC LIMIT ?`).all(input.tenantId, input.workspaceId, sequence(input.afterSequence), sequence(input.throughSequence), Math.max(1, Math.min(10_101, Math.floor(input.limit))));
34
+ ORDER BY workspace_sync_journal.sequence ASC LIMIT ?`).all(input.tenantId, input.workspaceId, sequence(input.afterSequence), sequence(input.throughSequence), Math.max(1, Math.min(10_101, Math.floor(input.limit))));
35
35
  return rows.map((row) => ({
36
36
  sequence: sequence(row.sequence), contractVersion: Number(row.contract_version), clientId: String(row.client_id || ''),
37
37
  operationId: String(row.operation_id || ''), domain: String(row.domain || ''),
@@ -0,0 +1,16 @@
1
+ import type { DatabaseAdapter } from '../../storage/databaseAdapter.js';
2
+ export declare const WORKSPACE_SYNC_OPERATION_RETENTION_DAYS = 90;
3
+ export declare const WORKSPACE_SYNC_OPERATION_RETENTION_INTERVAL_MS: number;
4
+ export declare const WORKSPACE_SYNC_OPERATION_RETENTION_BATCH_SIZE = 100;
5
+ export declare const WORKSPACE_SYNC_OPERATION_RETENTION_WORKSPACE_LIMIT = 100;
6
+ export interface WorkspaceSyncOperationRetentionResult {
7
+ deletedOutbox: number;
8
+ deletedResults: number;
9
+ remainingEligible: number;
10
+ workspacesProcessed: number;
11
+ }
12
+ export declare function pruneRetainedWorkspaceSyncOperations(input: {
13
+ db: DatabaseAdapter;
14
+ tenantId: string;
15
+ now?: Date;
16
+ }): WorkspaceSyncOperationRetentionResult;
@@ -0,0 +1,83 @@
1
+ import { WorkspaceSyncDurabilityStore } from './syncDurabilityStore.js';
2
+ export const WORKSPACE_SYNC_OPERATION_RETENTION_DAYS = 90;
3
+ export const WORKSPACE_SYNC_OPERATION_RETENTION_INTERVAL_MS = 24 * 60 * 60_000;
4
+ export const WORKSPACE_SYNC_OPERATION_RETENTION_BATCH_SIZE = 100;
5
+ export const WORKSPACE_SYNC_OPERATION_RETENTION_WORKSPACE_LIMIT = 100;
6
+ export function pruneRetainedWorkspaceSyncOperations(input) {
7
+ const now = input.now || new Date();
8
+ const cutoff = new Date(now.getTime() - WORKSPACE_SYNC_OPERATION_RETENTION_DAYS * 24 * 60 * 60_000).toISOString();
9
+ const workspaceRows = input.db.prepare(`
10
+ SELECT eligible.workspace_id
11
+ FROM (
12
+ SELECT candidate.workspace_id, candidate.updated_at AS terminal_at
13
+ FROM workspace_sync_outbox AS candidate
14
+ WHERE candidate.tenant_id = ?
15
+ AND candidate.status IN ('accepted', 'superseded')
16
+ AND candidate.updated_at < ?
17
+ AND NOT EXISTS (
18
+ SELECT 1
19
+ FROM workspace_sync_outbox AS replay
20
+ WHERE replay.tenant_id = candidate.tenant_id
21
+ AND replay.workspace_id = candidate.workspace_id
22
+ AND replay.replay_of_client_id = candidate.client_id
23
+ AND replay.replay_of_operation_id = candidate.operation_id
24
+ )
25
+ UNION ALL
26
+ SELECT workspace_id, updated_at AS terminal_at
27
+ FROM workspace_sync_operation_results
28
+ WHERE tenant_id = ? AND status = 'committed' AND updated_at < ?
29
+ ) AS eligible
30
+ GROUP BY eligible.workspace_id
31
+ ORDER BY MIN(eligible.terminal_at), eligible.workspace_id
32
+ LIMIT ?
33
+ `).all(input.tenantId, cutoff, input.tenantId, cutoff, WORKSPACE_SYNC_OPERATION_RETENTION_WORKSPACE_LIMIT);
34
+ const store = new WorkspaceSyncDurabilityStore(input.db);
35
+ let deletedOutbox = 0;
36
+ let deletedResults = 0;
37
+ for (const row of workspaceRows) {
38
+ const workspaceId = String(row.workspace_id || '').trim();
39
+ if (!workspaceId)
40
+ continue;
41
+ const outboxResult = store.pruneTerminalOutboxOperations({
42
+ tenantId: input.tenantId,
43
+ workspaceId,
44
+ terminalBefore: cutoff,
45
+ limit: WORKSPACE_SYNC_OPERATION_RETENTION_BATCH_SIZE,
46
+ });
47
+ deletedOutbox += outboxResult.deleted;
48
+ const result = store.pruneCommittedOperationResults({
49
+ tenantId: input.tenantId,
50
+ workspaceId,
51
+ terminalBefore: cutoff,
52
+ limit: WORKSPACE_SYNC_OPERATION_RETENTION_BATCH_SIZE,
53
+ });
54
+ deletedResults += result.deleted;
55
+ }
56
+ const remaining = input.db.prepare(`
57
+ SELECT (
58
+ SELECT COUNT(*)
59
+ FROM workspace_sync_outbox AS candidate
60
+ WHERE candidate.tenant_id = ?
61
+ AND candidate.status IN ('accepted', 'superseded')
62
+ AND candidate.updated_at < ?
63
+ AND NOT EXISTS (
64
+ SELECT 1
65
+ FROM workspace_sync_outbox AS replay
66
+ WHERE replay.tenant_id = candidate.tenant_id
67
+ AND replay.workspace_id = candidate.workspace_id
68
+ AND replay.replay_of_client_id = candidate.client_id
69
+ AND replay.replay_of_operation_id = candidate.operation_id
70
+ )
71
+ ) + (
72
+ SELECT COUNT(*)
73
+ FROM workspace_sync_operation_results
74
+ WHERE tenant_id = ? AND status = 'committed' AND updated_at < ?
75
+ ) AS count
76
+ `).get(input.tenantId, cutoff, input.tenantId, cutoff);
77
+ return {
78
+ deletedOutbox,
79
+ deletedResults,
80
+ remainingEligible: Number(remaining?.count || 0),
81
+ workspacesProcessed: workspaceRows.length,
82
+ };
83
+ }
@@ -46,6 +46,7 @@ export type WorkspaceSyncV3CloudOperationContext = {
46
46
  /** @deprecated Prefer resolveOriginActorRef; retained for create callers. */
47
47
  resolveTaskCreateActorRef?: (originActor: NonNullable<WorkspaceSyncV3TaskCreateEnvelope['operation']['payload']['originActor']>) => string;
48
48
  onPostCommitError?: (error: unknown) => void;
49
+ includeWorkflowRuntimeJournal?: boolean;
49
50
  };
50
51
  export type WorkspaceSyncV3CloudOperationHandler = {
51
52
  key: string;
@@ -197,6 +197,7 @@ export function createWorkspaceSyncV3CloudOperationHandlers() {
197
197
  taskId: operation.entityId,
198
198
  payload,
199
199
  expectedDetailRevision,
200
+ includeWorkflowRuntimeJournal: context.includeWorkflowRuntimeJournal,
200
201
  assertPrecondition: expectedDetailRevision && context.core.assertTaskDetailRevisionForUpdate
201
202
  ? () => context.core.assertTaskDetailRevisionForUpdate(operation.entityId, expectedDetailRevision, context.workspaceId)
202
203
  : undefined,
@@ -237,10 +238,16 @@ export function createWorkspaceSyncV3CloudOperationHandlers() {
237
238
  supports: (envelope) => envelope.operation.domain === 'task-checklist' && envelope.operation.mutationKind === 'replace',
238
239
  apply: (envelope, context) => {
239
240
  const operation = envelope.operation;
241
+ const { originActor, expectedDetailRevision, itemUpdateIntent, items } = operation.payload;
240
242
  return runDurableTaskChecklistReplace({
241
- ...withDeferredOriginActor(context, operation.payload.originActor),
243
+ ...withDeferredOriginActor(context, originActor),
242
244
  taskId: operation.entityId,
243
- items: operation.payload.items,
245
+ items,
246
+ expectedDetailRevision,
247
+ itemUpdateIntent,
248
+ assertPrecondition: expectedDetailRevision && context.core.assertTaskDetailRevisionForUpdate
249
+ ? () => context.core.assertTaskDetailRevisionForUpdate(operation.entityId, expectedDetailRevision, context.workspaceId)
250
+ : undefined,
244
251
  baseEntityRevision: operation.baseEntityRevision,
245
252
  baseLifecycleRevision: operation.baseLifecycleRevision,
246
253
  });
@@ -13,7 +13,7 @@ import { enqueueLocalTaskCommentReconciliation } from './localTaskCommentOutboxS
13
13
  import { buildWorkspaceSyncV3TaskCommentReconcileProvenance, indexWorkspaceSyncV3TaskCommentProvenanceEvidence, } from './taskCommentReconcileProvenance.js';
14
14
  import { serializeTaskRootForSync, } from './workspaceSyncV3TaskRootProjection.js';
15
15
  import { prepareWorkspaceSyncV3WorkflowRuntimeApply } from './workspaceSyncV3WorkflowRuntimeApply.js';
16
- import { serializeWorkflowExecutionEventSyncPayload, serializeWorkflowExecutionRootSyncPayload, serializeWorkflowPublishedDefinitionSyncPayload, } from './workflowRuntimeSync.js';
16
+ import { serializeWorkflowExecutionEventSyncPayload, serializeWorkflowExecutionRootSyncPayload, serializeWorkflowPublishedDefinitionSyncPayload, validateWorkflowExecutionEventSyncPayload, } from './workflowRuntimeSync.js';
17
17
  import { serializeWorkstreamTaskOrderForSync } from './workstreamTaskOrderSync.js';
18
18
  import { validateWorkspaceSyncV3WorkstreamTaskOrderFeedEntry } from './workspaceSyncV3WorkstreamTaskOrderProjection.js';
19
19
  function combinedRepairBaselineMarker(page) {
@@ -198,6 +198,9 @@ function applyEntries(input) {
198
198
  store: new WorkflowStore(input.core.getDatabaseAdapter(), input.tenantId),
199
199
  workspaceId: input.workspaceId,
200
200
  entries: input.entries,
201
+ replaceAuthoritativeHistoryExecutionIds: input.allowAuthoritativeRevisionReset
202
+ ? input.authoritativeWorkflowRecoveryExecutionIds
203
+ : undefined,
201
204
  });
202
205
  return store.runWorkspaceDomainCoexistenceTransaction({
203
206
  tenantId: input.tenantId,
@@ -1011,7 +1014,7 @@ export function applyWorkspaceSyncV3CombinedRepairPage(input) {
1011
1014
  : [];
1012
1015
  const selectRecoveryEntries = (entries) => {
1013
1016
  const byTarget = new Map(entries.map((entry) => [`${entry.domain}\0${entry.entityId}`, entry]));
1014
- return recoveryTargets.map((target) => {
1017
+ const selected = recoveryTargets.map((target) => {
1015
1018
  const entry = byTarget.get(`${target.domain}\0${target.entityId}`);
1016
1019
  if (!entry) {
1017
1020
  if (!target.required)
@@ -1023,12 +1026,28 @@ export function applyWorkspaceSyncV3CombinedRepairPage(input) {
1023
1026
  || (target.domain === 'task-attachment-links'
1024
1027
  && (entry.projection === 'task-attachment-links/full-v1'
1025
1028
  || entry.projection === 'task-attachment-links/full-v2'))
1026
- || (target.domain === 'entity-event' && entry.projection === 'entity-event/full-v1'));
1029
+ || (target.domain === 'entity-event' && entry.projection === 'entity-event/full-v1')
1030
+ || (target.domain === 'workflow-execution'
1031
+ && entry.projection === 'workflow-execution/root-v1'));
1027
1032
  if (!supportedTarget) {
1028
1033
  throw new Error('Targeted workspace sync recovery does not support this projection.');
1029
1034
  }
1030
1035
  return entry;
1031
1036
  }).filter((entry) => entry !== null);
1037
+ const workflowExecutionIds = new Set(selected
1038
+ .filter((entry) => entry.projection === 'workflow-execution/root-v1')
1039
+ .map((entry) => entry.entityId));
1040
+ if (workflowExecutionIds.size > 0) {
1041
+ for (const entry of entries) {
1042
+ if (entry.projection !== 'workflow-execution-event/full-v1')
1043
+ continue;
1044
+ const payload = validateWorkflowExecutionEventSyncPayload(entry.payload);
1045
+ if (!workflowExecutionIds.has(payload.event.workflowExecutionId))
1046
+ continue;
1047
+ selected.push(entry);
1048
+ }
1049
+ }
1050
+ return selected;
1032
1051
  };
1033
1052
  const projections = coveredProjections(input.page);
1034
1053
  let notices = notifications();
@@ -1056,6 +1075,9 @@ export function applyWorkspaceSyncV3CombinedRepairPage(input) {
1056
1075
  authoritativeEntityEventRecoveryIds: new Set(recoveryTargets
1057
1076
  .filter((target) => target.domain === 'entity-event')
1058
1077
  .map((target) => target.entityId)),
1078
+ authoritativeWorkflowRecoveryExecutionIds: new Set(recoveryTargets
1079
+ .filter((target) => target.domain === 'workflow-execution')
1080
+ .map((target) => target.entityId)),
1059
1081
  } : {}),
1060
1082
  });
1061
1083
  },
@@ -6,6 +6,7 @@ export declare function prepareWorkspaceSyncV3CombinedRepairSnapshot(input: {
6
6
  now?: string;
7
7
  nestedCoverage?: boolean;
8
8
  workflowCoverage?: boolean;
9
+ workflowTaskCoverCoverage?: boolean;
9
10
  planningOrderCoverage?: boolean;
10
11
  taskCoverCoverage?: boolean;
11
12
  coveredLegacyWritesFenced?: boolean;
@@ -42,6 +43,12 @@ export declare function prepareWorkspaceSyncV3TaskCoverRepairSnapshot(input: {
42
43
  now?: string;
43
44
  coveredLegacyWritesFenced?: boolean;
44
45
  }): ReturnType<typeof prepareWorkspaceSyncV3CombinedRepairSnapshot>;
46
+ export declare function prepareWorkspaceSyncV3WorkflowTaskCoverRepairSnapshot(input: {
47
+ core: TaskforceCore;
48
+ workspaceId: string;
49
+ now?: string;
50
+ coveredLegacyWritesFenced?: boolean;
51
+ }): ReturnType<typeof prepareWorkspaceSyncV3CombinedRepairSnapshot>;
45
52
  export declare function ensureWorkspaceSyncV3CombinedRepairBaselines(input: {
46
53
  core: TaskforceCore;
47
54
  workspaceId: string;
@@ -3,12 +3,13 @@ import { serializeInitiativeForSync, serializeWorkstreamForSync } from '../plann
3
3
  import { serializeTaskForSync } from '../taskSyncPayload.js';
4
4
  import { canonicalWorkspaceSyncJson } from './canonicalWorkspaceSyncJson.js';
5
5
  import { WORKSPACE_SYNC_COMBINED_PROJECTION, fingerprintWorkspaceSyncPayload, WORKSPACE_SYNC_CONTRACT_VERSION, WorkspaceSyncRevisionConflictError, } from './syncDurabilityStore.js';
6
- import { buildWorkspaceSyncV3CombinedRepairSnapshot, buildWorkspaceSyncV3CombinedRepairSnapshotFromLockedCandidates, buildWorkspaceSyncV3NestedRepairSnapshot, buildWorkspaceSyncV3PlanningOrderRepairSnapshot, buildWorkspaceSyncV3TaskCoverRepairSnapshot, buildWorkspaceSyncV3WorkflowRepairSnapshot, listWorkspaceSyncV3CombinedRepairCandidates, listWorkspaceSyncV3NestedRepairCandidates, listWorkspaceSyncV3PlanningOrderRepairCandidates, listWorkspaceSyncV3TaskCoverRepairCandidates, listWorkspaceSyncV3WorkflowRepairCandidates, } from './workspaceSyncV3CombinedRepairSnapshot.js';
6
+ import { buildWorkspaceSyncV3CombinedRepairSnapshot, buildWorkspaceSyncV3CombinedRepairSnapshotFromLockedCandidates, buildWorkspaceSyncV3NestedRepairSnapshot, buildWorkspaceSyncV3PlanningOrderRepairSnapshot, buildWorkspaceSyncV3TaskCoverRepairSnapshot, buildWorkspaceSyncV3WorkflowRepairSnapshot, buildWorkspaceSyncV3WorkflowTaskCoverRepairSnapshot, listWorkspaceSyncV3CombinedRepairCandidates, listWorkspaceSyncV3NestedRepairCandidates, listWorkspaceSyncV3PlanningOrderRepairCandidates, listWorkspaceSyncV3TaskCoverRepairCandidates, listWorkspaceSyncV3WorkflowRepairCandidates, listWorkspaceSyncV3WorkflowTaskCoverRepairCandidates, } from './workspaceSyncV3CombinedRepairSnapshot.js';
7
7
  import { WORKSPACE_SYNC_V3_COMBINED_COVERAGE_PROFILE } from './workspaceSyncV3CombinedCoverage.js';
8
8
  import { WORKSPACE_SYNC_V3_NESTED_COVERAGE_PROFILE } from './workspaceSyncV3NestedCoverage.js';
9
9
  import { WORKSPACE_SYNC_V3_WORKFLOW_COVERAGE_PROFILE } from './workspaceSyncV3WorkflowCoverage.js';
10
10
  import { WORKSPACE_SYNC_V3_PLANNING_ORDER_COVERAGE_PROFILE } from './workspaceSyncV3PlanningOrderCoverage.js';
11
11
  import { WORKSPACE_SYNC_V3_TASK_COVER_COVERAGE_PROFILE } from './workspaceSyncV3TaskCoverCoverage.js';
12
+ import { WORKSPACE_SYNC_V3_WORKFLOW_TASK_COVER_COVERAGE_PROFILE } from './workspaceSyncV3WorkflowTaskCoverCoverage.js';
12
13
  import { serializeWorkspaceSyncV3TaskAttachmentLinksPayload, serializeWorkspaceSyncV3TaskCommentsPayload, } from './workspaceSyncV3NestedTaskCodecs.js';
13
14
  import { projectWorkspaceSyncV3NestedTaskJournalRow } from './workspaceSyncV3NestedTaskProjection.js';
14
15
  import { serializeTaskRelationshipForSync } from './workspaceSyncV3TaskRelationshipProjection.js';
@@ -261,15 +262,17 @@ export function prepareWorkspaceSyncV3CombinedRepairSnapshot(input) {
261
262
  `).get(tenantId, workspaceId, now);
262
263
  sequence(lock?.last_sequence);
263
264
  const lockCompletedAt = Date.now();
264
- const candidates = input.workflowCoverage
265
- ? listWorkspaceSyncV3WorkflowRepairCandidates(input.core, workspaceId)
266
- : input.taskCoverCoverage
267
- ? listWorkspaceSyncV3TaskCoverRepairCandidates(input.core, workspaceId)
268
- : input.planningOrderCoverage
269
- ? listWorkspaceSyncV3PlanningOrderRepairCandidates(input.core, workspaceId)
270
- : input.nestedCoverage
271
- ? listWorkspaceSyncV3NestedRepairCandidates(input.core, workspaceId)
272
- : listWorkspaceSyncV3CombinedRepairCandidates(input.core, workspaceId);
265
+ const candidates = input.workflowTaskCoverCoverage
266
+ ? listWorkspaceSyncV3WorkflowTaskCoverRepairCandidates(input.core, workspaceId)
267
+ : input.workflowCoverage
268
+ ? listWorkspaceSyncV3WorkflowRepairCandidates(input.core, workspaceId)
269
+ : input.taskCoverCoverage
270
+ ? listWorkspaceSyncV3TaskCoverRepairCandidates(input.core, workspaceId)
271
+ : input.planningOrderCoverage
272
+ ? listWorkspaceSyncV3PlanningOrderRepairCandidates(input.core, workspaceId)
273
+ : input.nestedCoverage
274
+ ? listWorkspaceSyncV3NestedRepairCandidates(input.core, workspaceId)
275
+ : listWorkspaceSyncV3CombinedRepairCandidates(input.core, workspaceId);
273
276
  const inventoryCompletedAt = Date.now();
274
277
  const keys = candidates.map((candidate) => `${candidate.domain}\0${candidate.entityId}`);
275
278
  if (new Set(keys).size !== keys.length)
@@ -551,15 +554,17 @@ export function prepareWorkspaceSyncV3CombinedRepairSnapshot(input) {
551
554
  throw repairConflict('legacy-nested-repair-raced', repair.candidate);
552
555
  }
553
556
  const baselineWritesCompletedAt = Date.now();
554
- const profile = input.workflowCoverage
555
- ? WORKSPACE_SYNC_V3_WORKFLOW_COVERAGE_PROFILE
556
- : input.taskCoverCoverage
557
- ? WORKSPACE_SYNC_V3_TASK_COVER_COVERAGE_PROFILE
558
- : input.planningOrderCoverage
559
- ? WORKSPACE_SYNC_V3_PLANNING_ORDER_COVERAGE_PROFILE
560
- : input.nestedCoverage
561
- ? WORKSPACE_SYNC_V3_NESTED_COVERAGE_PROFILE
562
- : WORKSPACE_SYNC_V3_COMBINED_COVERAGE_PROFILE;
557
+ const profile = input.workflowTaskCoverCoverage
558
+ ? WORKSPACE_SYNC_V3_WORKFLOW_TASK_COVER_COVERAGE_PROFILE
559
+ : input.workflowCoverage
560
+ ? WORKSPACE_SYNC_V3_WORKFLOW_COVERAGE_PROFILE
561
+ : input.taskCoverCoverage
562
+ ? WORKSPACE_SYNC_V3_TASK_COVER_COVERAGE_PROFILE
563
+ : input.planningOrderCoverage
564
+ ? WORKSPACE_SYNC_V3_PLANNING_ORDER_COVERAGE_PROFILE
565
+ : input.nestedCoverage
566
+ ? WORKSPACE_SYNC_V3_NESTED_COVERAGE_PROFILE
567
+ : WORKSPACE_SYNC_V3_COMBINED_COVERAGE_PROFILE;
563
568
  const activeOwner = db.prepare(`
564
569
  SELECT 1 AS active
565
570
  FROM workspace_sync_projection_state
@@ -580,28 +585,32 @@ export function prepareWorkspaceSyncV3CombinedRepairSnapshot(input) {
580
585
  inventory: candidates,
581
586
  nestedCoverage: input.nestedCoverage === true,
582
587
  workflowCoverage: input.workflowCoverage === true,
588
+ workflowTaskCoverCoverage: input.workflowTaskCoverCoverage === true,
583
589
  planningOrderCoverage: input.planningOrderCoverage === true,
584
590
  taskCoverCoverage: input.taskCoverCoverage === true,
585
591
  })
586
- : input.workflowCoverage
587
- ? buildWorkspaceSyncV3WorkflowRepairSnapshot({ core: input.core, workspaceId })
588
- : input.taskCoverCoverage
589
- ? buildWorkspaceSyncV3TaskCoverRepairSnapshot({ core: input.core, workspaceId })
590
- : input.planningOrderCoverage
591
- ? buildWorkspaceSyncV3PlanningOrderRepairSnapshot({ core: input.core, workspaceId })
592
- : input.nestedCoverage
593
- ? buildWorkspaceSyncV3NestedRepairSnapshot({ core: input.core, workspaceId })
594
- : buildWorkspaceSyncV3CombinedRepairSnapshot({ core: input.core, workspaceId });
592
+ : input.workflowTaskCoverCoverage
593
+ ? buildWorkspaceSyncV3WorkflowTaskCoverRepairSnapshot({ core: input.core, workspaceId })
594
+ : input.workflowCoverage
595
+ ? buildWorkspaceSyncV3WorkflowRepairSnapshot({ core: input.core, workspaceId })
596
+ : input.taskCoverCoverage
597
+ ? buildWorkspaceSyncV3TaskCoverRepairSnapshot({ core: input.core, workspaceId })
598
+ : input.planningOrderCoverage
599
+ ? buildWorkspaceSyncV3PlanningOrderRepairSnapshot({ core: input.core, workspaceId })
600
+ : input.nestedCoverage
601
+ ? buildWorkspaceSyncV3NestedRepairSnapshot({ core: input.core, workspaceId })
602
+ : buildWorkspaceSyncV3CombinedRepairSnapshot({ core: input.core, workspaceId });
595
603
  const snapshotCompletedAt = Date.now();
596
604
  if (snapshot.snapshotSequence !== highWatermark) {
597
605
  throw new Error('Combined repair baseline snapshot sequence changed while locked.');
598
606
  }
599
607
  console.info('[Taskforce Sync Repair Baseline Timing]', JSON.stringify({
600
608
  workspaceId,
601
- coverage: input.workflowCoverage ? 'workflow'
602
- : input.taskCoverCoverage ? 'task-cover'
603
- : input.planningOrderCoverage ? 'planning-order'
604
- : input.nestedCoverage ? 'nested' : 'combined',
609
+ coverage: input.workflowTaskCoverCoverage ? 'workflow-task-cover'
610
+ : input.workflowCoverage ? 'workflow'
611
+ : input.taskCoverCoverage ? 'task-cover'
612
+ : input.planningOrderCoverage ? 'planning-order'
613
+ : input.nestedCoverage ? 'nested' : 'combined',
605
614
  candidates: candidates.length,
606
615
  lock: lockCompletedAt - startedAt,
607
616
  inventory: inventoryCompletedAt - lockCompletedAt,
@@ -627,6 +636,9 @@ export function prepareWorkspaceSyncV3PlanningOrderRepairSnapshot(input) {
627
636
  export function prepareWorkspaceSyncV3TaskCoverRepairSnapshot(input) {
628
637
  return prepareWorkspaceSyncV3CombinedRepairSnapshot({ ...input, taskCoverCoverage: true });
629
638
  }
639
+ export function prepareWorkspaceSyncV3WorkflowTaskCoverRepairSnapshot(input) {
640
+ return prepareWorkspaceSyncV3CombinedRepairSnapshot({ ...input, workflowTaskCoverCoverage: true });
641
+ }
630
642
  export function ensureWorkspaceSyncV3CombinedRepairBaselines(input) {
631
643
  const { snapshot: _snapshot, ...result } = prepareWorkspaceSyncV3CombinedRepairSnapshot(input);
632
644
  return result;