@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
@@ -1,5 +1,5 @@
1
1
  import { createHash } from 'crypto';
2
- import { createLocalWorkspaceSyncPendingV2Push, decodeWorkspaceSyncPayload, fingerprintLocalWorkspaceSyncPreparedPlan, isLocalWorkspaceSyncPullFairnessDue, } from '../coordinator/localWorkspaceSyncRunnerState.js';
2
+ import { createLocalWorkspaceSyncPendingV2Push, decodeWorkspaceSyncPayload, fingerprintLocalWorkspaceSyncPreparedPlan, isLocalWorkspaceSyncPullFairnessDue, upgradeLocalWorkspaceSyncPendingV2PushSettlement, } from '../coordinator/localWorkspaceSyncRunnerState.js';
3
3
  import { isTransientWorkspaceSyncStatus, runWorkspacePullSyncService, runWorkspacePushSyncService, } from '../syncService.js';
4
4
  import { hydrateWorkspaceSyncV3AttachmentAsset } from '../v3/workspaceSyncV3AttachmentAssetHydration.js';
5
5
  import { runWorkspaceSyncV3CombinedProjectionCycle } from '../v3/workspaceSyncV3CombinedFeedOrchestrator.js';
@@ -527,6 +527,13 @@ export function createWorkspaceSyncEngineServerRunnerOperations(options) {
527
527
  forceAllAiProfiles: checkpoint.pendingV2Push.forceAllAiProfiles,
528
528
  repairMode: checkpoint.pendingV2Push.repairMode,
529
529
  };
530
+ if (checkpoint.pendingV2Push.preparedPlan
531
+ && checkpoint.pendingV2Push.settlementVersion !== 1) {
532
+ persist({
533
+ ...checkpoint,
534
+ pendingV2Push: upgradeLocalWorkspaceSyncPendingV2PushSettlement(checkpoint.pendingV2Push),
535
+ });
536
+ }
530
537
  }
531
538
  else {
532
539
  const forcedContentPaths = pushRetryKind === 'v2-content-push'
@@ -573,23 +580,26 @@ export function createWorkspaceSyncEngineServerRunnerOperations(options) {
573
580
  preparedPlan: checkpoint.pendingV2Push?.preparedPlan,
574
581
  acknowledgedNonApplyingBatchOperationIdentities: checkpoint.pendingV2Push
575
582
  ?.acknowledgedNonApplyingBatchOperationIdentities,
583
+ settledBatchOperationIdentities: checkpoint.pendingV2Push?.settledBatchOperationIdentities,
576
584
  onPreparedPlan: ({ plan, acknowledgedOperationIdentities, }) => {
577
585
  const pendingV2Push = checkpoint.pendingV2Push;
578
586
  if (!pendingV2Push) {
579
587
  throw new WorkspaceSyncEngineServerRunnerOperationError('The frozen V2 push disappeared while recording its prepared plan.', 'SYNC_RUNNER_PUSH_CHECKPOINT_INVALID');
580
588
  }
589
+ const preparedPendingV2Push = {
590
+ ...pendingV2Push,
591
+ preparedPlan: plan,
592
+ preparedPlanFingerprint: fingerprintLocalWorkspaceSyncPreparedPlan(plan),
593
+ acknowledgedNonApplyingBatchOperationIdentities: [
594
+ ...acknowledgedOperationIdentities,
595
+ ],
596
+ };
581
597
  persist({
582
598
  ...checkpoint,
583
- pendingV2Push: {
584
- ...pendingV2Push,
585
- preparedPlan: plan,
586
- preparedPlanFingerprint: fingerprintLocalWorkspaceSyncPreparedPlan(plan),
587
- acknowledgedNonApplyingBatchOperationIdentities: [
588
- ...acknowledgedOperationIdentities,
589
- ],
590
- },
599
+ pendingV2Push: upgradeLocalWorkspaceSyncPendingV2PushSettlement(preparedPendingV2Push),
591
600
  });
592
- persistedAcknowledgementCount = acknowledgedOperationIdentities.length;
601
+ persistedAcknowledgementCount =
602
+ acknowledgedOperationIdentities.length;
593
603
  },
594
604
  onNonApplyingBatchAcknowledged: ({ acknowledgedOperationIdentities }) => {
595
605
  const pendingV2Push = checkpoint.pendingV2Push;
@@ -609,8 +619,76 @@ export function createWorkspaceSyncEngineServerRunnerOperations(options) {
609
619
  - persistedAcknowledgementCount
610
620
  >= NON_APPLYING_ACKNOWLEDGEMENT_CHECKPOINT_INTERVAL) {
611
621
  persist(checkpoint);
612
- persistedAcknowledgementCount = acknowledgedOperationIdentities.length;
622
+ persistedAcknowledgementCount =
623
+ acknowledgedOperationIdentities.length;
624
+ }
625
+ },
626
+ onAcceptedBatchSettled: async ({ operationIdentity, settlementIdentityFingerprint, appliedTaskUpserts, transferReceipt, pushBoundary, excludedProjections, }) => {
627
+ const pendingV2Push = checkpoint.pendingV2Push;
628
+ if (!pendingV2Push
629
+ || pendingV2Push.settlementVersion !== 1
630
+ || !pendingV2Push.settledBatchOperationIdentities
631
+ || !pendingV2Push.settledBatchContributions) {
632
+ throw new WorkspaceSyncEngineServerRunnerOperationError('The frozen V2 push settlement checkpoint is unavailable.', 'SYNC_RUNNER_PUSH_CHECKPOINT_INVALID');
633
+ }
634
+ if (pendingV2Push.settledBatchOperationIdentities.includes(operationIdentity)) {
635
+ throw new WorkspaceSyncEngineServerRunnerOperationError('The accepted V2 push page was already settled locally.', 'SYNC_RUNNER_PUSH_CHECKPOINT_INVALID');
636
+ }
637
+ if (checkpoint.retry?.kind !== pushRetryKind) {
638
+ setRetry(pushRetryKind, 'Accepted V2 push page local settlement is pending.');
639
+ }
640
+ const completionGroup = options.remoteServices.buildV2PushApplyCompletionGroup({
641
+ workspaceId,
642
+ pushBoundary,
643
+ receipts: [transferReceipt],
644
+ });
645
+ if (!completionGroup) {
646
+ throw new WorkspaceSyncEngineServerRunnerOperationError('Accepted V2 push page is missing an atomic local apply completion group.', 'SYNC_RUNNER_PUSH_APPLY_COMPLETION_INVALID');
647
+ }
648
+ const nextCheckpoint = {
649
+ ...checkpoint,
650
+ pendingV2Push: {
651
+ ...checkpoint.pendingV2Push,
652
+ settledBatchOperationIdentities: [
653
+ ...checkpoint.pendingV2Push
654
+ .settledBatchOperationIdentities,
655
+ operationIdentity,
656
+ ],
657
+ settledBatchContributions: [
658
+ ...checkpoint.pendingV2Push
659
+ .settledBatchContributions,
660
+ {
661
+ operationIdentity,
662
+ settlementIdentityFingerprint,
663
+ appliedTaskUpserts: structuredClone(appliedTaskUpserts),
664
+ },
665
+ ],
666
+ },
667
+ };
668
+ const commitState = {};
669
+ const applyResult = await localServices.applyV2Batch(workspaceId, appliedTaskUpserts.map((entry) => ({
670
+ op: 'upsert',
671
+ archived: entry.archived === true,
672
+ task: entry.task,
673
+ ...(entry.durableRevision
674
+ ? { durableRevision: entry.durableRevision }
675
+ : {}),
676
+ })), {
677
+ repairMode: attemptOptions.repairMode,
678
+ excludedProjections,
679
+ completionGroup,
680
+ commitServerCheckpoint: () => {
681
+ const persisted = input.persistCheckpoint(nextCheckpoint);
682
+ commitState.checkpoint = structuredClone(persisted.checkpoint);
683
+ return commitState.checkpoint;
684
+ },
685
+ });
686
+ if (!applyResult.ok || !commitState.checkpoint) {
687
+ throw new WorkspaceSyncEngineServerRunnerOperationError(!applyResult.ok
688
+ ? authoritativeV2ApplyFailureMessage(applyResult)
689
+ : 'Accepted V2 push page did not commit its settlement checkpoint.', 'SYNC_RUNNER_PUSH_AUTHORITATIVE_APPLY_FAILED');
613
690
  }
691
+ checkpoint = structuredClone(commitState.checkpoint);
614
692
  },
615
693
  });
616
694
  onResult?.(result);
@@ -630,7 +708,19 @@ export function createWorkspaceSyncEngineServerRunnerOperations(options) {
630
708
  }
631
709
  fail(pushRetryKind, message, 'SYNC_RUNNER_PUSH_FAILED', result.retryAfterMs);
632
710
  }
633
- for (const entry of result.appliedTaskUpserts || []) {
711
+ const serviceTaskUpserts = result.appliedTaskUpserts || [];
712
+ const pushTransferReceipts = result.pushTransferReceipts || [];
713
+ const settledTaskUpserts = checkpoint.pendingV2Push
714
+ ?.settledBatchContributions
715
+ ?.flatMap((entry) => entry.appliedTaskUpserts) || [];
716
+ const terminalTaskUpserts = pushTransferReceipts.length > 0
717
+ ? serviceTaskUpserts
718
+ : [];
719
+ result.appliedTaskUpserts = [
720
+ ...settledTaskUpserts,
721
+ ...terminalTaskUpserts,
722
+ ];
723
+ for (const entry of result.appliedTaskUpserts) {
634
724
  const taskId = String(entry.task.id || '').trim();
635
725
  const watermark = String(entry.task.updatedAt || entry.task.createdAt || '').trim();
636
726
  if (!taskId || !watermark)
@@ -645,14 +735,6 @@ export function createWorkspaceSyncEngineServerRunnerOperations(options) {
645
735
  result,
646
736
  });
647
737
  const syncedAt = result.syncedAt || input.now;
648
- const appliedTaskUpserts = result.appliedTaskUpserts || [];
649
- const pushTransferReceipts = result.pushTransferReceipts || [];
650
- if (appliedTaskUpserts.length > 0) {
651
- // Persist the retry obligation before entering the atomic local
652
- // apply. If that transaction rolls back after its checkpoint
653
- // callback, the runner resumes from this durable revision.
654
- setRetry(pushRetryKind, 'Authoritative V2 push echo local commit is pending.');
655
- }
656
738
  const baseNextCheckpoint = {
657
739
  ...checkpoint,
658
740
  controlState: 'pushing',
@@ -666,10 +748,8 @@ export function createWorkspaceSyncEngineServerRunnerOperations(options) {
666
748
  const nextCheckpoint = transformTerminalCheckpoint
667
749
  ? transformTerminalCheckpoint(baseNextCheckpoint, result, signature)
668
750
  : baseNextCheckpoint;
669
- if (appliedTaskUpserts.length > 0) {
670
- const abandonPushReceipts = async (errorCode) => {
671
- if (pushTransferReceipts.length === 0)
672
- return;
751
+ if (terminalTaskUpserts.length > 0) {
752
+ const abandonTerminalReceipts = async (errorCode = 'WORKSPACE_SYNC_V2_PUSH_AUTHORITATIVE_APPLY_FAILED') => {
673
753
  try {
674
754
  await options.remoteServices.abandonTransferReceipts({
675
755
  workspaceId,
@@ -679,10 +759,9 @@ export function createWorkspaceSyncEngineServerRunnerOperations(options) {
679
759
  }
680
760
  catch {
681
761
  // The durable retry checkpoint remains authoritative.
682
- // The next exact replay will recover the retained or
683
- // ambiguous permit through the gateway.
684
762
  }
685
763
  };
764
+ setRetry(pushRetryKind, 'Authoritative V2 push echo local commit is pending.');
686
765
  const completionGroup = result.pushBoundary
687
766
  ? options.remoteServices.buildV2PushApplyCompletionGroup({
688
767
  workspaceId,
@@ -691,13 +770,13 @@ export function createWorkspaceSyncEngineServerRunnerOperations(options) {
691
770
  })
692
771
  : undefined;
693
772
  if (!completionGroup) {
694
- await abandonPushReceipts('WORKSPACE_SYNC_V2_PUSH_APPLY_COMPLETION_INVALID');
773
+ await abandonTerminalReceipts('WORKSPACE_SYNC_V2_PUSH_APPLY_COMPLETION_INVALID');
695
774
  throw new WorkspaceSyncEngineServerRunnerOperationError('Accepted V2 push echoes are missing an atomic local apply completion group.', 'SYNC_RUNNER_PUSH_APPLY_COMPLETION_INVALID');
696
775
  }
697
776
  const commitState = {};
698
777
  let applyResult;
699
778
  try {
700
- applyResult = await localServices.applyV2Batch(workspaceId, appliedTaskUpserts.map((entry) => ({
779
+ applyResult = await localServices.applyV2Batch(workspaceId, terminalTaskUpserts.map((entry) => ({
701
780
  op: 'upsert',
702
781
  archived: entry.archived === true,
703
782
  task: entry.task,
@@ -707,34 +786,29 @@ export function createWorkspaceSyncEngineServerRunnerOperations(options) {
707
786
  })), {
708
787
  repairMode: attemptOptions.repairMode,
709
788
  excludedProjections: result.effectiveV2ExcludedProjections,
710
- ...(completionGroup ? { completionGroup } : {}),
789
+ completionGroup,
711
790
  commitServerCheckpoint: () => {
712
791
  const persisted = input.persistCheckpoint(nextCheckpoint, {
713
792
  beforeCommit: beforeTerminalPersist
714
793
  ? () => beforeTerminalPersist(result)
715
794
  : undefined,
716
795
  });
717
- commitState.checkpoint =
718
- structuredClone(persisted.checkpoint);
796
+ commitState.checkpoint = structuredClone(persisted.checkpoint);
719
797
  return commitState.checkpoint;
720
798
  },
721
799
  });
722
800
  }
723
801
  catch (error) {
724
- await abandonPushReceipts('WORKSPACE_SYNC_V2_PUSH_AUTHORITATIVE_APPLY_FAILED');
802
+ await abandonTerminalReceipts();
725
803
  throw new WorkspaceSyncEngineServerRunnerOperationError(errorMessage(error, 'Authoritative V2 push echo apply failed.'), 'SYNC_RUNNER_PUSH_AUTHORITATIVE_APPLY_FAILED');
726
804
  }
727
805
  if (!applyResult.ok || !commitState.checkpoint) {
728
- await abandonPushReceipts('WORKSPACE_SYNC_V2_PUSH_AUTHORITATIVE_APPLY_FAILED');
806
+ await abandonTerminalReceipts();
729
807
  throw new WorkspaceSyncEngineServerRunnerOperationError(!applyResult.ok
730
808
  ? authoritativeV2ApplyFailureMessage(applyResult)
731
809
  : 'Authoritative V2 push echo did not commit the server checkpoint.', 'SYNC_RUNNER_PUSH_AUTHORITATIVE_APPLY_FAILED');
732
810
  }
733
- const committedCheckpoint = commitState.checkpoint;
734
- if (!committedCheckpoint) {
735
- throw new WorkspaceSyncEngineServerRunnerOperationError('The authoritative V2 push echo apply did not commit its runner checkpoint.', 'SYNC_RUNNER_PUSH_CHECKPOINT_NOT_COMMITTED');
736
- }
737
- checkpoint = structuredClone(committedCheckpoint);
811
+ checkpoint = structuredClone(commitState.checkpoint);
738
812
  }
739
813
  else {
740
814
  persist(nextCheckpoint, {
@@ -28,6 +28,7 @@ export function toWorkspaceSyncV2PushBaseline(snapshot, currentTaxonomyStateFing
28
28
  lastPushedInitiativeWatermarks: new Map(),
29
29
  lastPushedWorkstreamIds: new Set(),
30
30
  lastPushedWorkstreamWatermarks: new Map(),
31
+ lastPushedPlanningIdentityWatermarks: new Map(),
31
32
  lastPushedAiProfileIds: new Set(),
32
33
  lastPushedAiProfileWatermarks: new Map(),
33
34
  lastPushedAiProfileChangeKeys: new Map(),
@@ -57,6 +58,7 @@ export function toWorkspaceSyncV2PushBaseline(snapshot, currentTaxonomyStateFing
57
58
  || snapshot.taxonomyStateFingerprint === currentTaxonomyStateFingerprint;
58
59
  const initiativeWatermarks = stringMap(snapshot.initiativeWatermarks);
59
60
  const workstreamWatermarks = stringMap(snapshot.workstreamWatermarks);
61
+ const planningIdentityWatermarks = stringMap(snapshot.planningIdentityWatermarks);
60
62
  const aiProfileWatermarks = stringMap(snapshot.aiProfileWatermarks);
61
63
  const documentWatermarks = stringMap(snapshot.documentWatermarks);
62
64
  const assetWatermarks = stringMap(snapshot.assetWatermarks);
@@ -76,6 +78,7 @@ export function toWorkspaceSyncV2PushBaseline(snapshot, currentTaxonomyStateFing
76
78
  lastPushedInitiativeWatermarks: initiativeWatermarks,
77
79
  lastPushedWorkstreamIds: new Set(workstreamWatermarks.keys()),
78
80
  lastPushedWorkstreamWatermarks: workstreamWatermarks,
81
+ lastPushedPlanningIdentityWatermarks: planningIdentityWatermarks,
79
82
  lastPushedAiProfileIds: new Set(aiProfileWatermarks.keys()),
80
83
  lastPushedAiProfileWatermarks: aiProfileWatermarks,
81
84
  lastPushedAiProfileChangeKeys: stringMap(snapshot.aiProfileChangeKeys),
@@ -146,6 +149,9 @@ export function createWorkspaceSyncEngineServerPushCandidateProvider(snapshotRea
146
149
  taskRelationshipChangeKeys: sortedEntries(taskRelationshipChangeKeys),
147
150
  initiativeWatermarks: sortedEntries(result.currentInitiativeWatermarks),
148
151
  workstreamWatermarks: sortedEntries(result.currentWorkstreamWatermarks),
152
+ planningIdentityWatermarks: sortedEntries(result.currentPlanningIdentityWatermarks
153
+ || payload.currentPlanningIdentityWatermarks
154
+ || stringMap(previousBaseline?.planningIdentityWatermarks)),
149
155
  aiProfileWatermarks: sortedEntries(result.currentAiProfileWatermarks),
150
156
  aiProfileChangeKeys: sortedEntries(aiProfileChangeKeys),
151
157
  taskforceAgentWatermarks: sortedEntries(result.currentTaskforceAgentWatermarks),
@@ -173,7 +173,7 @@ export function createWorkspaceSyncV3TransferBindings(input) {
173
173
  };
174
174
  }
175
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 }) {
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, 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;
177
177
  const scheduledTasks = new Map();
178
178
  let disposed = false;
179
179
  const scheduleCoordinatorTask = (key, callback, delayMs) => {
@@ -467,6 +467,8 @@ export function createWorkspaceTransferCoordinator({ cloudAuthConfigured, runtim
467
467
  workspaceLastPushedInitiativeWatermarksRef.current = new Map(pushResult.currentInitiativeWatermarks);
468
468
  workspaceLastPushedWorkstreamIdsRef.current = new Set(pushResult.currentWorkstreamIds);
469
469
  workspaceLastPushedWorkstreamWatermarksRef.current = new Map(pushResult.currentWorkstreamWatermarks);
470
+ workspaceLastPushedPlanningIdentityWatermarksRef.current = new Map(pushResult.currentPlanningIdentityWatermarks
471
+ || payload.currentPlanningIdentityWatermarks);
470
472
  workspaceLastPushedAiProfileIdsRef.current = new Set(pushResult.currentAiProfileIds);
471
473
  workspaceLastPushedAiProfileWatermarksRef.current = new Map(pushResult.currentAiProfileWatermarks);
472
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,11 @@ 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
+ } : {}),
320
+ coexistenceDirection: options.coexistenceDirection,
307
321
  recordSyncDiagnostic,
308
322
  createSyncRouteError,
309
323
  });
@@ -633,6 +647,18 @@ export function createWorkspaceSyncV2ChangeDispatcher(dependencies) {
633
647
  sourceUpdatedAt: intent.sourceUpdatedAt,
634
648
  publishedAt: now().toISOString(),
635
649
  deletedAt: intent.sourceUpdatedAt,
650
+ // This dispatch path only ever runs from an explicit document-delete/
651
+ // asset-delete WorkspaceSyncChange (see workspaceSyncV2PreparedContent.ts)
652
+ // — never from workspace repair, which is intentionally routed to a
653
+ // durable retry obligation instead (see workspaceRepair.ts) rather than
654
+ // ever reaching this admission boundary. operationId/actorId are not yet
655
+ // threaded through the WorkspaceSyncChange wire format from origin to this
656
+ // layer — see the type's doc comment.
657
+ provenance: {
658
+ source: 'explicit-delete',
659
+ sourceRuntime: 'server',
660
+ repairInvolved: false,
661
+ },
636
662
  });
637
663
  if (tombstone.versionId !== null
638
664
  || tombstone.sourceUpdatedAt !== intent.sourceUpdatedAt
@@ -748,6 +774,11 @@ export function createWorkspaceSyncV2ChangeDispatcher(dependencies) {
748
774
  incomingAgentRoles: applyModel.collaboration.incomingAgentRoles,
749
775
  incomingTaskforceAgentSkills: applyModel.collaboration.incomingTaskforceAgentSkills,
750
776
  incomingAgentConversations: applyModel.collaboration.incomingAgentConversations,
777
+ ...(options.coexistenceDirection === 'cloud-push' ? {
778
+ taskforceAgentPushActorUserId: String(options.actorUserId || '').trim() || null,
779
+ taskforceAgentPushAccessPreflighted: true,
780
+ } : {}),
781
+ coexistenceDirection: options.coexistenceDirection,
751
782
  recordSyncDiagnostic,
752
783
  createSyncRouteError,
753
784
  });
@@ -255,6 +255,9 @@ 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;
260
+ coexistenceDirection?: 'local-pull' | 'cloud-push';
258
261
  recordSyncDiagnostic: RecordSyncDiagnostic;
259
262
  createSyncRouteError: CreateSyncRouteError;
260
263
  }): 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, coexistenceDirection, 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 {
@@ -1132,6 +1141,48 @@ export function applyCollaborationSyncChanges(input) {
1132
1141
  .digest('hex')
1133
1142
  : '';
1134
1143
  const metadataCompare = resolveSyncConflictOrdering(comment.updatedAt, String(existing?.updatedAt || '').trim(), incomingTieBreak, existingTieBreak);
1144
+ const parentCommentConflict = Boolean(existing
1145
+ && comment.parentCommentId !== undefined
1146
+ && comment.parentCommentId !== existing.parentCommentId);
1147
+ const nonThreadFieldsMatch = Boolean(existing
1148
+ && comment.sessionId === existing.sessionId
1149
+ && comment.body === existing.body
1150
+ && JSON.stringify(comment.anchor ?? null) === JSON.stringify(existing.anchor ?? null)
1151
+ && comment.order === existing.order
1152
+ && (comment.authorActorId ?? null) === (existing.authorActorId ?? null)
1153
+ && (comment.updatedByActorId ?? null) === (existing.updatedByActorId ?? null)
1154
+ && (comment.deletedByActorId ?? null) === (existing.deletedByActorId ?? null)
1155
+ && comment.createdAt === existing.createdAt
1156
+ && comment.updatedAt === existing.updatedAt
1157
+ && (comment.deletedAt ?? null) === (existing.deletedAt ?? null));
1158
+ const incomingIsLegacyProjectedRoot = Boolean(nonThreadFieldsMatch
1159
+ && comment.parentCommentId === null
1160
+ && comment.threadStatus === 'open'
1161
+ && comment.threadStatusUpdatedAt === comment.createdAt
1162
+ && !comment.resolvedAt
1163
+ && !comment.resolvedByActorId);
1164
+ const existingIsLegacyProjectedRoot = Boolean(nonThreadFieldsMatch
1165
+ && existing
1166
+ && existing.parentCommentId === null
1167
+ && existing.threadStatus === 'open'
1168
+ && existing.threadStatusUpdatedAt === existing.createdAt
1169
+ && !existing.resolvedAt
1170
+ && !existing.resolvedByActorId);
1171
+ const preserveLocalReplyParent = parentCommentConflict
1172
+ && coexistenceDirection === 'local-pull'
1173
+ && Boolean(existing?.parentCommentId)
1174
+ && incomingIsLegacyProjectedRoot;
1175
+ const reconcileAuthoritativeParent = parentCommentConflict
1176
+ && coexistenceDirection === 'local-pull'
1177
+ && !preserveLocalReplyParent;
1178
+ const reconcileLegacyCloudRoot = parentCommentConflict
1179
+ && coexistenceDirection === 'cloud-push'
1180
+ && existingIsLegacyProjectedRoot
1181
+ && Boolean(comment.parentCommentId);
1182
+ const applyIncomingMetadata = metadataCompare >= 0
1183
+ && !(parentCommentConflict
1184
+ && coexistenceDirection === 'cloud-push'
1185
+ && !reconcileLegacyCloudRoot);
1135
1186
  const incomingLifecycleTieBreak = createHash('sha256')
1136
1187
  .update(JSON.stringify({
1137
1188
  threadStatus: comment.threadStatus,
@@ -1151,28 +1202,43 @@ export function applyCollaborationSyncChanges(input) {
1151
1202
  const lifecycleCompare = comment.threadStatusUpdatedAt === undefined
1152
1203
  ? -1
1153
1204
  : resolveSyncConflictOrdering(String(comment.threadStatusUpdatedAt || '').trim(), String(existing?.threadStatusUpdatedAt || '').trim(), incomingLifecycleTieBreak, existingLifecycleTieBreak);
1154
- if (metadataCompare < 0 && lifecycleCompare < 0)
1205
+ if (metadataCompare < 0
1206
+ && lifecycleCompare < 0
1207
+ && !reconcileAuthoritativeParent
1208
+ && !reconcileLegacyCloudRoot)
1155
1209
  continue;
1156
- core.upsertDocumentReviewCommentForSync({
1210
+ const commentForSync = {
1157
1211
  id: comment.id,
1158
1212
  tenantId: core.getTenantId(),
1159
1213
  workspaceId,
1160
- sessionId: metadataCompare >= 0 ? comment.sessionId : existing.sessionId,
1161
- body: metadataCompare >= 0 ? comment.body : existing.body,
1162
- anchor: (metadataCompare >= 0 ? comment.anchor : existing.anchor),
1163
- order: metadataCompare >= 0 ? comment.order : existing.order,
1164
- authorActorId: metadataCompare >= 0 ? comment.authorActorId : existing.authorActorId,
1165
- updatedByActorId: metadataCompare >= 0 ? comment.updatedByActorId : existing.updatedByActorId,
1166
- deletedByActorId: metadataCompare >= 0 ? comment.deletedByActorId : existing.deletedByActorId,
1167
- parentCommentId: metadataCompare >= 0 ? comment.parentCommentId : existing.parentCommentId,
1214
+ sessionId: applyIncomingMetadata ? comment.sessionId : existing.sessionId,
1215
+ body: applyIncomingMetadata ? comment.body : existing.body,
1216
+ anchor: (applyIncomingMetadata ? comment.anchor : existing.anchor),
1217
+ order: applyIncomingMetadata ? comment.order : existing.order,
1218
+ authorActorId: applyIncomingMetadata ? comment.authorActorId : existing.authorActorId,
1219
+ updatedByActorId: applyIncomingMetadata ? comment.updatedByActorId : existing.updatedByActorId,
1220
+ deletedByActorId: applyIncomingMetadata ? comment.deletedByActorId : existing.deletedByActorId,
1221
+ parentCommentId: preserveLocalReplyParent
1222
+ ? existing.parentCommentId
1223
+ : reconcileAuthoritativeParent || reconcileLegacyCloudRoot || applyIncomingMetadata
1224
+ ? comment.parentCommentId
1225
+ : existing.parentCommentId,
1168
1226
  threadStatus: lifecycleCompare >= 0 ? comment.threadStatus : undefined,
1169
1227
  threadStatusUpdatedAt: lifecycleCompare >= 0 ? comment.threadStatusUpdatedAt : undefined,
1170
1228
  resolvedAt: lifecycleCompare >= 0 ? comment.resolvedAt : undefined,
1171
1229
  resolvedByActorId: lifecycleCompare >= 0 ? comment.resolvedByActorId : undefined,
1172
- createdAt: metadataCompare >= 0 ? comment.createdAt : existing.createdAt,
1173
- updatedAt: metadataCompare >= 0 ? comment.updatedAt : existing.updatedAt,
1174
- deletedAt: metadataCompare >= 0 ? comment.deletedAt : existing.deletedAt,
1175
- });
1230
+ createdAt: applyIncomingMetadata ? comment.createdAt : existing.createdAt,
1231
+ updatedAt: applyIncomingMetadata ? comment.updatedAt : existing.updatedAt,
1232
+ deletedAt: applyIncomingMetadata ? comment.deletedAt : existing.deletedAt,
1233
+ };
1234
+ if (reconcileAuthoritativeParent || reconcileLegacyCloudRoot) {
1235
+ core.upsertDocumentReviewCommentForSync(commentForSync, {
1236
+ allowAuthoritativeThreadReconciliation: true,
1237
+ });
1238
+ }
1239
+ else {
1240
+ core.upsertDocumentReviewCommentForSync(commentForSync);
1241
+ }
1176
1242
  if (comment.parentCommentId) {
1177
1243
  const rootExists = core.listDocumentReviewCommentsForSync({
1178
1244
  workspaceId,
@@ -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;
@@ -90,6 +104,7 @@ export interface WorkspacePushSyncResult {
90
104
  currentInitiativeWatermarks: Map<string, string>;
91
105
  currentWorkstreamIds: Set<string>;
92
106
  currentWorkstreamWatermarks: Map<string, string>;
107
+ currentPlanningIdentityWatermarks?: Map<string, string>;
93
108
  currentAiProfileIds: Set<string>;
94
109
  currentAiProfileWatermarks: Map<string, string>;
95
110
  currentAiProfileChangeKeys?: Map<string, string>;