@taskforcehq/taskforce 0.3.328 → 0.3.330

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 (485) hide show
  1. package/dist/Taskforce.module.css +523 -79
  2. package/dist/TaskforceCore.js +237 -230
  3. package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.js +1 -1
  4. package/dist/cli.js +34 -0
  5. package/dist/cliCloudTargetGuard.d.ts +5 -0
  6. package/dist/cliCloudTargetGuard.js +11 -0
  7. package/dist/components/features/AiProfilesModule.js +3 -5
  8. package/dist/components/features/AnnotatedAttachmentWorkspace.js +24 -8
  9. package/dist/components/features/TaskSettings.d.ts +12 -1
  10. package/dist/components/features/TaskSettings.js +217 -54
  11. package/dist/components/features/TaskforceAgentsModule.d.ts +1 -2
  12. package/dist/components/features/TaskforceAgentsModule.js +586 -116
  13. package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.d.ts +1 -1
  14. package/dist/components/features/agentConnections/AgentConnectionControl.d.ts +15 -0
  15. package/dist/components/features/agentConnections/AgentConnectionControl.js +125 -0
  16. package/dist/components/features/agentConnections/ModelConnectionsPanel.d.ts +18 -0
  17. package/dist/components/features/agentConnections/ModelConnectionsPanel.js +393 -0
  18. package/dist/components/features/agentConnections/modelConnectionsApi.d.ts +65 -0
  19. package/dist/components/features/agentConnections/modelConnectionsApi.js +129 -0
  20. package/dist/components/features/planning/PlanningModule.js +2 -5
  21. package/dist/components/features/planning/PlanningTaskOrderList.d.ts +1 -1
  22. package/dist/components/features/planning/PlanningTaskOrderList.js +17 -6
  23. package/dist/components/features/planning/planningTaskArrangement.d.ts +1 -0
  24. package/dist/components/features/planning/planningTaskArrangement.js +5 -5
  25. package/dist/components/features/taskforceAgentAssignments/AgentBehaviorAssignments.js +15 -24
  26. package/dist/components/features/taskforceAgentEditorModel.d.ts +2 -1
  27. package/dist/components/features/taskforceAgentEditorModel.js +5 -1
  28. package/dist/components/features/workflowManager/workflowManagerApi.d.ts +1 -1
  29. package/dist/components/features/workflowManager/workflowManagerApi.js +3 -0
  30. package/dist/components/task/TaskCard.d.ts +5 -0
  31. package/dist/components/task/TaskCard.js +65 -10
  32. package/dist/components/task/TaskImageReviews.js +14 -5
  33. package/dist/components/task/TaskKanban.d.ts +6 -1
  34. package/dist/components/task/TaskKanban.js +152 -6
  35. package/dist/components/task/TaskList.d.ts +5 -0
  36. package/dist/components/task/TaskList.js +3 -3
  37. package/dist/components/task/TaskWorkflowAssignmentField.js +68 -10
  38. package/dist/components/ui/PasswordInput.d.ts +6 -0
  39. package/dist/components/ui/PasswordInput.js +11 -0
  40. package/dist/components/ui/TopNoticeLayer.js +1 -1
  41. package/dist/components/views/AppShellHeader.js +32 -11
  42. package/dist/components/views/PlanComparisonPage.js +12 -0
  43. package/dist/components/views/StandaloneLayout.js +32 -55
  44. package/dist/components/views/WidgetView.js +3 -3
  45. package/dist/components/views/panels/PlanningDrawer.js +5 -12
  46. package/dist/components/views/standalone/modals/AccountSettingsModal.js +26 -17
  47. package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +4 -3
  48. package/dist/components/views/standalone/modals/SyncStatusModal.js +33 -38
  49. package/dist/config/envSchema.js +60 -1
  50. package/dist/config/localServiceRuntimeContract.d.ts +13 -0
  51. package/dist/config/localServiceRuntimeContract.js +135 -0
  52. package/dist/core/AiProfileService.js +46 -8
  53. package/dist/core/DeletedTaskLifecycleService.d.ts +1 -0
  54. package/dist/core/DeletedTaskLifecycleService.js +37 -6
  55. package/dist/core/McpTokenService.d.ts +23 -1
  56. package/dist/core/McpTokenService.js +93 -10
  57. package/dist/core/TaskAttachmentLinksDurableMutationService.d.ts +3 -2
  58. package/dist/core/TaskAttachmentLinksDurableMutationService.js +33 -9
  59. package/dist/core/TaskChecklistCommandService.d.ts +27 -0
  60. package/dist/core/TaskChecklistCommandService.js +83 -5
  61. package/dist/core/TaskLifecycleCommandService.d.ts +3 -1
  62. package/dist/core/TaskLifecycleCommandService.js +6 -2
  63. package/dist/core/Taskforce.d.ts +94 -2
  64. package/dist/core/Taskforce.js +760 -36
  65. package/dist/core/types.d.ts +14 -0
  66. package/dist/documentReviews/commandService.d.ts +2 -1
  67. package/dist/documentReviews/commandService.js +6 -3
  68. package/dist/hooks/sync/orchestratorShared.d.ts +1 -0
  69. package/dist/hooks/sync/orchestratorShared.js +2 -0
  70. package/dist/hooks/sync/useDurableLocalOutboxDrain.d.ts +1 -1
  71. package/dist/hooks/sync/useDurableTaskCreateMutation.js +1 -1
  72. package/dist/hooks/sync/useDurableTaskMetadataMutation.d.ts +1 -0
  73. package/dist/hooks/sync/useDurableTaskMetadataMutation.js +1 -0
  74. package/dist/hooks/sync/useDurableTaskStatusMutation.d.ts +1 -0
  75. package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.d.ts +3 -0
  76. package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.js +85 -9
  77. package/dist/hooks/sync/useSyncStatusControls.d.ts +4 -1
  78. package/dist/hooks/sync/useSyncStatusControls.js +47 -11
  79. package/dist/hooks/tasks/taskHttpMutation.js +1 -0
  80. package/dist/hooks/tasks/useCloudTaskSearch.d.ts +12 -0
  81. package/dist/hooks/tasks/useCloudTaskSearch.js +71 -0
  82. package/dist/hooks/tasks/useTaskDescriptionImageDraftRecovery.d.ts +16 -0
  83. package/dist/hooks/tasks/useTaskDescriptionImageDraftRecovery.js +197 -0
  84. package/dist/hooks/tasks/useTaskEditorNavigation.d.ts +16 -3
  85. package/dist/hooks/tasks/useTaskEditorNavigation.js +72 -13
  86. package/dist/hooks/tasks/useTaskFormActions.d.ts +6 -0
  87. package/dist/hooks/tasks/useTaskFormActions.js +65 -12
  88. package/dist/hooks/ui/useSettingsModel.d.ts +24 -2
  89. package/dist/hooks/ui/useSettingsModel.js +13 -2
  90. package/dist/hooks/ui/useSettingsPersistence.d.ts +12 -1
  91. package/dist/hooks/ui/useSettingsPersistence.js +74 -47
  92. package/dist/hooks/useFilterSort.d.ts +7 -3
  93. package/dist/hooks/useFilterSort.js +15 -5
  94. package/dist/hooks/useSyncOrchestrator.d.ts +3 -0
  95. package/dist/hooks/useSyncOrchestrator.js +111 -2
  96. package/dist/hooks/useTaskData.d.ts +40 -1
  97. package/dist/hooks/useTaskData.js +240 -9
  98. package/dist/hooks/useTaskMutations.d.ts +12 -2
  99. package/dist/hooks/useTaskMutations.js +266 -52
  100. package/dist/hooks/useTaskforce.d.ts +39 -9
  101. package/dist/hooks/useTaskforce.js +359 -40
  102. package/dist/hooks/useUiNotice.d.ts +4 -0
  103. package/dist/hooks/useUiNotice.js +4 -0
  104. package/dist/mcp/adminWorkspaceRegistrar.js +3 -3
  105. package/dist/mcp/clientRegistry.d.ts +2 -2
  106. package/dist/mcp/clientRegistry.js +1 -1
  107. package/dist/mcp/documentAssetRegistrar.js +53 -41
  108. package/dist/mcp/documentHelpers.d.ts +1 -0
  109. package/dist/mcp/documentHelpers.js +7 -3
  110. package/dist/mcp/durableTaskMutationRouter.d.ts +4 -1
  111. package/dist/mcp/durableTaskMutationRouter.js +10 -0
  112. package/dist/mcp/durableTaskRelationshipMutationRouter.js +4 -0
  113. package/dist/mcp/httpProtocolRouting.d.ts +10 -0
  114. package/dist/mcp/httpProtocolRouting.js +19 -0
  115. package/dist/mcp/localCliHealth.d.ts +2 -2
  116. package/dist/mcp/localCliHealth.js +2 -2
  117. package/dist/mcp/localServiceProxy.d.ts +1 -0
  118. package/dist/mcp/localServiceProxy.js +530 -68
  119. package/dist/mcp/planningAttachmentCommandAdapter.d.ts +3 -1
  120. package/dist/mcp/planningAttachmentCommandAdapter.js +20 -2
  121. package/dist/mcp/runtime.d.ts +54 -79
  122. package/dist/mcp/runtime.js +556 -139
  123. package/dist/mcp/taskPlanningRegistrar.js +64 -42
  124. package/dist/mcp/toolCallCompatibility.js +38 -1
  125. package/dist/mcp/toolCatalog.d.ts +1 -0
  126. package/dist/mcp/toolProfiles.d.ts +2 -0
  127. package/dist/mcp/toolProfiles.js +10 -0
  128. package/dist/mcp/toolRegistry.d.ts +1 -0
  129. package/dist/mcp/toolRegistry.js +1 -0
  130. package/dist/mcp/workflowExecutionRegistrar.js +4 -4
  131. package/dist/migrations/taskSchemaMigrations.d.ts +5 -0
  132. package/dist/migrations/taskSchemaMigrations.js +427 -0
  133. package/dist/runtime/appGateDefinitions.d.ts +30 -6
  134. package/dist/runtime/appGateDefinitions.js +6 -6
  135. package/dist/runtime/appGates.d.ts +13 -13
  136. package/dist/runtime/appGates.js +36 -13
  137. package/dist/runtime/nodeAppGates.d.ts +8 -0
  138. package/dist/runtime/nodeAppGates.js +27 -0
  139. package/dist/server/cloudCollectionRead.d.ts +1 -1
  140. package/dist/server/cloudCollectionRead.js +2 -2
  141. package/dist/server/index.d.ts +6 -0
  142. package/dist/server/index.js +123 -14
  143. package/dist/server/localDatabaseIdentity.js +4 -1
  144. package/dist/server/localServiceLease.d.ts +3 -0
  145. package/dist/server/localServiceLease.js +11 -2
  146. package/dist/server/localServiceSessions.d.ts +14 -17
  147. package/dist/server/localServiceSessions.js +308 -94
  148. package/dist/server/localWorkspaceSyncServerRuntime.js +12 -7
  149. package/dist/server/rateLimit.d.ts +1 -0
  150. package/dist/server/rateLimit.js +4 -0
  151. package/dist/server/realtimeSyncWs.js +36 -12
  152. package/dist/server/routes/admin.d.ts +4 -0
  153. package/dist/server/routes/admin.js +113 -3
  154. package/dist/server/routes/agentRoles.js +3 -2
  155. package/dist/server/routes/agentSkills.js +3 -2
  156. package/dist/server/routes/agents.d.ts +7 -0
  157. package/dist/server/routes/agents.js +394 -39
  158. package/dist/server/routes/annotatedAttachments.js +3 -2
  159. package/dist/server/routes/auth.js +3 -1
  160. package/dist/server/routes/billing.js +5 -1
  161. package/dist/server/routes/durableTaskHttpRouters.d.ts +11 -2
  162. package/dist/server/routes/executorPhaseAApprovals.d.ts +19 -0
  163. package/dist/server/routes/executorPhaseAApprovals.js +140 -0
  164. package/dist/server/routes/executorPhaseAIssuerRedemptions.d.ts +11 -0
  165. package/dist/server/routes/executorPhaseAIssuerRedemptions.js +24 -0
  166. package/dist/server/routes/githubReviewEvidence.d.ts +19 -0
  167. package/dist/server/routes/githubReviewEvidence.js +116 -0
  168. package/dist/server/routes/localService.d.ts +15 -4
  169. package/dist/server/routes/localService.js +138 -40
  170. package/dist/server/routes/modelConnections.d.ts +24 -0
  171. package/dist/server/routes/modelConnections.js +205 -0
  172. package/dist/server/routes/primitives.d.ts +2 -0
  173. package/dist/server/routes/shared.d.ts +19 -0
  174. package/dist/server/routes/shared.js +95 -19
  175. package/dist/server/routes/sync.js +1 -0
  176. package/dist/server/routes/syncAuxRoutes.js +9 -2
  177. package/dist/server/routes/syncPullApplyRoutes.js +23 -4
  178. package/dist/server/routes/syncPushRoutes.d.ts +1 -0
  179. package/dist/server/routes/syncPushRoutes.js +1 -0
  180. package/dist/server/routes/syncV3FeedRoutes.js +27 -16
  181. package/dist/server/routes/syncV3LocalCaptureRoutes.js +28 -2
  182. package/dist/server/routes/syncV3LocalFeedApplyRoutes.d.ts +1 -0
  183. package/dist/server/routes/syncV3LocalFeedApplyRoutes.js +26 -0
  184. package/dist/server/routes/syncV3OperationRoutes.js +45 -9
  185. package/dist/server/routes/tasks.js +124 -13
  186. package/dist/server/routes/workflows.js +9 -1
  187. package/dist/server/routes/workspaces.js +43 -1
  188. package/dist/server/routes.js +59 -0
  189. package/dist/server/workspaceDeletionAdmission.d.ts +23 -0
  190. package/dist/server/workspaceDeletionAdmission.js +50 -0
  191. package/dist/service/localServiceCli.js +16 -0
  192. package/dist/service/localServiceClientLifecycle.js +36 -10
  193. package/dist/services/codexAppServerModelGateway.d.ts +161 -0
  194. package/dist/services/codexAppServerModelGateway.js +663 -0
  195. package/dist/services/codexDeviceCodeLoginManager.d.ts +39 -0
  196. package/dist/services/codexDeviceCodeLoginManager.js +265 -0
  197. package/dist/services/codexModelProviderConnectionLifecycle.d.ts +8 -0
  198. package/dist/services/codexModelProviderConnectionLifecycle.js +73 -0
  199. package/dist/services/executorPhaseAApprovalRuntime.d.ts +14 -0
  200. package/dist/services/executorPhaseAApprovalRuntime.js +24 -0
  201. package/dist/services/executorPhaseAApprovalService.d.ts +40 -0
  202. package/dist/services/executorPhaseAApprovalService.js +609 -0
  203. package/dist/services/executorPhaseADriftEvaluator.d.ts +78 -0
  204. package/dist/services/executorPhaseADriftEvaluator.js +93 -0
  205. package/dist/services/executorPhaseAIssuerCore.d.ts +126 -0
  206. package/dist/services/executorPhaseAIssuerCore.js +295 -0
  207. package/dist/services/executorPhaseAIssuerRedemptionService.d.ts +34 -0
  208. package/dist/services/executorPhaseAIssuerRedemptionService.js +158 -0
  209. package/dist/services/githubReviewEvidenceRuntime.d.ts +14 -0
  210. package/dist/services/githubReviewEvidenceRuntime.js +30 -0
  211. package/dist/services/githubReviewEvidenceService.d.ts +93 -0
  212. package/dist/services/githubReviewEvidenceService.js +336 -0
  213. package/dist/services/modelGateway.d.ts +7 -0
  214. package/dist/services/modelProviderConnectionService.d.ts +71 -0
  215. package/dist/services/modelProviderConnectionService.js +279 -0
  216. package/dist/services/modelProviderCredentialHome.d.ts +32 -0
  217. package/dist/services/modelProviderCredentialHome.js +271 -0
  218. package/dist/services/ownerScopedModelConnectionGateway.d.ts +12 -0
  219. package/dist/services/ownerScopedModelConnectionGateway.js +30 -0
  220. package/dist/services/taskforceAgentConnectionBindingService.d.ts +66 -0
  221. package/dist/services/taskforceAgentConnectionBindingService.js +185 -0
  222. package/dist/services/taskforceAgentMcpBridge.d.ts +8 -2
  223. package/dist/services/taskforceAgentMcpBridge.js +30 -27
  224. package/dist/shared/adminEdgeProxy.d.ts +5 -0
  225. package/dist/shared/adminEdgeProxy.js +94 -0
  226. package/dist/shared/adminProxySessionCookies.d.ts +16 -0
  227. package/dist/shared/adminProxySessionCookies.js +86 -0
  228. package/dist/shared/aiProfileColors.d.ts +31 -1
  229. package/dist/shared/aiProfileColors.js +14 -6
  230. package/dist/shared/executorPhaseAApprovalGoldenVector.json +269 -0
  231. package/dist/shared/executorPhaseAApprovalReceipt.d.ts +112 -0
  232. package/dist/shared/executorPhaseAApprovalReceipt.js +58 -0
  233. package/dist/shared/executorPhaseAApprovalTrustPolicy.json +10 -0
  234. package/dist/shared/executorPhaseADriftContracts.d.ts +37 -0
  235. package/dist/shared/executorPhaseADriftContracts.js +63 -0
  236. package/dist/shared/executorPhaseAIssuerContracts.d.ts +75 -0
  237. package/dist/shared/executorPhaseAIssuerContracts.js +90 -0
  238. package/dist/shared/executorPhaseARunAuthorization.d.ts +120 -0
  239. package/dist/shared/executorPhaseARunAuthorization.js +232 -0
  240. package/dist/shared/executorPhaseASchemaValidation.d.ts +7 -0
  241. package/dist/shared/executorPhaseASchemaValidation.js +53 -0
  242. package/dist/shared/executorPhaseASchemas/approval-receipt.schema.json +106 -0
  243. package/dist/shared/executorPhaseASchemas/drift-attestation.schema.json +54 -0
  244. package/dist/shared/executorPhaseASchemas/drift-request.schema.json +47 -0
  245. package/dist/shared/executorPhaseASchemas/foundation-manifest.schema.json +29 -0
  246. package/dist/shared/executorPhaseASchemas/issuer-audit-record.schema.json +24 -0
  247. package/dist/shared/executorPhaseASchemas/issuer-proof.schema.json +43 -0
  248. package/dist/shared/executorPhaseASchemas/issuer-redemption-request.schema.json +18 -0
  249. package/dist/shared/executorPhaseASchemas/issuer-redemption-response.schema.json +39 -0
  250. package/dist/shared/executorPhaseASchemas/logical-envelope.schema.json +149 -0
  251. package/dist/shared/executorPhaseASchemas/preflight-report.schema.json +216 -0
  252. package/dist/shared/executorPhaseASchemas/run-capability.schema.json +111 -0
  253. package/dist/shared/executorPhaseASchemas/sender-proof.schema.json +37 -0
  254. package/dist/shared/executorPhaseASchemas/workload-grant.schema.json +68 -0
  255. package/dist/shared/executorPhaseASchemas/workload-jwt-claims.schema.json +67 -0
  256. package/dist/shared/executorPhaseATiming.d.ts +1 -0
  257. package/dist/shared/executorPhaseATiming.js +1 -0
  258. package/dist/shared/planningIdentity.js +1 -1
  259. package/dist/shared/productLogoKeys.d.ts +2 -0
  260. package/dist/shared/productLogoKeys.js +18 -0
  261. package/dist/shared/taskforceAgentDefinition.d.ts +0 -1
  262. package/dist/shared/taskforceAgentDefinition.js +6 -3
  263. package/dist/shared/taskforceAgentModels.d.ts +1 -0
  264. package/dist/shared/taskforceAgentModels.js +36 -3
  265. package/dist/shared/userFeatureGrants.d.ts +4 -0
  266. package/dist/shared/userFeatureGrants.js +7 -0
  267. package/dist/storage/executorPhaseAApprovalReceiptStore.d.ts +37 -0
  268. package/dist/storage/executorPhaseAApprovalReceiptStore.js +81 -0
  269. package/dist/storage/executorPhaseARunAuthorizationStore.d.ts +103 -0
  270. package/dist/storage/executorPhaseARunAuthorizationStore.js +492 -0
  271. package/dist/storage/githubReviewEvidenceInstallationStore.d.ts +26 -0
  272. package/dist/storage/githubReviewEvidenceInstallationStore.js +89 -0
  273. package/dist/storage/modelProviderConnectionStore.d.ts +99 -0
  274. package/dist/storage/modelProviderConnectionStore.js +446 -0
  275. package/dist/storage/postgresAdapter.d.ts +24 -3
  276. package/dist/storage/postgresAdapter.js +117 -14
  277. package/dist/storage/postgresWorker.js +22 -5
  278. package/dist/storage/postgresWorkerProtocol.d.ts +30 -0
  279. package/dist/storage/postgresWorkerProtocol.js +30 -0
  280. package/dist/storage/taskforceAgentConnectionBindingStore.d.ts +31 -0
  281. package/dist/storage/taskforceAgentConnectionBindingStore.js +84 -0
  282. package/dist/sync/cloudSyncApi.d.ts +4 -1
  283. package/dist/sync/cloudSyncApi.js +7 -2
  284. package/dist/sync/contentSyncState.d.ts +1 -1
  285. package/dist/sync/coordinator/localSyncExecutionPermitStore.d.ts +1 -0
  286. package/dist/sync/coordinator/localSyncExecutionPermitStore.js +67 -30
  287. package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.d.ts +10 -0
  288. package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.js +29 -0
  289. package/dist/sync/coordinator/localWorkspaceSyncRunner.js +6 -2
  290. package/dist/sync/coordinator/localWorkspaceSyncRunnerState.d.ts +15 -1
  291. package/dist/sync/coordinator/localWorkspaceSyncRunnerState.js +99 -2
  292. package/dist/sync/coordinator/workspaceSyncCredentialBroker.d.ts +1 -0
  293. package/dist/sync/coordinator/workspaceSyncCredentialBroker.js +33 -4
  294. package/dist/sync/engine/workspaceSyncContentLifecycleAdapter.d.ts +2 -1
  295. package/dist/sync/engine/workspaceSyncContentVersionStore.d.ts +38 -0
  296. package/dist/sync/engine/workspaceSyncContentVersionStore.js +50 -1
  297. package/dist/sync/engine/workspaceSyncEngineBrowserGatewayRemoteServices.js +20 -2
  298. package/dist/sync/engine/workspaceSyncEngineLifecyclePolicy.js +6 -6
  299. package/dist/sync/engine/workspaceSyncEngineLocalServices.d.ts +4 -0
  300. package/dist/sync/engine/workspaceSyncEngineLocalServices.js +11 -0
  301. package/dist/sync/engine/workspaceSyncEnginePushCompletion.d.ts +14 -0
  302. package/dist/sync/engine/workspaceSyncEnginePushCompletion.js +84 -0
  303. package/dist/sync/engine/workspaceSyncEngineRecovery.js +1 -0
  304. package/dist/sync/engine/workspaceSyncEngineRemoteServices.d.ts +11 -0
  305. package/dist/sync/engine/workspaceSyncEngineRemoteServices.js +2 -1
  306. package/dist/sync/engine/workspaceSyncEngineRuntime.d.ts +1 -0
  307. package/dist/sync/engine/workspaceSyncEngineRuntime.js +1 -0
  308. package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.js +31 -4
  309. package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.d.ts +3 -1
  310. package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +134 -43
  311. package/dist/sync/engine/workspaceSyncEngineServerSnapshotReader.js +6 -0
  312. package/dist/sync/engine/workspaceSyncEngineTransfers.d.ts +1 -1
  313. package/dist/sync/engine/workspaceSyncEngineTransfers.js +11 -4
  314. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.d.ts +1 -0
  315. package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.js +29 -0
  316. package/dist/sync/syncApplyHandlers.d.ts +2 -0
  317. package/dist/sync/syncApplyHandlers.js +10 -1
  318. package/dist/sync/syncService.d.ts +17 -0
  319. package/dist/sync/syncService.js +87 -19
  320. package/dist/sync/taskforceAgentSyncAuthorization.d.ts +16 -0
  321. package/dist/sync/taskforceAgentSyncAuthorization.js +20 -0
  322. package/dist/sync/v3/combinedFeedCapability.js +8 -0
  323. package/dist/sync/v3/durableInitiativeMutationRouter.js +18 -10
  324. package/dist/sync/v3/durableOperationReplay.d.ts +14 -0
  325. package/dist/sync/v3/durableOperationReplay.js +18 -0
  326. package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.d.ts +2 -0
  327. package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +14 -1
  328. package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +4 -1
  329. package/dist/sync/v3/durableTaskChecklistMutationRouter.js +62 -15
  330. package/dist/sync/v3/durableTaskCommentMutationRouter.js +3 -0
  331. package/dist/sync/v3/durableTaskHttpBulkMutationRouter.d.ts +1 -0
  332. package/dist/sync/v3/durableTaskHttpBulkMutationRouter.js +30 -8
  333. package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +5 -3
  334. package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +37 -2
  335. package/dist/sync/v3/durableTaxonomyMutationRouter.js +5 -0
  336. package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.d.ts +11 -0
  337. package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.js +39 -10
  338. package/dist/sync/v3/durableWorkstreamMutationRouter.js +18 -10
  339. package/dist/sync/v3/durableWorkstreamTaskOrderMutationRouter.js +16 -5
  340. package/dist/sync/v3/localOutboxDispatchRuntime.js +2 -2
  341. package/dist/sync/v3/localTaskAttachmentLinksOutboxService.d.ts +2 -0
  342. package/dist/sync/v3/localTaskAttachmentLinksOutboxService.js +47 -7
  343. package/dist/sync/v3/localTaskChecklistOutboxHandler.js +16 -2
  344. package/dist/sync/v3/localTaskChecklistOutboxService.d.ts +4 -0
  345. package/dist/sync/v3/localTaskChecklistOutboxService.js +14 -1
  346. package/dist/sync/v3/localTaskCreateOutboxService.js +15 -6
  347. package/dist/sync/v3/localTaskMetadataClient.d.ts +1 -0
  348. package/dist/sync/v3/localTaskMetadataClient.js +1 -0
  349. package/dist/sync/v3/localTaskMetadataOutboxHandler.js +5 -1
  350. package/dist/sync/v3/localTaskMetadataOutboxService.d.ts +2 -0
  351. package/dist/sync/v3/localTaskMetadataOutboxService.js +7 -0
  352. package/dist/sync/v3/localTaskRestoreOutboxService.js +14 -6
  353. package/dist/sync/v3/localTaskStatusClient.d.ts +1 -0
  354. package/dist/sync/v3/localTaskStatusClient.js +6 -1
  355. package/dist/sync/v3/localTaskStatusOutboxService.d.ts +10 -0
  356. package/dist/sync/v3/localTaskStatusOutboxService.js +272 -24
  357. package/dist/sync/v3/syncDurabilityStore.d.ts +41 -0
  358. package/dist/sync/v3/syncDurabilityStore.js +199 -13
  359. package/dist/sync/v3/taskAttachmentLinksMutationService.d.ts +6 -4
  360. package/dist/sync/v3/taskAttachmentLinksMutationService.js +19 -10
  361. package/dist/sync/v3/taskChecklistMutationService.d.ts +15 -2
  362. package/dist/sync/v3/taskChecklistMutationService.js +48 -1
  363. package/dist/sync/v3/taskCreateMutationService.d.ts +2 -2
  364. package/dist/sync/v3/taskCreateMutationService.js +7 -4
  365. package/dist/sync/v3/taskMetadataMutationService.d.ts +3 -0
  366. package/dist/sync/v3/taskMetadataMutationService.js +4 -0
  367. package/dist/sync/v3/taskRestoreMutationService.d.ts +2 -2
  368. package/dist/sync/v3/taskRestoreMutationService.js +7 -4
  369. package/dist/sync/v3/taskStatusMutationService.d.ts +31 -1
  370. package/dist/sync/v3/taskStatusMutationService.js +123 -3
  371. package/dist/sync/v3/workflowAssignmentSync.d.ts +6 -0
  372. package/dist/sync/v3/workflowAssignmentSync.js +30 -0
  373. package/dist/sync/v3/workspaceSyncJournalReader.js +1 -1
  374. package/dist/sync/v3/workspaceSyncOperationRetentionService.d.ts +16 -0
  375. package/dist/sync/v3/workspaceSyncOperationRetentionService.js +83 -0
  376. package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.d.ts +1 -1
  377. package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.js +13 -3
  378. package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.d.ts +11 -0
  379. package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.js +27 -10
  380. package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.d.ts +2 -1
  381. package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.js +52 -10
  382. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.d.ts +1 -0
  383. package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +18 -3
  384. package/dist/sync/v3/workspaceSyncV3CombinedFeedOrchestrator.js +8 -3
  385. package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.js +51 -10
  386. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +14 -0
  387. package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +49 -25
  388. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +13 -4
  389. package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +124 -57
  390. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +20 -0
  391. package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +106 -30
  392. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +4 -1
  393. package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +34 -0
  394. package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +12 -0
  395. package/dist/sync/v3/workspaceSyncV3FeedProfile.d.ts +1 -1
  396. package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.d.ts +1 -0
  397. package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.js +23 -10
  398. package/dist/sync/v3/workspaceSyncV3NestedTaskApply.d.ts +3 -0
  399. package/dist/sync/v3/workspaceSyncV3NestedTaskApply.js +64 -13
  400. package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.d.ts +9 -0
  401. package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.js +26 -0
  402. package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.d.ts +15 -5
  403. package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.js +50 -14
  404. package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.d.ts +2 -1
  405. package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.js +11 -3
  406. package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +5 -0
  407. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +7 -0
  408. package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +55 -9
  409. package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.d.ts +17 -0
  410. package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.js +64 -0
  411. package/dist/sync/v3/workspaceSyncV3TaskCommentAudit.js +9 -2
  412. package/dist/sync/v3/workspaceSyncV3TaskCoverCoverage.d.ts +7 -0
  413. package/dist/sync/v3/workspaceSyncV3TaskCoverCoverage.js +37 -0
  414. package/dist/sync/v3/workspaceSyncV3TaskCoverWireContract.d.ts +6 -0
  415. package/dist/sync/v3/workspaceSyncV3TaskCoverWireContract.js +9 -0
  416. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.d.ts +7 -0
  417. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.js +33 -0
  418. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.d.ts +7 -0
  419. package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.js +8 -0
  420. package/dist/sync/workspacePullFeed.js +2 -1
  421. package/dist/sync/workspaceRepair.d.ts +8 -2
  422. package/dist/sync/workspaceRepair.js +222 -6
  423. package/dist/sync/workspaceSyncModel.d.ts +21 -0
  424. package/dist/sync/workspaceSyncModel.js +35 -7
  425. package/dist/sync/workspaceSyncState.d.ts +1 -0
  426. package/dist/sync/workspaceSyncV2SnapshotBuilder.d.ts +6 -0
  427. package/dist/sync/workspaceSyncV2SnapshotBuilder.js +5 -0
  428. package/dist/types.d.ts +47 -1
  429. package/dist/types.js +6 -0
  430. package/dist/ui/assets/AiIdentityRosterCard-OcSz1PkK.js +1 -0
  431. package/dist/ui/assets/AiProfilesModule-ByhYW5Xi.js +1 -0
  432. package/dist/ui/assets/AnnotatedAttachmentWorkspace-BTM6nIg_.js +3 -0
  433. package/dist/ui/assets/AnnotatedAttachmentWorkspace-TzYu7pkG.css +1 -0
  434. package/dist/ui/assets/{AssetTraySortControl-Kf1pelSy.js → AssetTraySortControl-DabEG8L4.js} +1 -1
  435. package/dist/ui/assets/{ContextAttachmentManager-B8boOs6Q.js → ContextAttachmentManager-Coa8yVGM.js} +2 -2
  436. package/dist/ui/assets/{DocumentWorkspace-DXH4XUsB.js → DocumentWorkspace-BB0qhdix.js} +1 -1
  437. package/dist/ui/assets/{EntityActivityTimeline-BtSTq0ON.js → EntityActivityTimeline-CZ8x4UJE.js} +1 -1
  438. package/dist/ui/assets/PlanningModule-pRPjR7v5.js +1 -0
  439. package/dist/ui/assets/PlansPage-D86pZSSl.js +1 -0
  440. package/dist/ui/assets/TaskContextUpload-BVIkU9yT.js +1 -0
  441. package/dist/ui/assets/TaskSettings-Cv1mNhv_.js +12 -0
  442. package/dist/ui/assets/TaskforceAgentsModule-b-8R25cJ.css +1 -0
  443. package/dist/ui/assets/TaskforceAgentsModule-gmH-PD2q.js +24 -0
  444. package/dist/ui/assets/{WorkflowManagerModule-DWFspC-o.js → WorkflowManagerModule-DbfnHJ-f.js} +1 -1
  445. package/dist/ui/assets/index-BZ-hdZSk.css +1 -0
  446. package/dist/ui/assets/index-CTsDBaef.js +7 -0
  447. package/dist/ui/assets/{vendor-icons-BkFLXavV.js → vendor-icons-Bsq-mcEn.js} +1 -1
  448. package/dist/ui/branding/logos/letterhead_dark.png +0 -0
  449. package/dist/ui/branding/logos/letterhead_light.png +0 -0
  450. package/dist/ui/branding/logos/signature_dark.png +0 -0
  451. package/dist/ui/branding/logos/signature_light.png +0 -0
  452. package/dist/ui/index.html +3 -3
  453. package/dist/utils/aiProfileDefaultLogo.js +16 -48
  454. package/dist/utils/httpSetCookie.d.ts +1 -0
  455. package/dist/utils/httpSetCookie.js +4 -1
  456. package/dist/utils/localRuntimeUrl.d.ts +1 -0
  457. package/dist/utils/localRuntimeUrl.js +14 -0
  458. package/dist/utils/productLogoRegistry.d.ts +2 -0
  459. package/dist/utils/productLogoRegistry.js +36 -0
  460. package/dist/utils/syncStatusPresentation.d.ts +4 -0
  461. package/dist/utils/syncStatusPresentation.js +17 -0
  462. package/dist/utils/taskActivity.d.ts +3 -2
  463. package/dist/utils/taskActivity.js +19 -2
  464. package/dist/utils/taskEditorReconciliation.d.ts +40 -0
  465. package/dist/utils/taskEditorReconciliation.js +217 -0
  466. package/dist/utils/taskEvents.d.ts +2 -0
  467. package/dist/utils/taskNormalization.d.ts +1 -0
  468. package/dist/utils/taskNormalization.js +39 -0
  469. package/dist/utils/taskSearch.js +2 -2
  470. package/dist/utils/uiNotice.d.ts +4 -0
  471. package/dist/utils/workspaceSyncPresentation.d.ts +1 -1
  472. package/dist/utils/workspaceSyncPresentation.js +23 -17
  473. package/package.json +36 -6
  474. package/dist/ui/assets/AiIdentityRosterCard-MZs7lVED.js +0 -1
  475. package/dist/ui/assets/AiProfilesModule-C3i0LOxe.js +0 -1
  476. package/dist/ui/assets/AnnotatedAttachmentWorkspace-CBRZ8rca.css +0 -1
  477. package/dist/ui/assets/AnnotatedAttachmentWorkspace-DVZk5Tln.js +0 -3
  478. package/dist/ui/assets/PlanningModule-BPVyEa-f.js +0 -1
  479. package/dist/ui/assets/PlansPage-ChqgxALc.js +0 -1
  480. package/dist/ui/assets/TaskContextUpload-CB3ol0sN.js +0 -1
  481. package/dist/ui/assets/TaskSettings-g4ECKNOz.js +0 -12
  482. package/dist/ui/assets/TaskforceAgentsModule-BazdUwxZ.js +0 -21
  483. package/dist/ui/assets/TaskforceAgentsModule-D6IC0S7Q.css +0 -1
  484. package/dist/ui/assets/index-BUplSsv_.js +0 -7
  485. package/dist/ui/assets/index-gz2EXuoK.css +0 -1
@@ -4,6 +4,7 @@ import { resolveWorkspacePullRequestPlan, resolveWorkspacePullSuccessPlan } from
4
4
  import { runWorkspaceSyncV3InitiativeProjectionCycle } from '../v3/workspaceSyncV3FeedOrchestrator.js';
5
5
  import { runWorkspaceSyncV3CombinedProjectionCycle } from '../v3/workspaceSyncV3CombinedFeedOrchestrator.js';
6
6
  import { hydrateWorkspaceSyncV3AttachmentAsset } from '../v3/workspaceSyncV3AttachmentAssetHydration.js';
7
+ import { authoritativeV2ApplyFailureMessage, } from './workspaceSyncEngineLocalServices.js';
7
8
  import { WORKSPACE_SYNC_V3_APPLY_NOT_COMMITTED } from './workspaceSyncEngineRemoteServices.js';
8
9
  export function combinedAttachmentAssetHydrationId(input) {
9
10
  if (input.causeCode === 'TASK_ATTACHMENT_ASSET_NOT_READY' && input.causeAssetId) {
@@ -172,7 +173,7 @@ export function createWorkspaceSyncV3TransferBindings(input) {
172
173
  };
173
174
  }
174
175
  export function createWorkspaceTransferCoordinator({ cloudAuthConfigured, runtimeMode, initiativeFeedActivationEnabled, combinedFeedActivationEnabled, combinedFeedCoverage, workspaceCloudSyncEnabled, currentWorkspaceId, workspaceSyncPhase, isAuthenticated, checkAuthSession, resolveCloudAuthUrl, ensureCloudWorkspaceReadyForSync, ensureWorkspaceSyncReady, handleSyncAuthFailure, clearWorkspaceRetry, clearWorkspaceIssue, isWorkspaceRetryPending, isDurableRecoveryBlockingOrdinaryPush, isExecutionAuthorized = () => true, scheduleWorkspaceSyncRetry, persistWorkspaceSyncPatchSafely, persistWorkspaceSyncPatchBestEffort, persistWorkspaceSyncWatermarksSnapshotBestEffort, refreshWorkspaceAiProfilePushBaselineFromPersistence, reportSyncEvent, acquireWorkspaceSyncLease, releaseWorkspaceSyncLease, recordWorkspaceSyncCompletion, reportWorkspaceWindowContention, refreshWorkspaceSyncMarkdownDocumentsSnapshot, refreshWorkspaceSyncAiProfilesSnapshot, refreshWorkspaceSyncAssetsSnapshot, refreshWorkspaceSyncTaxonomySnapshot, refreshWorkspaceSyncPlanningEntitiesSnapshot, refreshWorkspaceSyncDocumentReviewSessionsSnapshot, refreshWorkspaceSyncAnnotatedAttachmentSessionsSnapshot, refreshWorkspaceSyncTaskforceAgentsSnapshot, refreshLocalWorkspaceTaskCollections, buildWorkspaceSyncPayload, buildWorkspaceSyncSignature, seedWorkspaceSnapshotPushBaseline, shouldSuppressAttachBootstrapPush, recordSuppressedEventIds, runtime, localServices, remoteServices, setWorkspaceSyncBusy, setUserGlobalSyncStatus, setUserGlobalSyncError, setWorkspaceLastErrorMessage, setWorkspaceLastErrorAt, setWorkspaceLastPullAt, setWorkspaceLastPushAt, setWorkspaceSyncPendingChanges, setTasks, setArchivedTasks, now, scheduleTask, logDebug = () => undefined, notifyAiProfilesMutated = () => undefined, notifyAgentsMutated = () => undefined, notifyAgentSkillsMutated = () => undefined }) {
175
- const { repairMode: workspaceRepairModeRef, forceFullAiProfilePush: workspaceForceFullAiProfilePushRef, pushInFlight: workspacePushInFlightRef, pullInFlight: workspacePullInFlightRef, pullAfterPushRequested: workspacePullAfterPushRequestedRef, pendingPushReplay: workspacePendingPushReplayRef, blockedPushSignature: workspaceBlockedPushSignatureRef, lastPushedSignature: workspaceLastPushedSignatureRef, pendingSignature: workspacePendingSignatureRef, lastPushedTaskIds: workspaceLastPushedTaskIdsRef, deletedTaskIds: workspaceDeletedTaskIdsRef, deletedTaskWatermarks: workspaceDeletedTaskWatermarksRef, pullCursor: workspacePullCursorRef, lastPushedWatermarks: workspaceLastPushedWatermarksRef, lastPushedTaskChangeKeys: workspaceLastPushedTaskChangeKeysRef, lastPushedTaskRelationshipChangeKeys: workspaceLastPushedTaskRelationshipChangeKeysRef, lastPushedTaxonomyChangeKey: workspaceLastPushedTaxonomyChangeKeyRef, lastPushedInitiativeIds: workspaceLastPushedInitiativeIdsRef, lastPushedInitiativeWatermarks: workspaceLastPushedInitiativeWatermarksRef, lastPushedWorkstreamIds: workspaceLastPushedWorkstreamIdsRef, lastPushedWorkstreamWatermarks: workspaceLastPushedWorkstreamWatermarksRef, lastPushedAiProfileIds: workspaceLastPushedAiProfileIdsRef, lastPushedAiProfileWatermarks: workspaceLastPushedAiProfileWatermarksRef, lastPushedAiProfileChangeKeys: workspaceLastPushedAiProfileChangeKeysRef, lastPushedDocumentPaths: workspaceLastPushedDocumentPathsRef, lastPushedDocumentWatermarks: workspaceLastPushedDocumentWatermarksRef, lastPushedAssetPaths: workspaceLastPushedAssetPathsRef, lastPushedAssetWatermarks: workspaceLastPushedAssetWatermarksRef, lastPushedDocumentReviewSessionIds: workspaceLastPushedDocumentReviewSessionIdsRef, lastPushedDocumentReviewSessionWatermarks: workspaceLastPushedDocumentReviewSessionWatermarksRef, lastPushedDocumentReviewCommentIds: workspaceLastPushedDocumentReviewCommentIdsRef, lastPushedDocumentReviewCommentWatermarks: workspaceLastPushedDocumentReviewCommentWatermarksRef, lastPushedAnnotatedAttachmentSessionIds: workspaceLastPushedAnnotatedAttachmentSessionIdsRef, lastPushedAnnotatedAttachmentSessionWatermarks: workspaceLastPushedAnnotatedAttachmentSessionWatermarksRef, lastPushedTaskforceAgentIds: workspaceLastPushedTaskforceAgentIdsRef, lastPushedTaskforceAgentWatermarks: workspaceLastPushedTaskforceAgentWatermarksRef, lastPushedTaskforceAgentSkillIds: workspaceLastPushedTaskforceAgentSkillIdsRef, lastPushedTaskforceAgentSkillWatermarks: workspaceLastPushedTaskforceAgentSkillWatermarksRef, lastPushedAgentConversationIds: workspaceLastPushedAgentConversationIdsRef, lastPushedAgentConversationWatermarks: workspaceLastPushedAgentConversationWatermarksRef, lastPushedTaskEventWatermarks: workspaceLastPushedTaskEventWatermarksRef, baselineResetReason: workspaceBaselineResetReasonRef, captureAttachBootstrapBaseline: workspaceCaptureAttachBootstrapBaselineRef, startupFullReconcileRan: workspaceStartupFullReconcileRanRef, startupFullReconcileRequested: workspaceStartupFullReconcileRequestedRef, fullReconcileInFlight: workspaceFullReconcileInFlightRef, bootstrapLastProgressAtMs: bootstrapLastProgressAtRef, realtimeSuppressedEventQueue: realtimeSuppressedEventQueueRef, } = runtime;
176
+ const { repairMode: workspaceRepairModeRef, forceFullAiProfilePush: workspaceForceFullAiProfilePushRef, pushInFlight: workspacePushInFlightRef, pullInFlight: workspacePullInFlightRef, pullAfterPushRequested: workspacePullAfterPushRequestedRef, pendingPushReplay: workspacePendingPushReplayRef, blockedPushSignature: workspaceBlockedPushSignatureRef, lastPushedSignature: workspaceLastPushedSignatureRef, pendingSignature: workspacePendingSignatureRef, lastPushedTaskIds: workspaceLastPushedTaskIdsRef, deletedTaskIds: workspaceDeletedTaskIdsRef, deletedTaskWatermarks: workspaceDeletedTaskWatermarksRef, pullCursor: workspacePullCursorRef, lastPushedWatermarks: workspaceLastPushedWatermarksRef, lastPushedTaskChangeKeys: workspaceLastPushedTaskChangeKeysRef, lastPushedTaskRelationshipChangeKeys: workspaceLastPushedTaskRelationshipChangeKeysRef, lastPushedTaxonomyChangeKey: workspaceLastPushedTaxonomyChangeKeyRef, lastPushedInitiativeIds: workspaceLastPushedInitiativeIdsRef, lastPushedInitiativeWatermarks: workspaceLastPushedInitiativeWatermarksRef, lastPushedWorkstreamIds: workspaceLastPushedWorkstreamIdsRef, lastPushedWorkstreamWatermarks: workspaceLastPushedWorkstreamWatermarksRef, lastPushedPlanningIdentityWatermarks: workspaceLastPushedPlanningIdentityWatermarksRef, lastPushedAiProfileIds: workspaceLastPushedAiProfileIdsRef, lastPushedAiProfileWatermarks: workspaceLastPushedAiProfileWatermarksRef, lastPushedAiProfileChangeKeys: workspaceLastPushedAiProfileChangeKeysRef, lastPushedDocumentPaths: workspaceLastPushedDocumentPathsRef, lastPushedDocumentWatermarks: workspaceLastPushedDocumentWatermarksRef, lastPushedAssetPaths: workspaceLastPushedAssetPathsRef, lastPushedAssetWatermarks: workspaceLastPushedAssetWatermarksRef, lastPushedDocumentReviewSessionIds: workspaceLastPushedDocumentReviewSessionIdsRef, lastPushedDocumentReviewSessionWatermarks: workspaceLastPushedDocumentReviewSessionWatermarksRef, lastPushedDocumentReviewCommentIds: workspaceLastPushedDocumentReviewCommentIdsRef, lastPushedDocumentReviewCommentWatermarks: workspaceLastPushedDocumentReviewCommentWatermarksRef, lastPushedAnnotatedAttachmentSessionIds: workspaceLastPushedAnnotatedAttachmentSessionIdsRef, lastPushedAnnotatedAttachmentSessionWatermarks: workspaceLastPushedAnnotatedAttachmentSessionWatermarksRef, lastPushedTaskforceAgentIds: workspaceLastPushedTaskforceAgentIdsRef, lastPushedTaskforceAgentWatermarks: workspaceLastPushedTaskforceAgentWatermarksRef, lastPushedTaskforceAgentSkillIds: workspaceLastPushedTaskforceAgentSkillIdsRef, lastPushedTaskforceAgentSkillWatermarks: workspaceLastPushedTaskforceAgentSkillWatermarksRef, lastPushedAgentConversationIds: workspaceLastPushedAgentConversationIdsRef, lastPushedAgentConversationWatermarks: workspaceLastPushedAgentConversationWatermarksRef, lastPushedTaskEventWatermarks: workspaceLastPushedTaskEventWatermarksRef, baselineResetReason: workspaceBaselineResetReasonRef, captureAttachBootstrapBaseline: workspaceCaptureAttachBootstrapBaselineRef, startupFullReconcileRan: workspaceStartupFullReconcileRanRef, startupFullReconcileRequested: workspaceStartupFullReconcileRequestedRef, fullReconcileInFlight: workspaceFullReconcileInFlightRef, bootstrapLastProgressAtMs: bootstrapLastProgressAtRef, realtimeSuppressedEventQueue: realtimeSuppressedEventQueueRef, } = runtime;
176
177
  const scheduledTasks = new Map();
177
178
  let disposed = false;
178
179
  const scheduleCoordinatorTask = (key, callback, delayMs) => {
@@ -391,6 +392,10 @@ export function createWorkspaceTransferCoordinator({ cloudAuthConfigured, runtim
391
392
  }
392
393
  let applyResult;
393
394
  try {
395
+ const applyOptions = {
396
+ repairMode: replayPayload?.repairMode ?? repairMode,
397
+ excludedProjections: pushResult.effectiveV2ExcludedProjections,
398
+ };
394
399
  const authoritativeChanges = appliedTaskUpserts.map((entry) => ({
395
400
  op: 'upsert',
396
401
  archived: entry.archived === true,
@@ -398,8 +403,8 @@ export function createWorkspaceTransferCoordinator({ cloudAuthConfigured, runtim
398
403
  ...(entry.durableRevision ? { durableRevision: entry.durableRevision } : {}),
399
404
  }));
400
405
  applyResult = completionGroup
401
- ? await localServices.applyV2Batch(currentWorkspaceId, authoritativeChanges, { completionGroup })
402
- : await localServices.applyV2Batch(currentWorkspaceId, authoritativeChanges);
406
+ ? await localServices.applyV2Batch(currentWorkspaceId, authoritativeChanges, { ...applyOptions, completionGroup })
407
+ : await localServices.applyV2Batch(currentWorkspaceId, authoritativeChanges, applyOptions);
403
408
  }
404
409
  catch (error) {
405
410
  if (pushTransferReceipts.length > 0) {
@@ -419,7 +424,7 @@ export function createWorkspaceTransferCoordinator({ cloudAuthConfigured, runtim
419
424
  errorCode: 'WORKSPACE_SYNC_V2_PUSH_AUTHORITATIVE_APPLY_FAILED',
420
425
  });
421
426
  }
422
- throw new Error(`Authoritative V2 push echo apply failed (${applyResult.status || 0}).`);
427
+ throw new Error(authoritativeV2ApplyFailureMessage(applyResult));
423
428
  }
424
429
  for (const entry of appliedTaskUpserts) {
425
430
  const taskId = String(entry.task.id || '').trim();
@@ -462,6 +467,8 @@ export function createWorkspaceTransferCoordinator({ cloudAuthConfigured, runtim
462
467
  workspaceLastPushedInitiativeWatermarksRef.current = new Map(pushResult.currentInitiativeWatermarks);
463
468
  workspaceLastPushedWorkstreamIdsRef.current = new Set(pushResult.currentWorkstreamIds);
464
469
  workspaceLastPushedWorkstreamWatermarksRef.current = new Map(pushResult.currentWorkstreamWatermarks);
470
+ workspaceLastPushedPlanningIdentityWatermarksRef.current = new Map(pushResult.currentPlanningIdentityWatermarks
471
+ || payload.currentPlanningIdentityWatermarks);
465
472
  workspaceLastPushedAiProfileIdsRef.current = new Set(pushResult.currentAiProfileIds);
466
473
  workspaceLastPushedAiProfileWatermarksRef.current = new Map(pushResult.currentAiProfileWatermarks);
467
474
  workspaceLastPushedAiProfileChangeKeysRef.current = pushResult.currentAiProfileChangeKeys
@@ -12,6 +12,7 @@ type SyncCore = TaskforceCore & TaskforceSyncCapable;
12
12
  type ContentSyncState = ReturnType<typeof createContentSyncState>;
13
13
  export interface WorkspaceSyncV2DispatchOptions {
14
14
  allowReferenceNumberReassignment?: boolean;
15
+ actorUserId?: string;
15
16
  workspaceMembers?: WorkspaceSyncWorkspaceMemberSnapshot[];
16
17
  coexistenceDirection?: TaskMetadataCoexistenceDirection;
17
18
  assertedActiveV3TaskMetadataIds?: ReadonlySet<string>;
@@ -7,6 +7,7 @@ import { WorkspaceSyncDurabilityStore } from '../v3/syncDurabilityStore.js';
7
7
  import { assertWorkspaceSyncV2TaskCarrierRootsExist, prepareWorkspaceSyncV2TaskCarriers, } from '../v3/workspaceSyncV2ProjectionExclusions.js';
8
8
  import { resolveV3OwnedTaskDeleteIds, resolveV3OwnedTaskLifecycleIds, resolveV3OwnedTaskMetadataIds, resolveV3OwnedTaskReopenAssigneeIds, resolveV3OwnedTaskTaxonomyIds, } from '../v3/taskMetadataCoexistence.js';
9
9
  import { assertWorkspaceSyncV2MetadataOnlyApplyPreflight, } from './workspaceSyncEngineLocalApply.js';
10
+ import { assertTaskforceAgentSyncPushAccess } from '../taskforceAgentSyncAuthorization.js';
10
11
  function createSyncRouteError(message, details, options) {
11
12
  const error = new Error(message);
12
13
  error.code = options?.code || 'SYNC_APPLY_FAILED';
@@ -132,6 +133,14 @@ export function createWorkspaceSyncV2ChangeDispatcher(dependencies) {
132
133
  normalizeTaskEventSyncPayload,
133
134
  recordSyncDiagnostic,
134
135
  });
136
+ if (options.coexistenceDirection === 'cloud-push') {
137
+ assertTaskforceAgentSyncPushAccess({
138
+ agents: applyModel.collaboration.incomingTaskforceAgents.values(),
139
+ actorUserId: String(options.actorUserId || '').trim() || null,
140
+ hasUserFeatureGrant: (userId, featureKey) => core.hasUserFeatureGrant(userId, featureKey),
141
+ createSyncRouteError,
142
+ });
143
+ }
135
144
  if (metadataOnly) {
136
145
  assertWorkspaceSyncV2MetadataOnlyApplyPreflight(incomingChanges);
137
146
  }
@@ -304,6 +313,10 @@ export function createWorkspaceSyncV2ChangeDispatcher(dependencies) {
304
313
  incomingAgentRoles: applyModel.collaboration.incomingAgentRoles,
305
314
  incomingTaskforceAgentSkills: applyModel.collaboration.incomingTaskforceAgentSkills,
306
315
  incomingAgentConversations: applyModel.collaboration.incomingAgentConversations,
316
+ ...(options.coexistenceDirection === 'cloud-push' ? {
317
+ taskforceAgentPushActorUserId: String(options.actorUserId || '').trim() || null,
318
+ taskforceAgentPushAccessPreflighted: true,
319
+ } : {}),
307
320
  recordSyncDiagnostic,
308
321
  createSyncRouteError,
309
322
  });
@@ -633,6 +646,18 @@ export function createWorkspaceSyncV2ChangeDispatcher(dependencies) {
633
646
  sourceUpdatedAt: intent.sourceUpdatedAt,
634
647
  publishedAt: now().toISOString(),
635
648
  deletedAt: intent.sourceUpdatedAt,
649
+ // This dispatch path only ever runs from an explicit document-delete/
650
+ // asset-delete WorkspaceSyncChange (see workspaceSyncV2PreparedContent.ts)
651
+ // — never from workspace repair, which is intentionally routed to a
652
+ // durable retry obligation instead (see workspaceRepair.ts) rather than
653
+ // ever reaching this admission boundary. operationId/actorId are not yet
654
+ // threaded through the WorkspaceSyncChange wire format from origin to this
655
+ // layer — see the type's doc comment.
656
+ provenance: {
657
+ source: 'explicit-delete',
658
+ sourceRuntime: 'server',
659
+ repairInvolved: false,
660
+ },
636
661
  });
637
662
  if (tombstone.versionId !== null
638
663
  || tombstone.sourceUpdatedAt !== intent.sourceUpdatedAt
@@ -748,6 +773,10 @@ export function createWorkspaceSyncV2ChangeDispatcher(dependencies) {
748
773
  incomingAgentRoles: applyModel.collaboration.incomingAgentRoles,
749
774
  incomingTaskforceAgentSkills: applyModel.collaboration.incomingTaskforceAgentSkills,
750
775
  incomingAgentConversations: applyModel.collaboration.incomingAgentConversations,
776
+ ...(options.coexistenceDirection === 'cloud-push' ? {
777
+ taskforceAgentPushActorUserId: String(options.actorUserId || '').trim() || null,
778
+ taskforceAgentPushAccessPreflighted: true,
779
+ } : {}),
751
780
  recordSyncDiagnostic,
752
781
  createSyncRouteError,
753
782
  });
@@ -255,6 +255,8 @@ export declare function applyCollaborationSyncChanges(input: {
255
255
  incomingAgentRoles?: Map<string, WorkspaceSyncAgentRoleSnapshot>;
256
256
  incomingTaskforceAgentSkills?: Map<string, WorkspaceSyncTaskforceAgentSkillSnapshot>;
257
257
  incomingAgentConversations?: Map<string, WorkspaceSyncAgentConversationSnapshot>;
258
+ taskforceAgentPushActorUserId?: string | null;
259
+ taskforceAgentPushAccessPreflighted?: boolean;
258
260
  recordSyncDiagnostic: RecordSyncDiagnostic;
259
261
  createSyncRouteError: CreateSyncRouteError;
260
262
  }): void;
@@ -18,6 +18,7 @@ import { TaskforceAgentStore } from '../storage/taskforceAgentStore.js';
18
18
  import { TaskforceAgentSkillStore } from '../storage/taskforceAgentSkillStore.js';
19
19
  import { TaskforceAgentConversationStore } from '../storage/taskforceAgentConversationStore.js';
20
20
  import { AgentRoleStore } from '../storage/agentRoleStore.js';
21
+ import { assertTaskforceAgentSyncPushAccess } from './taskforceAgentSyncAuthorization.js';
21
22
  import { preserveV3OwnedTaskRoot, preserveV3OwnedTaskLifecycle, preserveV3OwnedTaskMetadata, preserveV3OwnedTaskReopenAssignee, preserveV3OwnedTaskTaxonomy, } from './v3/taskMetadataCoexistence.js';
22
23
  function createIncomingApplyModel() {
23
24
  return {
@@ -1052,7 +1053,15 @@ export async function applyContentSyncChanges(input) {
1052
1053
  }
1053
1054
  }
1054
1055
  export function applyCollaborationSyncChanges(input) {
1055
- const { core, workspaceId, incomingDocumentReviewSessions, incomingDocumentReviewSessionDeletes, incomingDocumentReviewComments, incomingDocumentReviewCommentDeletes, incomingAnnotatedAttachmentSessions, incomingAnnotatedAttachmentSessionDeletes, incomingTaskforceAgents = new Map(), incomingAgentRoles = new Map(), incomingTaskforceAgentSkills = new Map(), incomingAgentConversations = new Map(), recordSyncDiagnostic, createSyncRouteError, } = input;
1056
+ const { core, workspaceId, incomingDocumentReviewSessions, incomingDocumentReviewSessionDeletes, incomingDocumentReviewComments, incomingDocumentReviewCommentDeletes, incomingAnnotatedAttachmentSessions, incomingAnnotatedAttachmentSessionDeletes, incomingTaskforceAgents = new Map(), incomingAgentRoles = new Map(), incomingTaskforceAgentSkills = new Map(), incomingAgentConversations = new Map(), taskforceAgentPushActorUserId, taskforceAgentPushAccessPreflighted = false, recordSyncDiagnostic, createSyncRouteError, } = input;
1057
+ if (taskforceAgentPushActorUserId !== undefined && !taskforceAgentPushAccessPreflighted) {
1058
+ assertTaskforceAgentSyncPushAccess({
1059
+ agents: incomingTaskforceAgents.values(),
1060
+ actorUserId: taskforceAgentPushActorUserId,
1061
+ hasUserFeatureGrant: (userId, featureKey) => core.hasUserFeatureGrant(userId, featureKey),
1062
+ createSyncRouteError,
1063
+ });
1064
+ }
1056
1065
  if (incomingDocumentReviewSessions.size > 0) {
1057
1066
  for (const session of incomingDocumentReviewSessions.values()) {
1058
1067
  try {
@@ -52,6 +52,12 @@ export interface WorkspacePushSyncInput {
52
52
  remoteServices?: WorkspaceSyncEngineRemoteServices;
53
53
  localServices?: Pick<WorkspaceSyncEngineLocalServices, 'readPushOwnership'>;
54
54
  acknowledgedNonApplyingBatchOperationIdentities?: readonly string[];
55
+ /**
56
+ * Server-owned pages whose remote receipt, authoritative task echo, and
57
+ * runner checkpoint contribution committed atomically. Browser callers
58
+ * must not use this recovery boundary.
59
+ */
60
+ settledBatchOperationIdentities?: readonly string[];
55
61
  preparedPlan?: WorkspacePushPreparedPlan | null;
56
62
  onPreparedPlan?: (input: {
57
63
  plan: WorkspacePushPreparedPlan;
@@ -62,6 +68,14 @@ export interface WorkspacePushSyncInput {
62
68
  operationIdentity: string;
63
69
  acknowledgedOperationIdentities: readonly string[];
64
70
  }) => void | Promise<void>;
71
+ onAcceptedBatchSettled?: (input: {
72
+ operationIdentity: string;
73
+ settlementIdentityFingerprint: string;
74
+ appliedTaskUpserts: WorkspacePushSyncResult['appliedTaskUpserts'];
75
+ transferReceipt: WorkspaceSyncEngineRemoteTransferReceipt;
76
+ pushBoundary: WorkspaceSyncEngineV2PushBoundary;
77
+ excludedProjections?: readonly WorkspaceSyncV2ProjectionExclusion[];
78
+ }) => void | Promise<void>;
65
79
  }
66
80
  export interface WorkspacePushSyncResult {
67
81
  success: boolean;
@@ -77,6 +91,8 @@ export interface WorkspacePushSyncResult {
77
91
  effectiveDeltaDiagnostics?: WorkspaceSyncDeltaDiagnostics & {
78
92
  combinedV3SuppressedChangeCount?: number;
79
93
  };
94
+ /** Exact V3-owned projections excluded while preparing this V2 attempt. */
95
+ effectiveV2ExcludedProjections?: readonly WorkspaceSyncV2ProjectionExclusion[];
80
96
  deleteCount: number;
81
97
  currentTaskIds: Set<string>;
82
98
  currentTaskWatermarks?: Map<string, string>;
@@ -88,6 +104,7 @@ export interface WorkspacePushSyncResult {
88
104
  currentInitiativeWatermarks: Map<string, string>;
89
105
  currentWorkstreamIds: Set<string>;
90
106
  currentWorkstreamWatermarks: Map<string, string>;
107
+ currentPlanningIdentityWatermarks?: Map<string, string>;
91
108
  currentAiProfileIds: Set<string>;
92
109
  currentAiProfileWatermarks: Map<string, string>;
93
110
  currentAiProfileChangeKeys?: Map<string, string>;
@@ -1,11 +1,11 @@
1
1
  import { applyLocalWorkspaceChanges, getLocalWorkspaceContentPullObligations, recordLocalWorkspaceContentPullObligationFailures, getLocalWorkspaceContentManifest, pullUserSettings, pushUserSettings, prepareWorkspacePushChanges, } from './cloudSyncApi.js';
2
2
  import { workspaceSyncContentPullObligationId, } from './engine/workspaceSyncContentPullObligationStore.js';
3
3
  import { createBrowserWorkspaceSyncEngineRemoteServices, } from './engine/workspaceSyncEngineRemoteServices.js';
4
- import { createWorkspaceSyncEngineV2PushBoundary, parseWorkspaceSyncEngineAppliedTaskUpserts, workspaceSyncEngineExpectedTaskEchoIds, } from './engine/workspaceSyncEnginePushCompletion.js';
4
+ import { createWorkspaceSyncEngineV2SettlementIdentityProjection, createWorkspaceSyncEngineV2PushBoundary, parseWorkspaceSyncEngineAppliedTaskUpserts, workspaceSyncEngineExpectedTaskEchoIds, } from './engine/workspaceSyncEnginePushCompletion.js';
5
5
  import { encryptDocument } from './encryptionService.js';
6
6
  import { decryptWorkspaceSyncContentChangeInPlace } from './workspaceSyncContentDecryption.js';
7
7
  import { decideWorkspaceContentFetch, fingerprintWorkspaceContentBody, } from './workspaceContentManifest.js';
8
- import { workspaceSyncV2ProjectionExclusionsEqual, } from './v3/workspaceSyncV2ProjectionExclusions.js';
8
+ import { normalizeWorkspaceSyncV2ProjectionExclusions, workspaceSyncV2ProjectionExclusionsEqual, } from './v3/workspaceSyncV2ProjectionExclusions.js';
9
9
  import { WORKSPACE_PUSH_PREPARED_PLAN_VERSION, } from './workspacePushPreparedPlan.js';
10
10
  import { canonicalWorkspaceSyncJson } from './v3/canonicalWorkspaceSyncJson.js';
11
11
  function asObjectRecord(value) {
@@ -181,13 +181,8 @@ function buildEffectiveWorkspacePushDiagnostics(diagnostics, changes, ownership)
181
181
  : {}),
182
182
  };
183
183
  }
184
- async function computeIdempotencyKey(workspaceId, changes, repairMode) {
185
- const text = canonicalWorkspaceSyncJson({
186
- contractVersion: 1,
187
- workspaceId,
188
- repairMode,
189
- changes
190
- });
184
+ async function computeCanonicalWorkspaceSyncSha256(value, fallbackNamespace) {
185
+ const text = canonicalWorkspaceSyncJson(value);
191
186
  try {
192
187
  const buffer = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(text));
193
188
  return Array.from(new Uint8Array(buffer)).map(b => b.toString(16).padStart(2, '0')).join('');
@@ -202,9 +197,19 @@ async function computeIdempotencyKey(workspaceId, changes, repairMode) {
202
197
  hash = Math.imul(hash, 0x01000193);
203
198
  }
204
199
  const hex = (hash >>> 0).toString(16).padStart(8, '0');
205
- return `${workspaceId}:fallback:${hex}`;
200
+ return fallbackNamespace
201
+ ? `${fallbackNamespace}:fallback:${hex}`
202
+ : hex.repeat(8);
206
203
  }
207
204
  }
205
+ async function computeIdempotencyKey(workspaceId, changes, repairMode) {
206
+ return computeCanonicalWorkspaceSyncSha256({
207
+ contractVersion: 1,
208
+ workspaceId,
209
+ repairMode,
210
+ changes
211
+ }, workspaceId);
212
+ }
208
213
  const MAX_WORKSPACE_PUSH_CHANGES_PER_REQUEST = 64;
209
214
  const MAX_WORKSPACE_PUSH_BYTES_PER_REQUEST = 4 * 1024 * 1024;
210
215
  const MAX_WORKSPACE_PUSH_SINGLE_CHANGE_BYTES = 45 * 1024 * 1024;
@@ -428,6 +433,7 @@ export async function runWorkspacePushSyncService(input) {
428
433
  currentInitiativeWatermarks: input.payload.currentInitiativeWatermarks,
429
434
  currentWorkstreamIds: input.payload.currentWorkstreamIds,
430
435
  currentWorkstreamWatermarks: input.payload.currentWorkstreamWatermarks,
436
+ currentPlanningIdentityWatermarks: input.payload.currentPlanningIdentityWatermarks,
431
437
  currentAiProfileIds: input.payload.currentAiProfileIds,
432
438
  currentAiProfileWatermarks: input.payload.currentAiProfileWatermarks,
433
439
  currentAiProfileChangeKeys: input.payload.currentAiProfileChangeKeys ?? new Map(),
@@ -464,6 +470,7 @@ export async function runWorkspacePushSyncService(input) {
464
470
  }
465
471
  const changeCount = preparedChanges.length;
466
472
  const effectiveDeltaDiagnostics = buildEffectiveWorkspacePushDiagnostics(input.payload.deltaDiagnostics, preparedChanges, preparedOwnership);
473
+ const effectiveV2ExcludedProjections = normalizeWorkspaceSyncV2ProjectionExclusions(preparedOwnership.combinedExcludedProjections || []);
467
474
  const deleteCount = input.payload.deleteTaskIds.size;
468
475
  let requestMs = 0;
469
476
  const canElideSteadyStateRequest = changeCount === 0
@@ -478,6 +485,7 @@ export async function runWorkspacePushSyncService(input) {
478
485
  requestMs: 0,
479
486
  changeCount: 0,
480
487
  effectiveDeltaDiagnostics,
488
+ effectiveV2ExcludedProjections,
481
489
  deleteCount,
482
490
  currentTaskIds: input.payload.currentTaskIds,
483
491
  currentTaskWatermarks: input.payload.currentTaskWatermarks ?? new Map(),
@@ -489,6 +497,7 @@ export async function runWorkspacePushSyncService(input) {
489
497
  currentInitiativeWatermarks: input.payload.currentInitiativeWatermarks,
490
498
  currentWorkstreamIds: input.payload.currentWorkstreamIds,
491
499
  currentWorkstreamWatermarks: input.payload.currentWorkstreamWatermarks,
500
+ currentPlanningIdentityWatermarks: input.payload.currentPlanningIdentityWatermarks,
492
501
  currentAiProfileIds: input.payload.currentAiProfileIds,
493
502
  currentAiProfileWatermarks: input.payload.currentAiProfileWatermarks,
494
503
  currentAiProfileChangeKeys: input.payload.currentAiProfileChangeKeys ?? new Map(),
@@ -581,6 +590,7 @@ export async function runWorkspacePushSyncService(input) {
581
590
  currentInitiativeWatermarks: input.payload.currentInitiativeWatermarks,
582
591
  currentWorkstreamIds: input.payload.currentWorkstreamIds,
583
592
  currentWorkstreamWatermarks: input.payload.currentWorkstreamWatermarks,
593
+ currentPlanningIdentityWatermarks: input.payload.currentPlanningIdentityWatermarks,
584
594
  currentAiProfileIds: input.payload.currentAiProfileIds,
585
595
  currentAiProfileWatermarks: input.payload.currentAiProfileWatermarks,
586
596
  currentAiProfileChangeKeys: input.payload.currentAiProfileChangeKeys ?? new Map(),
@@ -668,8 +678,18 @@ export async function runWorkspacePushSyncService(input) {
668
678
  && acknowledgedNonApplyingBatchOperationIdentities.size !== requestedAcknowledgements.length) {
669
679
  throw new Error('Persisted V2 push batch acknowledgement state does not match the frozen push plan.');
670
680
  }
681
+ const requestedSettledBatchOperationIdentities = input.settledBatchOperationIdentities || [];
682
+ if ((requestedSettledBatchOperationIdentities.length > 0
683
+ && !input.onAcceptedBatchSettled)
684
+ || new Set(requestedSettledBatchOperationIdentities).size
685
+ !== requestedSettledBatchOperationIdentities.length
686
+ || requestedSettledBatchOperationIdentities.some((identity) => !batchOperationIdentities.includes(identity))) {
687
+ throw new Error('Persisted V2 push batch settlement state does not match the frozen push plan.');
688
+ }
689
+ const settledBatchOperationIdentities = new Set(requestedSettledBatchOperationIdentities);
671
690
  let completedBatchCount = 0;
672
691
  let completedChangeCount = 0;
692
+ let firstPushFailure = null;
673
693
  const pushTransferReceipts = [];
674
694
  const abandonRetainedPushReceipts = async (errorCode) => {
675
695
  if (pushTransferReceipts.length === 0)
@@ -687,7 +707,8 @@ export async function runWorkspacePushSyncService(input) {
687
707
  const safeBatchChanges = batch.map((entry) => entry.safe);
688
708
  const expectedTaskEchoIds = workspaceSyncEngineExpectedTaskEchoIds(plainBatchChanges);
689
709
  const idempotencyKey = batchOperationIdentities[batchIndex];
690
- if (acknowledgedNonApplyingBatchOperationIdentities.has(idempotencyKey)) {
710
+ if (settledBatchOperationIdentities.has(idempotencyKey)
711
+ || acknowledgedNonApplyingBatchOperationIdentities.has(idempotencyKey)) {
691
712
  completedBatchCount += 1;
692
713
  completedChangeCount += plainBatchChanges.length;
693
714
  continue;
@@ -730,7 +751,12 @@ export async function runWorkspacePushSyncService(input) {
730
751
  const data = asObjectRecord(pushResult.data);
731
752
  const failedOperations = Array.from(new Set(plainBatchChanges.map((change) => change.op)));
732
753
  const failedContentChanges = plainBatchChanges.filter(isWorkspacePushContentChange).length;
733
- return {
754
+ const failureDomain = failedContentChanges === plainBatchChanges.length
755
+ ? 'content'
756
+ : failedContentChanges === 0
757
+ ? 'metadata'
758
+ : 'mixed';
759
+ const failureResult = {
734
760
  success: false,
735
761
  status: pushResult.status,
736
762
  error: typeof data.error === 'string' ? data.error : undefined,
@@ -742,11 +768,7 @@ export async function runWorkspacePushSyncService(input) {
742
768
  failedBatchIndex: batchIndex,
743
769
  failedChangeCount: plainBatchChanges.length,
744
770
  failedOperations,
745
- failureDomain: failedContentChanges === plainBatchChanges.length
746
- ? 'content'
747
- : failedContentChanges === 0
748
- ? 'metadata'
749
- : 'mixed',
771
+ failureDomain,
750
772
  },
751
773
  retryAfterMs: pushResult.retryAfterMs,
752
774
  transient: pushInProgress || isTransientWorkspaceSyncStatus(pushResult.status),
@@ -763,6 +785,7 @@ export async function runWorkspacePushSyncService(input) {
763
785
  currentInitiativeWatermarks: input.payload.currentInitiativeWatermarks,
764
786
  currentWorkstreamIds: input.payload.currentWorkstreamIds,
765
787
  currentWorkstreamWatermarks: input.payload.currentWorkstreamWatermarks,
788
+ currentPlanningIdentityWatermarks: input.payload.currentPlanningIdentityWatermarks,
766
789
  currentAiProfileIds: input.payload.currentAiProfileIds,
767
790
  currentAiProfileWatermarks: input.payload.currentAiProfileWatermarks,
768
791
  currentAiProfileChangeKeys: input.payload.currentAiProfileChangeKeys ?? new Map(),
@@ -791,8 +814,18 @@ export async function runWorkspacePushSyncService(input) {
791
814
  pushedWatermarks: new Map(),
792
815
  pushedTaskChangeKeys: new Map(),
793
816
  emittedEventIds: [],
794
- appliedTaskUpserts: []
817
+ appliedTaskUpserts: [],
795
818
  };
819
+ firstPushFailure ||= failureResult;
820
+ // Only content is isolated from later durable projections.
821
+ // Ownership, auth, and metadata failures can invalidate phase
822
+ // dependencies, so they still stop the attempt immediately.
823
+ if (failureDomain !== 'content')
824
+ return failureResult;
825
+ // Later phases contain independent relationships, events, and
826
+ // comments. Let them settle and checkpoint their non-applying
827
+ // receipts even though this attempt reports the content failure.
828
+ continue;
796
829
  }
797
830
  const pushData = asObjectRecord(pushResult.data);
798
831
  if (Array.isArray(pushData.emittedEventIds)) {
@@ -804,7 +837,29 @@ export async function runWorkspacePushSyncService(input) {
804
837
  }
805
838
  const normalizedTaskUpserts = parseWorkspaceSyncEngineAppliedTaskUpserts(pushData, expectedTaskEchoIds);
806
839
  appliedTaskUpserts.push(...normalizedTaskUpserts);
807
- if (pushResult.transferReceipt && normalizedTaskUpserts.length === 0) {
840
+ if (input.onAcceptedBatchSettled) {
841
+ if (!pushResult.transferReceipt) {
842
+ throw new Error('Accepted V2 push batch is missing its atomic settlement receipt.');
843
+ }
844
+ await input.onAcceptedBatchSettled({
845
+ operationIdentity: idempotencyKey,
846
+ settlementIdentityFingerprint: await computeCanonicalWorkspaceSyncSha256(createWorkspaceSyncEngineV2SettlementIdentityProjection({
847
+ operationIdentity: idempotencyKey,
848
+ changes: plainBatchChanges,
849
+ appliedTaskUpserts: normalizedTaskUpserts,
850
+ excludedProjections: effectiveV2ExcludedProjections,
851
+ })),
852
+ appliedTaskUpserts: normalizedTaskUpserts,
853
+ transferReceipt: pushResult.transferReceipt,
854
+ pushBoundary,
855
+ excludedProjections: effectiveV2ExcludedProjections,
856
+ });
857
+ const receiptIndex = pushTransferReceipts.indexOf(pushResult.transferReceipt);
858
+ if (receiptIndex >= 0)
859
+ pushTransferReceipts.splice(receiptIndex, 1);
860
+ settledBatchOperationIdentities.add(idempotencyKey);
861
+ }
862
+ else if (pushResult.transferReceipt && normalizedTaskUpserts.length === 0) {
808
863
  await remoteServices.acknowledgeNonApplyingTransferReceipts({
809
864
  workspaceId: input.workspaceId,
810
865
  receipts: [pushResult.transferReceipt],
@@ -826,6 +881,17 @@ export async function runWorkspacePushSyncService(input) {
826
881
  await abandonRetainedPushReceipts('WORKSPACE_SYNC_V2_PUSH_ATTEMPT_FAILED');
827
882
  throw error;
828
883
  }
884
+ if (firstPushFailure) {
885
+ return {
886
+ ...firstPushFailure,
887
+ batchProgress: {
888
+ ...firstPushFailure.batchProgress,
889
+ completedBatches: completedBatchCount,
890
+ completedChanges: completedChangeCount,
891
+ },
892
+ requestMs,
893
+ };
894
+ }
829
895
  return {
830
896
  success: true,
831
897
  syncedAt: new Date().toISOString(),
@@ -841,6 +907,7 @@ export async function runWorkspacePushSyncService(input) {
841
907
  failureDomain: null,
842
908
  },
843
909
  effectiveDeltaDiagnostics,
910
+ effectiveV2ExcludedProjections,
844
911
  deleteCount,
845
912
  currentTaskIds: input.payload.currentTaskIds,
846
913
  currentTaskWatermarks: input.payload.currentTaskWatermarks ?? new Map(),
@@ -852,6 +919,7 @@ export async function runWorkspacePushSyncService(input) {
852
919
  currentInitiativeWatermarks: input.payload.currentInitiativeWatermarks,
853
920
  currentWorkstreamIds: input.payload.currentWorkstreamIds,
854
921
  currentWorkstreamWatermarks: input.payload.currentWorkstreamWatermarks,
922
+ currentPlanningIdentityWatermarks: input.payload.currentPlanningIdentityWatermarks,
855
923
  currentAiProfileIds: input.payload.currentAiProfileIds,
856
924
  currentAiProfileWatermarks: input.payload.currentAiProfileWatermarks,
857
925
  currentAiProfileChangeKeys: input.payload.currentAiProfileChangeKeys ?? new Map(),
@@ -0,0 +1,16 @@
1
+ import type { WorkspaceSyncTaskforceAgentSnapshot } from './workspaceSyncModel.js';
2
+ type SyncAuthorizationError = Error & {
3
+ code?: string;
4
+ statusCode?: number;
5
+ details?: Record<string, unknown>;
6
+ };
7
+ export declare function assertTaskforceAgentSyncPushAccess(input: {
8
+ agents: Iterable<WorkspaceSyncTaskforceAgentSnapshot>;
9
+ actorUserId: string | null;
10
+ hasUserFeatureGrant: (userId: string, featureKey: unknown) => boolean;
11
+ createSyncRouteError: (message: string, details: Record<string, unknown>, options?: {
12
+ code?: string;
13
+ statusCode?: number;
14
+ }) => SyncAuthorizationError;
15
+ }): void;
16
+ export {};
@@ -0,0 +1,20 @@
1
+ import { getTaskforceAgentModel } from '../shared/taskforceAgentModels.js';
2
+ import { INTERNAL_SUBSCRIPTION_MODEL_FEATURE_KEY } from '../shared/userFeatureGrants.js';
3
+ export function assertTaskforceAgentSyncPushAccess(input) {
4
+ const actorUserId = String(input.actorUserId || '').trim();
5
+ for (const agent of input.agents) {
6
+ if (agent.deletedAt)
7
+ continue;
8
+ const modelKey = String(agent.definition?.model?.modelKey || agent.modelKey || '').trim();
9
+ if (getTaskforceAgentModel(modelKey)?.source !== 'subscription_dev')
10
+ continue;
11
+ if (actorUserId && input.hasUserFeatureGrant(actorUserId, INTERNAL_SUBSCRIPTION_MODEL_FEATURE_KEY))
12
+ continue;
13
+ throw input.createSyncRouteError(`Subscription-backed Taskforce Agent ${agent.id} requires an internal user grant.`, {
14
+ source: 'apply.taskforceAgentUpsert',
15
+ agentId: agent.id,
16
+ actorUserId: actorUserId || null,
17
+ featureKey: INTERNAL_SUBSCRIPTION_MODEL_FEATURE_KEY,
18
+ }, { code: 'SUBSCRIPTION_MODEL_ACCESS_REQUIRED', statusCode: 403 });
19
+ }
20
+ }
@@ -3,6 +3,8 @@ import { WORKSPACE_SYNC_V3_COMBINED_CAPABILITY_VERSION, WORKSPACE_SYNC_V3_COMBIN
3
3
  import { WORKSPACE_SYNC_V3_NESTED_COVERAGE_SELECTOR } from './workspaceSyncV3NestedWireContract.js';
4
4
  import { WORKSPACE_SYNC_V3_WORKFLOW_COVERAGE_SELECTOR } from './workspaceSyncV3WorkflowWireContract.js';
5
5
  import { WORKSPACE_SYNC_V3_PLANNING_ORDER_COVERAGE_SELECTOR } from './workspaceSyncV3PlanningOrderWireContract.js';
6
+ import { WORKSPACE_SYNC_V3_TASK_COVER_COVERAGE_SELECTOR } from './workspaceSyncV3TaskCoverWireContract.js';
7
+ import { WORKSPACE_SYNC_V3_WORKFLOW_TASK_COVER_COVERAGE_SELECTOR } from './workspaceSyncV3WorkflowTaskCoverWireContract.js';
6
8
  export { WORKSPACE_SYNC_V3_COMBINED_CAPABILITY_VERSION } from './workspaceSyncV3CombinedWireContract.js';
7
9
  export function resolveRequestedCombinedFeedCoverage(env = process.env) {
8
10
  const requestedVersion = String(env.TASKFORCE_SYNC_V3_COMBINED_FEED_COVERAGE_VERSION || '').trim();
@@ -18,6 +20,12 @@ export function resolveRequestedCombinedFeedCoverage(env = process.env) {
18
20
  if (requestedVersion === String(WORKSPACE_SYNC_V3_PLANNING_ORDER_COVERAGE_SELECTOR.coverageVersion)) {
19
21
  return WORKSPACE_SYNC_V3_PLANNING_ORDER_COVERAGE_SELECTOR;
20
22
  }
23
+ if (requestedVersion === String(WORKSPACE_SYNC_V3_TASK_COVER_COVERAGE_SELECTOR.coverageVersion)) {
24
+ return WORKSPACE_SYNC_V3_TASK_COVER_COVERAGE_SELECTOR;
25
+ }
26
+ if (requestedVersion === String(WORKSPACE_SYNC_V3_WORKFLOW_TASK_COVER_COVERAGE_SELECTOR.coverageVersion)) {
27
+ return WORKSPACE_SYNC_V3_WORKFLOW_TASK_COVER_COVERAGE_SELECTOR;
28
+ }
21
29
  throw new Error(`Unsupported TASKFORCE_SYNC_V3_COMBINED_FEED_COVERAGE_VERSION: ${requestedVersion}.`);
22
30
  }
23
31
  export function resolveCombinedFeedCapability(input) {
@@ -7,6 +7,7 @@ import { enqueueLocalInitiativeMutation, } from './localInitiativeOutboxService.
7
7
  import { isWorkspaceSyncV3PlanningActivationEnabled } from './planningActivation.js';
8
8
  import { serializeEntityActivityForSync } from './taskActivityJournal.js';
9
9
  import { WorkspaceSyncDurabilityStore, WorkspaceSyncIdempotencyConflictError } from './syncDurabilityStore.js';
10
+ import { readDurableOperationReplay } from './durableOperationReplay.js';
10
11
  import { buildInitiativeActivityEventId } from './initiativeActivityIdentity.js';
11
12
  const OPERATION_LEASE_MS = 30_000;
12
13
  export class DurableInitiativeMutationRouterDisabledError extends Error {
@@ -85,6 +86,9 @@ export function createDurableInitiativeMutationRouter(input) {
85
86
  if (persistedOutbox.domain !== 'initiative' || persistedOutbox.entityId !== initiativeId) {
86
87
  throw new WorkspaceSyncIdempotencyConflictError();
87
88
  }
89
+ store.assertOutboxOperationIdentity(persistedOutbox, {
90
+ domain: 'initiative', entityId: initiativeId, mutationKind: persistedOutbox.mutationKind,
91
+ });
88
92
  return {
89
93
  revisions: {
90
94
  entityRevision: persistedOutbox.baseEntityRevision,
@@ -99,18 +103,22 @@ export function createDurableInitiativeMutationRouter(input) {
99
103
  if (operationState?.status === 'committed') {
100
104
  if (!operationState.responseJson)
101
105
  throw new Error('Committed operation is missing its response.');
102
- const response = JSON.parse(operationState.responseJson);
103
- if (response.authoritative.entityId !== initiativeId) {
104
- throw new WorkspaceSyncIdempotencyConflictError();
105
- }
106
- const lifecycleMutation = response.authoritative.mutationKind === 'archive'
107
- || response.authoritative.mutationKind === 'unarchive';
106
+ const parsed = JSON.parse(operationState.responseJson);
107
+ const lifecycleMutation = parsed.authoritative.mutationKind === 'archive'
108
+ || parsed.authoritative.mutationKind === 'unarchive';
109
+ const replay = readDurableOperationReplay({
110
+ responseJson: operationState.responseJson,
111
+ operationId,
112
+ domain: 'initiative',
113
+ entityId: initiativeId,
114
+ mutationKind: parsed.authoritative.mutationKind,
115
+ revisionMode: lifecycleMutation ? 'both' : 'metadata',
116
+ });
117
+ const response = replay.response;
108
118
  return {
109
119
  revisions: {
110
- entityRevision: String(BigInt(response.authoritative.entityRevision) - 1n),
111
- lifecycleRevision: lifecycleMutation
112
- ? String(BigInt(response.authoritative.lifecycleRevision) - 1n)
113
- : response.authoritative.lifecycleRevision,
120
+ entityRevision: replay.baseEntityRevision,
121
+ lifecycleRevision: replay.baseLifecycleRevision,
114
122
  },
115
123
  persistedOutbox: null,
116
124
  committedResponse: response,
@@ -15,6 +15,20 @@ export declare class DurableOperationReplayIdentityConflictError extends Error {
15
15
  readonly code = "DURABLE_OPERATION_REPLAY_IDENTITY_CONFLICT";
16
16
  constructor(message?: string);
17
17
  }
18
+ export interface DurableOperationIdentityRecord {
19
+ operationId: string;
20
+ domain: string;
21
+ entityId: string;
22
+ mutationKind: string;
23
+ payloadFingerprint: string;
24
+ }
25
+ /**
26
+ * Canonical identity comparison for durable mutation records. Storage lanes may
27
+ * retain different reservation metadata, but an accepted operation can have
28
+ * only one exact domain/entity/mutation/payload meaning.
29
+ */
30
+ export declare function assertDurableOperationIdentity(actual: Readonly<DurableOperationIdentityRecord>, expected: Readonly<DurableOperationIdentityRecord>): void;
31
+ export declare function assertDurableOperationFingerprint(actual: string, expected: string): void;
18
32
  export interface DurableOperationReplayResult<Payload = unknown> {
19
33
  response: Readonly<Record<string, unknown>>;
20
34
  authoritative: DurableOperationAuthoritativeEntry<Payload>;
@@ -12,6 +12,24 @@ export class DurableOperationReplayIdentityConflictError extends Error {
12
12
  this.name = 'DurableOperationReplayIdentityConflictError';
13
13
  }
14
14
  }
15
+ /**
16
+ * Canonical identity comparison for durable mutation records. Storage lanes may
17
+ * retain different reservation metadata, but an accepted operation can have
18
+ * only one exact domain/entity/mutation/payload meaning.
19
+ */
20
+ export function assertDurableOperationIdentity(actual, expected) {
21
+ if (actual.operationId !== expected.operationId
22
+ || actual.domain !== expected.domain
23
+ || actual.entityId !== expected.entityId
24
+ || actual.mutationKind !== expected.mutationKind
25
+ || actual.payloadFingerprint !== expected.payloadFingerprint) {
26
+ throw new DurableOperationReplayIdentityConflictError();
27
+ }
28
+ }
29
+ export function assertDurableOperationFingerprint(actual, expected) {
30
+ if (!actual || actual !== expected)
31
+ throw new DurableOperationReplayIdentityConflictError();
32
+ }
15
33
  const DEFAULT_MAX_AUTHORITATIVE_ENTRIES = 1_024;
16
34
  const POSITIVE_REVISION = /^[1-9]\d*$/;
17
35
  const NON_NEGATIVE_REVISION = /^(0|[1-9]\d*)$/;
@@ -12,6 +12,7 @@ export declare function resolveTaskAttachmentLinksMutationCapability(input: {
12
12
  export type DurableTaskAttachmentLinksMutationRouterCore = DurableTaskAttachmentLinksServiceCore & LocalTaskAttachmentLinksOutboxCore & {
13
13
  getDatabaseAdapter(): DatabaseAdapter;
14
14
  getTask(id: string, workspaceId?: string): TaskItem | null;
15
+ assertTaskDetailRevisionForUpdate(id: string, expected: string, workspaceId?: string): void;
15
16
  };
16
17
  export declare class DurableTaskAttachmentLinksRouterDisabledError extends Error {
17
18
  readonly code = "WORKSPACE_SYNC_V3_TASK_ATTACHMENT_LINKS_ROUTER_DISABLED";
@@ -41,6 +42,7 @@ export declare function createDurableTaskAttachmentLinksMutationRouter(input: {
41
42
  taskId: string;
42
43
  links: readonly WorkspaceSyncV3TaskAttachmentLink[];
43
44
  cardCoverAssetId?: string | null;
45
+ expectedDetailRevision?: string;
44
46
  }): {
45
47
  state: "pending" | "committed";
46
48
  route: "local-outbox" | "cloud-acceptance";