From f94c91bac8c9132b1166262a89ea3c12f4414abc Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Tue, 28 Jul 2026 15:49:45 -0700 Subject: [PATCH 1/9] Add PropagatedNexusSerializationContext --- openapi/openapiv2.json | 44 +++++++++++++++++++ openapi/openapiv3.yaml | 38 ++++++++++++++++ temporal/api/activity/v1/message.proto | 3 ++ temporal/api/common/v1/message.proto | 10 +++++ temporal/api/update/v1/message.proto | 2 + temporal/api/workflow/v1/message.proto | 3 ++ .../workflowservice/v1/request_response.proto | 8 ++++ 7 files changed, 108 insertions(+) diff --git a/openapi/openapiv2.json b/openapi/openapiv2.json index 0b643ceb7..53246eee2 100644 --- a/openapi/openapiv2.json +++ b/openapi/openapiv2.json @@ -12634,6 +12634,10 @@ "startDelay": { "type": "string", "description": "Time to wait before making the first activity task available for dispatch. This delay is not applied to retry attempts." + }, + "propagatedNexusSerializationContext": { + "$ref": "#/definitions/v1PropagatedNexusSerializationContext", + "description": "Serialization context propagated from the Nexus caller that started this activity." } } }, @@ -12903,6 +12907,10 @@ "timeSkippingConfig": { "$ref": "#/definitions/v1TimeSkippingConfig", "description": "Time-skipping configuration. If not set, time skipping is disabled." + }, + "propagatedNexusSerializationContext": { + "$ref": "#/definitions/v1PropagatedNexusSerializationContext", + "description": "Serialization context propagated from the Nexus caller that started this workflow." } } }, @@ -13423,6 +13431,10 @@ "$ref": "#/definitions/apiCommonV1Link" }, "description": "Links to be associated with this update." + }, + "propagatedNexusSerializationContext": { + "$ref": "#/definitions/v1PropagatedNexusSerializationContext", + "description": "Serialization context propagated from the Nexus caller that started this update." } }, "description": "The request information that will be delivered all the way down to the\nWorkflow Execution." @@ -13908,6 +13920,10 @@ "type": "string", "format": "date-time", "description": "The time at which the first activity task is made available for dispatch, computed as\n`schedule_time + start_delay`. Same as `schedule_time` if `start_delay` is not set." + }, + "propagatedNexusSerializationContext": { + "$ref": "#/definitions/v1PropagatedNexusSerializationContext", + "description": "Serialization context propagated from the Nexus caller that started this activity." } }, "description": "Information about a standalone activity." @@ -18560,6 +18576,10 @@ "pollerGroupsInfo": { "$ref": "#/definitions/v1PollerGroupsInfo", "description": "The weighted, versioned list of poller groups IDs that client should use for future polls to\nthis task queue. Client should ignore this if it has already applied a snapshot with a\nversion greater than or equal to `poller_groups_info.version`. Client is expected to:\n 1. Maintain minimum number of pollers no less than the number of groups.\n 2. Try to assign the next poll to a group without any pending polls,\n 3. If every group has some pending polls, assign the next poll to a group randomly\n according to the weights." + }, + "propagatedNexusSerializationContext": { + "$ref": "#/definitions/v1PropagatedNexusSerializationContext", + "description": "Serialization context propagated from the Nexus caller that started this workflow." } } }, @@ -18675,6 +18695,22 @@ }, "description": "Priority contains metadata that controls relative ordering of task processing\nwhen tasks are backed up in a queue. Initially, Priority will be used in\nmatching (workflow and activity) task queues. Later it may be used in history\ntask queues and in rate limiting decisions.\n\nPriority is attached to workflows and activities. By default, activities\ninherit Priority from the workflow that created them, but may override fields\nwhen an activity is started or modified.\n\nDespite being named \"Priority\", this message also contains fields that\ncontrol \"fairness\" mechanisms.\n\nFor all fields, the field not present or equal to zero/empty string means to\ninherit the value from the calling workflow, or if there is no calling\nworkflow, then use the default value.\n\nFor all fields other than fairness_key, the zero value isn't meaningful so\nthere's no confusion between inherit/default and a meaningful value. For\nfairness_key, the empty string will be interpreted as \"inherit\". This means\nthat if a workflow has a non-empty fairness key, you can't override the\nfairness key of its activity to the empty string.\n\nThe overall semantics of Priority are:\n1. First, consider \"priority\": higher priority (lower number) goes first.\n2. Then, consider fairness: try to dispatch tasks for different fairness keys\n in proportion to their weight.\n\nApplications may use any subset of mechanisms that are useful to them and\nleave the other fields to use default values.\n\nNot all queues in the system may support the \"full\" semantics of all priority\nfields. (Currently only support in matching task queues is planned.)" }, + "v1PropagatedNexusSerializationContext": { + "type": "object", + "properties": { + "endpoint": { + "type": "string" + }, + "service": { + "type": "string" + }, + "operation": { + "type": "string", + "description": "If more context is needed, this message can be extended with additional fields." + } + }, + "description": "PropagatedNexusSerializationContext represents the context of the Nexus caller that started this entity.\nIf multiple Nexus callers attempt to attach to the same entity the server will verify that\neach field matches, if any field does not match then the request will be rejected." + }, "v1QueryRejectCondition": { "type": "string", "enum": [ @@ -18919,6 +18955,10 @@ "$ref": "#/definitions/v1Link" }, "description": "Links to be associated with this update." + }, + "propagatedNexusSerializationContext": { + "$ref": "#/definitions/v1PropagatedNexusSerializationContext", + "description": "Serialization context propagated from the Nexus caller that started this update." } }, "description": "The client request that triggers a Workflow Update." @@ -21649,6 +21689,10 @@ "timeSkippingInfo": { "$ref": "#/definitions/v1TimeSkippingInfo", "description": "Information about time skipping of the workflow execution.\nIf the execution has never enabled time skipping, it will be nil." + }, + "propagatedNexusSerializationContext": { + "$ref": "#/definitions/v1PropagatedNexusSerializationContext", + "description": "Serialization context propagated from the Nexus caller that started this workflow." } }, "description": "Holds all the extra information about workflow execution that is not part of Visibility." diff --git a/openapi/openapiv3.yaml b/openapi/openapiv3.yaml index 2aa7c45bf..864e746fd 100644 --- a/openapi/openapiv3.yaml +++ b/openapi/openapiv3.yaml @@ -9915,6 +9915,10 @@ components: The time at which the first activity task is made available for dispatch, computed as `schedule_time + start_delay`. Same as `schedule_time` if `start_delay` is not set. format: date-time + propagatedNexusSerializationContext: + allOf: + - $ref: '#/components/schemas/PropagatedNexusSerializationContext' + description: Serialization context propagated from the Nexus caller that started this activity. description: Information about a standalone activity. ActivityExecutionListInfo: type: object @@ -14853,6 +14857,10 @@ components: 2. Try to assign the next poll to a group without any pending polls, 3. If every group has some pending polls, assign the next poll to a group randomly according to the weights. + propagatedNexusSerializationContext: + allOf: + - $ref: '#/components/schemas/PropagatedNexusSerializationContext' + description: Serialization context propagated from the Nexus caller that started this workflow. PollerGroupInfo: type: object properties: @@ -15064,6 +15072,20 @@ components: Not all queues in the system may support the "full" semantics of all priority fields. (Currently only support in matching task queues is planned.) + PropagatedNexusSerializationContext: + type: object + properties: + endpoint: + type: string + service: + type: string + operation: + type: string + description: If more context is needed, this message can be extended with additional fields. + description: |- + PropagatedNexusSerializationContext represents the context of the Nexus caller that started this entity. + If multiple Nexus callers attempt to attach to the same entity the server will verify that + each field matches, if any field does not match then the request will be rejected. QueryRejected: type: object properties: @@ -15330,6 +15352,10 @@ components: items: $ref: '#/components/schemas/Link' description: Links to be associated with this update. + propagatedNexusSerializationContext: + allOf: + - $ref: '#/components/schemas/PropagatedNexusSerializationContext' + description: Serialization context propagated from the Nexus caller that started this update. description: The client request that triggers a Workflow Update. RequestCancelActivityExecutionRequest: type: object @@ -17124,6 +17150,10 @@ components: pattern: ^-?(?:0|[1-9][0-9]{0,11})(?:\.[0-9]{1,9})?s$ type: string description: Time to wait before making the first activity task available for dispatch. This delay is not applied to retry attempts. + propagatedNexusSerializationContext: + allOf: + - $ref: '#/components/schemas/PropagatedNexusSerializationContext' + description: Serialization context propagated from the Nexus caller that started this activity. StartActivityExecutionResponse: type: object properties: @@ -17601,6 +17631,10 @@ components: allOf: - $ref: '#/components/schemas/TimeSkippingConfig' description: Time-skipping configuration. If not set, time skipping is disabled. + propagatedNexusSerializationContext: + allOf: + - $ref: '#/components/schemas/PropagatedNexusSerializationContext' + description: Serialization context propagated from the Nexus caller that started this workflow. StartWorkflowExecutionResponse: type: object properties: @@ -20090,6 +20124,10 @@ components: description: |- Information about time skipping of the workflow execution. If the execution has never enabled time skipping, it will be nil. + propagatedNexusSerializationContext: + allOf: + - $ref: '#/components/schemas/PropagatedNexusSerializationContext' + description: Serialization context propagated from the Nexus caller that started this workflow. description: Holds all the extra information about workflow execution that is not part of Visibility. WorkflowExecutionFailedEventAttributes: type: object diff --git a/temporal/api/activity/v1/message.proto b/temporal/api/activity/v1/message.proto index e3852aa9f..bcb1d1977 100644 --- a/temporal/api/activity/v1/message.proto +++ b/temporal/api/activity/v1/message.proto @@ -195,6 +195,9 @@ message ActivityExecutionInfo { // The time at which the first activity task is made available for dispatch, computed as // `schedule_time + start_delay`. Same as `schedule_time` if `start_delay` is not set. google.protobuf.Timestamp execution_time = 38; + + // Serialization context propagated from the Nexus caller that started this activity. + temporal.api.common.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 39; } // Limited activity information returned in the list response. diff --git a/temporal/api/common/v1/message.proto b/temporal/api/common/v1/message.proto index 908c5c80b..1a06aa3dc 100644 --- a/temporal/api/common/v1/message.proto +++ b/temporal/api/common/v1/message.proto @@ -60,6 +60,16 @@ message Header { map fields = 1; } +// PropagatedNexusSerializationContext represents the context of the Nexus caller that started this entity. +// If multiple Nexus callers attempt to attach to the same entity the server will verify that +// each field matches, if any field does not match then the request will be rejected. +message PropagatedNexusSerializationContext { + string endpoint = 1; + string service = 2; + // If more context is needed, this message can be extended with additional fields. + string operation = 3; +} + // Identifies a specific workflow within a namespace. Practically speaking, because run_id is a // uuid, a workflow execution is globally unique. Note that many commands allow specifying an empty // run id as a way of saying "target the latest run of the workflow". diff --git a/temporal/api/update/v1/message.proto b/temporal/api/update/v1/message.proto index 76c46d47d..e1b77ba2a 100644 --- a/temporal/api/update/v1/message.proto +++ b/temporal/api/update/v1/message.proto @@ -68,6 +68,8 @@ message Request { repeated temporal.api.common.v1.Callback completion_callbacks = 4; // Links to be associated with this update. repeated temporal.api.common.v1.Link links = 5; + // Serialization context propagated from the Nexus caller that started this update. + temporal.api.common.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 6; } // An Update protocol message indicating that a Workflow Update has been rejected. diff --git a/temporal/api/workflow/v1/message.proto b/temporal/api/workflow/v1/message.proto index cf763aa12..1d00ae15e 100644 --- a/temporal/api/workflow/v1/message.proto +++ b/temporal/api/workflow/v1/message.proto @@ -138,6 +138,9 @@ message WorkflowExecutionExtendedInfo { // Information about time skipping of the workflow execution. // If the execution has never enabled time skipping, it will be nil. temporal.api.common.v1.TimeSkippingInfo time_skipping_info = 9; + + // Serialization context propagated from the Nexus caller that started this workflow. + temporal.api.common.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 10; } // Holds all the information about worker versioning for a particular workflow execution. diff --git a/temporal/api/workflowservice/v1/request_response.proto b/temporal/api/workflowservice/v1/request_response.proto index 1aae988d8..9c47c35e6 100644 --- a/temporal/api/workflowservice/v1/request_response.proto +++ b/temporal/api/workflowservice/v1/request_response.proto @@ -219,6 +219,8 @@ message StartWorkflowExecutionRequest { // Time-skipping configuration. If not set, time skipping is disabled. temporal.api.common.v1.TimeSkippingConfig time_skipping_config = 29; + // Serialization context propagated from the Nexus caller that started this workflow. + temporal.api.common.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 30; } message StartWorkflowExecutionResponse { @@ -384,6 +386,8 @@ message PollWorkflowTaskQueueResponse { // 3. If every group has some pending polls, assign the next poll to a group randomly // according to the weights. temporal.api.taskqueue.v1.PollerGroupsInfo poller_groups_info = 19; + // Serialization context propagated from the Nexus caller that started this workflow. + temporal.api.common.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 20; } message RespondWorkflowTaskCompletedRequest { @@ -612,6 +616,8 @@ message PollActivityTaskQueueResponse { // 3. If every group has some pending polls, assign the next poll to a group randomly // according to the weights. temporal.api.taskqueue.v1.PollerGroupsInfo poller_groups_info = 22; + // Serialization context propagated from the Nexus caller that started this activity. + temporal.api.common.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 23; } message RecordActivityTaskHeartbeatRequest { @@ -3270,6 +3276,8 @@ message StartActivityExecutionRequest { temporal.api.common.v1.OnConflictOptions on_conflict_options = 21; // Time to wait before making the first activity task available for dispatch. This delay is not applied to retry attempts. google.protobuf.Duration start_delay = 22; + // Serialization context propagated from the Nexus caller that started this activity. + temporal.api.common.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 23; } message StartActivityExecutionResponse { From a346436621720358adac095dc9fc4638cd9471cc Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Wed, 29 Jul 2026 11:17:45 -0700 Subject: [PATCH 2/9] Preserve Nexus serialization context in workflow history Record the context on the workflow started event so mutable-state rebuilds and resets restore it through normal replay. Constraint: Reset rebuilds mutable state from history. Rejected: Copy context directly in workflow resetter | bypasses standard event reconstruction. Confidence: high Scope-risk: moderate Tested: make buf-lint api-linter go-grpc fix-path Not-tested: make grpc (blocked by pre-existing WorkerHeartbeat.environment breaking-change failure) --- temporal/api/history/v1/message.proto | 2 ++ 1 file changed, 2 insertions(+) diff --git a/temporal/api/history/v1/message.proto b/temporal/api/history/v1/message.proto index b40324d68..09047756f 100644 --- a/temporal/api/history/v1/message.proto +++ b/temporal/api/history/v1/message.proto @@ -213,6 +213,8 @@ message WorkflowExecutionStartedEventAttributes { // if no time skipping has occurred or there is no previous run. temporal.api.common.v1.TimeSkippingStatePropagation time_skipping_state_propagation = 43; + // Serialization context propagated from the Nexus caller that started this workflow. + temporal.api.common.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 44; } From e9b1f18eecff96b324318062499d3a44b978967f Mon Sep 17 00:00:00 2001 From: Joshua Frenchwood Date: Tue, 29 Sep 2026 14:15:28 -0500 Subject: [PATCH 3/9] Regenerate OpenAPI for Nexus serialization context in history --- openapi/openapiv2.json | 4 ++++ openapi/openapiv3.yaml | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/openapi/openapiv2.json b/openapi/openapiv2.json index 53246eee2..36918f352 100644 --- a/openapi/openapiv2.json +++ b/openapi/openapiv2.json @@ -22120,6 +22120,10 @@ "timeSkippingStatePropagation": { "$ref": "#/definitions/v1TimeSkippingStatePropagation", "description": "The time-skipping state propagated from a previous run of this workflow. This can be nil\nif no time skipping has occurred or there is no previous run." + }, + "propagatedNexusSerializationContext": { + "$ref": "#/definitions/v1PropagatedNexusSerializationContext", + "description": "Serialization context propagated from the Nexus caller that started this workflow." } }, "title": "Always the first event in workflow history" diff --git a/openapi/openapiv3.yaml b/openapi/openapiv3.yaml index 864e746fd..64ba4522a 100644 --- a/openapi/openapiv3.yaml +++ b/openapi/openapiv3.yaml @@ -20672,6 +20672,10 @@ components: description: |- The time-skipping state propagated from a previous run of this workflow. This can be nil if no time skipping has occurred or there is no previous run. + propagatedNexusSerializationContext: + allOf: + - $ref: '#/components/schemas/PropagatedNexusSerializationContext' + description: Serialization context propagated from the Nexus caller that started this workflow. description: Always the first event in workflow history WorkflowExecutionTerminatedEventAttributes: type: object From 8bd11b2f9d8fab3fda8f55f23e00ff7677237021 Mon Sep 17 00:00:00 2001 From: Joshua Frenchwood Date: Tue, 29 Sep 2026 16:28:54 -0500 Subject: [PATCH 4/9] Updating NexusSerializationContext description --- openapi/openapiv2.json | 5 ++--- openapi/openapiv3.yaml | 5 ++--- temporal/api/common/v1/message.proto | 5 ++--- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/openapi/openapiv2.json b/openapi/openapiv2.json index 36918f352..b3ed5e090 100644 --- a/openapi/openapiv2.json +++ b/openapi/openapiv2.json @@ -18705,11 +18705,10 @@ "type": "string" }, "operation": { - "type": "string", - "description": "If more context is needed, this message can be extended with additional fields." + "type": "string" } }, - "description": "PropagatedNexusSerializationContext represents the context of the Nexus caller that started this entity.\nIf multiple Nexus callers attempt to attach to the same entity the server will verify that\neach field matches, if any field does not match then the request will be rejected." + "description": "PropagatedNexusSerializationContext represents the context of the Nexus caller that started this execution.\nIf multiple Nexus callers attempt to attach to the same execution the server will verify that\neach field matches, if any field does not match then the request will be rejected." }, "v1QueryRejectCondition": { "type": "string", diff --git a/openapi/openapiv3.yaml b/openapi/openapiv3.yaml index 64ba4522a..3f17142d5 100644 --- a/openapi/openapiv3.yaml +++ b/openapi/openapiv3.yaml @@ -15081,10 +15081,9 @@ components: type: string operation: type: string - description: If more context is needed, this message can be extended with additional fields. description: |- - PropagatedNexusSerializationContext represents the context of the Nexus caller that started this entity. - If multiple Nexus callers attempt to attach to the same entity the server will verify that + PropagatedNexusSerializationContext represents the context of the Nexus caller that started this execution. + If multiple Nexus callers attempt to attach to the same execution the server will verify that each field matches, if any field does not match then the request will be rejected. QueryRejected: type: object diff --git a/temporal/api/common/v1/message.proto b/temporal/api/common/v1/message.proto index 1a06aa3dc..705682760 100644 --- a/temporal/api/common/v1/message.proto +++ b/temporal/api/common/v1/message.proto @@ -60,13 +60,12 @@ message Header { map fields = 1; } -// PropagatedNexusSerializationContext represents the context of the Nexus caller that started this entity. -// If multiple Nexus callers attempt to attach to the same entity the server will verify that +// PropagatedNexusSerializationContext represents the context of the Nexus caller that started this execution. +// If multiple Nexus callers attempt to attach to the same execution the server will verify that // each field matches, if any field does not match then the request will be rejected. message PropagatedNexusSerializationContext { string endpoint = 1; string service = 2; - // If more context is needed, this message can be extended with additional fields. string operation = 3; } From 1a2dfad63e20ee20901ad9354330b7121b535f75 Mon Sep 17 00:00:00 2001 From: Joshua Frenchwood Date: Tue, 29 Sep 2026 16:51:00 -0500 Subject: [PATCH 5/9] Updating nexusserializationcontext conflicting behavior --- openapi/openapiv2.json | 4 ++-- openapi/openapiv3.yaml | 9 ++++++--- temporal/api/common/v1/message.proto | 4 ++-- temporal/api/workflowservice/v1/request_response.proto | 2 ++ 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/openapi/openapiv2.json b/openapi/openapiv2.json index b3ed5e090..fd89dde95 100644 --- a/openapi/openapiv2.json +++ b/openapi/openapiv2.json @@ -12910,7 +12910,7 @@ }, "propagatedNexusSerializationContext": { "$ref": "#/definitions/v1PropagatedNexusSerializationContext", - "description": "Serialization context propagated from the Nexus caller that started this workflow." + "description": "Serialization context propagated from the Nexus caller that started this workflow.\nWith WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING, this must match the existing execution's\ncontext because all attached completion callbacks receive the same encoded outcome." } } }, @@ -18708,7 +18708,7 @@ "type": "string" } }, - "description": "PropagatedNexusSerializationContext represents the context of the Nexus caller that started this execution.\nIf multiple Nexus callers attempt to attach to the same execution the server will verify that\neach field matches, if any field does not match then the request will be rejected." + "description": "PropagatedNexusSerializationContext represents the context of the Nexus caller that started this execution.\nNexus callers can share a workflow or standalone activity with USE_EXISTING only when their\nendpoint, service, and operation match. A request with a different context is rejected." }, "v1QueryRejectCondition": { "type": "string", diff --git a/openapi/openapiv3.yaml b/openapi/openapiv3.yaml index 3f17142d5..c2810499a 100644 --- a/openapi/openapiv3.yaml +++ b/openapi/openapiv3.yaml @@ -15083,8 +15083,8 @@ components: type: string description: |- PropagatedNexusSerializationContext represents the context of the Nexus caller that started this execution. - If multiple Nexus callers attempt to attach to the same execution the server will verify that - each field matches, if any field does not match then the request will be rejected. + Nexus callers can share a workflow or standalone activity with USE_EXISTING only when their + endpoint, service, and operation match. A request with a different context is rejected. QueryRejected: type: object properties: @@ -17633,7 +17633,10 @@ components: propagatedNexusSerializationContext: allOf: - $ref: '#/components/schemas/PropagatedNexusSerializationContext' - description: Serialization context propagated from the Nexus caller that started this workflow. + description: |- + Serialization context propagated from the Nexus caller that started this workflow. + With WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING, this must match the existing execution's + context because all attached completion callbacks receive the same encoded outcome. StartWorkflowExecutionResponse: type: object properties: diff --git a/temporal/api/common/v1/message.proto b/temporal/api/common/v1/message.proto index 705682760..08322e1bc 100644 --- a/temporal/api/common/v1/message.proto +++ b/temporal/api/common/v1/message.proto @@ -61,8 +61,8 @@ message Header { } // PropagatedNexusSerializationContext represents the context of the Nexus caller that started this execution. -// If multiple Nexus callers attempt to attach to the same execution the server will verify that -// each field matches, if any field does not match then the request will be rejected. +// Nexus callers can share a workflow or standalone activity with USE_EXISTING only when their +// endpoint, service, and operation match. A request with a different context is rejected. message PropagatedNexusSerializationContext { string endpoint = 1; string service = 2; diff --git a/temporal/api/workflowservice/v1/request_response.proto b/temporal/api/workflowservice/v1/request_response.proto index 9c47c35e6..ffb9fff81 100644 --- a/temporal/api/workflowservice/v1/request_response.proto +++ b/temporal/api/workflowservice/v1/request_response.proto @@ -220,6 +220,8 @@ message StartWorkflowExecutionRequest { // Time-skipping configuration. If not set, time skipping is disabled. temporal.api.common.v1.TimeSkippingConfig time_skipping_config = 29; // Serialization context propagated from the Nexus caller that started this workflow. + // With WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING, this must match the existing execution's + // context because all attached completion callbacks receive the same encoded outcome. temporal.api.common.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 30; } From 3d67825e518d633dee457a94c9f8bdc5445641df Mon Sep 17 00:00:00 2001 From: Joshua Frenchwood Date: Wed, 30 Sep 2026 12:20:04 -0500 Subject: [PATCH 6/9] Moving PropagatedNexusSerializationContext to nexus package --- openapi/openapiv3.yaml | 119 ++++++++++++------ temporal/api/activity/v1/message.proto | 3 +- temporal/api/common/v1/message.proto | 9 -- temporal/api/history/v1/message.proto | 3 +- temporal/api/nexus/v1/message.proto | 9 ++ temporal/api/update/v1/message.proto | 3 +- temporal/api/workflow/v1/message.proto | 3 +- .../workflowservice/v1/request_response.proto | 8 +- 8 files changed, 103 insertions(+), 54 deletions(-) diff --git a/openapi/openapiv3.yaml b/openapi/openapiv3.yaml index c2810499a..9a857af9e 100644 --- a/openapi/openapiv3.yaml +++ b/openapi/openapiv3.yaml @@ -10952,6 +10952,25 @@ components: NexusHandler callbacks are only supported for certain types of operations, e.g. standalone Nexus operations. Attempting to attach a Worker callback for an unsupported operation will result in an INVALID_ARGUMENT error from the server. + CancelOperationRequest: + type: object + properties: + service: + type: string + description: Service name. + operation: + type: string + description: Type of operation to cancel. + operationId: + type: string + description: |- + Operation ID as originally generated by a Handler. + + Deprecated. Renamed to operation_token. + operationToken: + type: string + description: Operation token as originally generated by a Handler. + description: A request to cancel an operation. CanceledFailureInfo: type: object properties: @@ -13082,22 +13101,6 @@ components: Used as part of WorkflowExecutionStartedEventAttributes to pass down the AutoUpgrade behavior and source deployment version to a workflow execution whose parent/previous workflow has an AutoUpgrade behavior. Also used for Upgrade-on-CaN behaviors AutoUpgrade and UseRampingVersion. - Input: - type: object - properties: - header: - allOf: - - $ref: '#/components/schemas/Header' - description: |- - Headers that are passed with the Update from the requesting entity. - These can include things like auth or tracing tokens. - name: - type: string - description: The name of the Update handler to invoke on the target Workflow. - args: - allOf: - - $ref: '#/components/schemas/Payloads' - description: The arguments to pass to the named Update handler. IntervalSpec: type: object properties: @@ -15334,28 +15337,32 @@ components: Request: type: object properties: - meta: - $ref: '#/components/schemas/Meta' - input: - $ref: '#/components/schemas/Input' - requestId: + header: + type: object + additionalProperties: + type: string + description: |- + Headers extracted from the original request in the Temporal frontend. + When using Nexus over HTTP, this includes the request's HTTP headers ignoring multiple values. + scheduledTime: type: string - description: The request ID of the request. - completionCallbacks: - type: array - items: - $ref: '#/components/schemas/Callback' - description: Callbacks to be called by the server when this update reaches a terminal state. - links: - type: array - items: - $ref: '#/components/schemas/Link' - description: Links to be associated with this update. - propagatedNexusSerializationContext: - allOf: - - $ref: '#/components/schemas/PropagatedNexusSerializationContext' - description: Serialization context propagated from the Nexus caller that started this update. - description: The client request that triggers a Workflow Update. + description: |- + The timestamp when the request was scheduled in the frontend. + (-- api-linter: core::0142::time-field-names=disabled + aip.dev/not-precedent: Not following linter rules. --) + format: date-time + capabilities: + $ref: '#/components/schemas/Request_Capabilities' + startOperation: + $ref: '#/components/schemas/StartOperationRequest' + cancelOperation: + $ref: '#/components/schemas/CancelOperationRequest' + endpoint: + type: string + description: |- + The endpoint this request was addressed to before forwarding to the worker. + Supported from server version 1.30.0. + description: A Nexus request. RequestCancelActivityExecutionRequest: type: object properties: @@ -15569,6 +15576,14 @@ components: Indicate if the request is still buffered. If so, the event ID is not known and its value will be an invalid event ID. description: RequestIdInfo contains details of a request ID. + Request_Capabilities: + type: object + properties: + temporalFailureResponses: + type: boolean + description: |- + If set, handlers may use temporal.api.failure.v1.Failure instances to return failures to the server. + This also allows handler and operation errors to have their own messages and stack traces. ResetActivityExecutionRequest: type: object properties: @@ -17487,6 +17502,36 @@ components: started: type: boolean description: If true, a new operation was started. + StartOperationRequest: + type: object + properties: + service: + type: string + description: Name of service to start the operation in. + operation: + type: string + description: Type of operation to start. + requestId: + type: string + description: A request ID that can be used as an idempotentency key. + callback: + type: string + description: Callback URL to call upon completion if the started operation is async. + payload: + allOf: + - $ref: '#/components/schemas/Payload' + description: Full request body from the incoming HTTP request. + callbackHeader: + type: object + additionalProperties: + type: string + description: Header that is expected to be attached to the callback request when the operation completes. + links: + type: array + items: + $ref: '#/components/schemas/Link' + description: Links contain caller information and can be attached to the operations started by the handler. + description: A request to start an operation. StartWorkflowExecutionRequest: type: object properties: diff --git a/temporal/api/activity/v1/message.proto b/temporal/api/activity/v1/message.proto index bcb1d1977..a0bb66c18 100644 --- a/temporal/api/activity/v1/message.proto +++ b/temporal/api/activity/v1/message.proto @@ -18,6 +18,7 @@ import "temporal/api/enums/v1/activity.proto"; import "temporal/api/callback/v1/message.proto"; import "temporal/api/enums/v1/workflow.proto"; import "temporal/api/failure/v1/message.proto"; +import "temporal/api/nexus/v1/message.proto"; import "temporal/api/taskqueue/v1/message.proto"; import "temporal/api/sdk/v1/user_metadata.proto"; @@ -197,7 +198,7 @@ message ActivityExecutionInfo { google.protobuf.Timestamp execution_time = 38; // Serialization context propagated from the Nexus caller that started this activity. - temporal.api.common.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 39; + temporal.api.nexus.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 39; } // Limited activity information returned in the list response. diff --git a/temporal/api/common/v1/message.proto b/temporal/api/common/v1/message.proto index 08322e1bc..908c5c80b 100644 --- a/temporal/api/common/v1/message.proto +++ b/temporal/api/common/v1/message.proto @@ -60,15 +60,6 @@ message Header { map fields = 1; } -// PropagatedNexusSerializationContext represents the context of the Nexus caller that started this execution. -// Nexus callers can share a workflow or standalone activity with USE_EXISTING only when their -// endpoint, service, and operation match. A request with a different context is rejected. -message PropagatedNexusSerializationContext { - string endpoint = 1; - string service = 2; - string operation = 3; -} - // Identifies a specific workflow within a namespace. Practically speaking, because run_id is a // uuid, a workflow execution is globally unique. Note that many commands allow specifying an empty // run id as a way of saying "target the latest run of the workflow". diff --git a/temporal/api/history/v1/message.proto b/temporal/api/history/v1/message.proto index 09047756f..bec532db5 100644 --- a/temporal/api/history/v1/message.proto +++ b/temporal/api/history/v1/message.proto @@ -19,6 +19,7 @@ import "temporal/api/enums/v1/workflow.proto"; import "temporal/api/common/v1/message.proto"; import "temporal/api/deployment/v1/message.proto"; import "temporal/api/failure/v1/message.proto"; +import "temporal/api/nexus/v1/message.proto"; import "temporal/api/taskqueue/v1/message.proto"; import "temporal/api/update/v1/message.proto"; import "temporal/api/workflow/v1/message.proto"; @@ -214,7 +215,7 @@ message WorkflowExecutionStartedEventAttributes { temporal.api.common.v1.TimeSkippingStatePropagation time_skipping_state_propagation = 43; // Serialization context propagated from the Nexus caller that started this workflow. - temporal.api.common.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 44; + temporal.api.nexus.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 44; } diff --git a/temporal/api/nexus/v1/message.proto b/temporal/api/nexus/v1/message.proto index a4e400c29..ea49b230a 100644 --- a/temporal/api/nexus/v1/message.proto +++ b/temporal/api/nexus/v1/message.proto @@ -17,6 +17,15 @@ import "temporal/api/enums/v1/nexus.proto"; import "temporal/api/failure/v1/message.proto"; import "temporal/api/sdk/v1/user_metadata.proto"; +// PropagatedNexusSerializationContext represents the context of the Nexus caller that started this execution. +// Nexus callers can share a workflow or standalone activity with USE_EXISTING only when their +// endpoint, service, and operation match. A request with a different context is rejected. +message PropagatedNexusSerializationContext { + string endpoint = 1; + string service = 2; + string operation = 3; +} + // A general purpose failure message. // See: https://github.com/nexus-rpc/api/blob/main/SPEC.md#failure message Failure { diff --git a/temporal/api/update/v1/message.proto b/temporal/api/update/v1/message.proto index e1b77ba2a..1178cb392 100644 --- a/temporal/api/update/v1/message.proto +++ b/temporal/api/update/v1/message.proto @@ -12,6 +12,7 @@ option csharp_namespace = "Temporalio.Api.Update.V1"; import "temporal/api/common/v1/message.proto"; import "temporal/api/enums/v1/update.proto"; import "temporal/api/failure/v1/message.proto"; +import "temporal/api/nexus/v1/message.proto"; // Specifies client's intent to wait for Update results. message WaitPolicy { @@ -69,7 +70,7 @@ message Request { // Links to be associated with this update. repeated temporal.api.common.v1.Link links = 5; // Serialization context propagated from the Nexus caller that started this update. - temporal.api.common.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 6; + temporal.api.nexus.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 6; } // An Update protocol message indicating that a Workflow Update has been rejected. diff --git a/temporal/api/workflow/v1/message.proto b/temporal/api/workflow/v1/message.proto index 1d00ae15e..6308ec807 100644 --- a/temporal/api/workflow/v1/message.proto +++ b/temporal/api/workflow/v1/message.proto @@ -21,6 +21,7 @@ import "temporal/api/enums/v1/workflow.proto"; import "temporal/api/common/v1/message.proto"; import "temporal/api/deployment/v1/message.proto"; import "temporal/api/failure/v1/message.proto"; +import "temporal/api/nexus/v1/message.proto"; import "temporal/api/taskqueue/v1/message.proto"; import "temporal/api/sdk/v1/user_metadata.proto"; @@ -140,7 +141,7 @@ message WorkflowExecutionExtendedInfo { temporal.api.common.v1.TimeSkippingInfo time_skipping_info = 9; // Serialization context propagated from the Nexus caller that started this workflow. - temporal.api.common.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 10; + temporal.api.nexus.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 10; } // Holds all the information about worker versioning for a particular workflow execution. diff --git a/temporal/api/workflowservice/v1/request_response.proto b/temporal/api/workflowservice/v1/request_response.proto index ffb9fff81..d1c829123 100644 --- a/temporal/api/workflowservice/v1/request_response.proto +++ b/temporal/api/workflowservice/v1/request_response.proto @@ -222,7 +222,7 @@ message StartWorkflowExecutionRequest { // Serialization context propagated from the Nexus caller that started this workflow. // With WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING, this must match the existing execution's // context because all attached completion callbacks receive the same encoded outcome. - temporal.api.common.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 30; + temporal.api.nexus.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 30; } message StartWorkflowExecutionResponse { @@ -389,7 +389,7 @@ message PollWorkflowTaskQueueResponse { // according to the weights. temporal.api.taskqueue.v1.PollerGroupsInfo poller_groups_info = 19; // Serialization context propagated from the Nexus caller that started this workflow. - temporal.api.common.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 20; + temporal.api.nexus.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 20; } message RespondWorkflowTaskCompletedRequest { @@ -619,7 +619,7 @@ message PollActivityTaskQueueResponse { // according to the weights. temporal.api.taskqueue.v1.PollerGroupsInfo poller_groups_info = 22; // Serialization context propagated from the Nexus caller that started this activity. - temporal.api.common.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 23; + temporal.api.nexus.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 23; } message RecordActivityTaskHeartbeatRequest { @@ -3279,7 +3279,7 @@ message StartActivityExecutionRequest { // Time to wait before making the first activity task available for dispatch. This delay is not applied to retry attempts. google.protobuf.Duration start_delay = 22; // Serialization context propagated from the Nexus caller that started this activity. - temporal.api.common.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 23; + temporal.api.nexus.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 23; } message StartActivityExecutionResponse { From dc038ff3039f32a3d3d2b49820d2f79de8a56ba7 Mon Sep 17 00:00:00 2001 From: Joshua Frenchwood Date: Wed, 30 Sep 2026 14:30:49 -0500 Subject: [PATCH 7/9] Adding nexus context to nexusoperation poll response --- openapi/openapiv2.json | 4 ++++ openapi/openapiv3.yaml | 6 ++++++ temporal/api/workflowservice/v1/request_response.proto | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/openapi/openapiv2.json b/openapi/openapiv2.json index fd89dde95..f6669e228 100644 --- a/openapi/openapiv2.json +++ b/openapi/openapiv2.json @@ -18454,6 +18454,10 @@ "type": "string", "description": "Operation token. Only populated for asynchronous operations after a successful StartOperation call." }, + "propagatedNexusSerializationContext": { + "$ref": "#/definitions/v1PropagatedNexusSerializationContext", + "description": "Serialization context for this operation's payloads, derived from its stored target.\nFor a reused operation, this is the original execution's context." + }, "result": { "$ref": "#/definitions/v1Payload", "description": "The result if the operation completed successfully." diff --git a/openapi/openapiv3.yaml b/openapi/openapiv3.yaml index 9a857af9e..6c6edc38a 100644 --- a/openapi/openapiv3.yaml +++ b/openapi/openapiv3.yaml @@ -14711,6 +14711,12 @@ components: operationToken: type: string description: Operation token. Only populated for asynchronous operations after a successful StartOperation call. + propagatedNexusSerializationContext: + allOf: + - $ref: '#/components/schemas/PropagatedNexusSerializationContext' + description: |- + Serialization context for this operation's payloads, derived from its stored target. + For a reused operation, this is the original execution's context. result: allOf: - $ref: '#/components/schemas/Payload' diff --git a/temporal/api/workflowservice/v1/request_response.proto b/temporal/api/workflowservice/v1/request_response.proto index d1c829123..58d1e5190 100644 --- a/temporal/api/workflowservice/v1/request_response.proto +++ b/temporal/api/workflowservice/v1/request_response.proto @@ -3511,6 +3511,10 @@ message PollNexusOperationExecutionResponse { // Operation token. Only populated for asynchronous operations after a successful StartOperation call. string operation_token = 3; + // Serialization context for this operation's payloads, derived from its stored target. + // For a reused operation, this is the original execution's context. + temporal.api.nexus.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 6; + // The operation outcome, available if the operation is in a closed state. oneof outcome { // The result if the operation completed successfully. From 4abfee14ccd2a94556f1c7d69bd41846ab4e212b Mon Sep 17 00:00:00 2001 From: Joshua Frenchwood Date: Fri, 2 Oct 2026 15:24:52 -0500 Subject: [PATCH 8/9] Updating PropagatedNexusSerializationContext to PropagatedSerializationContext --- openapi/openapiv2.json | 24 ++++++++--------- openapi/openapiv3.yaml | 26 +++++++------------ temporal/api/activity/v1/message.proto | 2 +- temporal/api/history/v1/message.proto | 2 +- temporal/api/nexus/v1/message.proto | 6 ++--- temporal/api/update/v1/message.proto | 2 +- temporal/api/workflow/v1/message.proto | 2 +- .../workflowservice/v1/request_response.proto | 12 ++++----- 8 files changed, 33 insertions(+), 43 deletions(-) diff --git a/openapi/openapiv2.json b/openapi/openapiv2.json index f6669e228..525599883 100644 --- a/openapi/openapiv2.json +++ b/openapi/openapiv2.json @@ -12636,7 +12636,7 @@ "description": "Time to wait before making the first activity task available for dispatch. This delay is not applied to retry attempts." }, "propagatedNexusSerializationContext": { - "$ref": "#/definitions/v1PropagatedNexusSerializationContext", + "$ref": "#/definitions/v1PropagatedSerializationContext", "description": "Serialization context propagated from the Nexus caller that started this activity." } } @@ -12909,8 +12909,8 @@ "description": "Time-skipping configuration. If not set, time skipping is disabled." }, "propagatedNexusSerializationContext": { - "$ref": "#/definitions/v1PropagatedNexusSerializationContext", - "description": "Serialization context propagated from the Nexus caller that started this workflow.\nWith WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING, this must match the existing execution's\ncontext because all attached completion callbacks receive the same encoded outcome." + "$ref": "#/definitions/v1PropagatedSerializationContext", + "description": "Serialization context propagated from the Nexus caller that started this workflow." } } }, @@ -13433,7 +13433,7 @@ "description": "Links to be associated with this update." }, "propagatedNexusSerializationContext": { - "$ref": "#/definitions/v1PropagatedNexusSerializationContext", + "$ref": "#/definitions/v1PropagatedSerializationContext", "description": "Serialization context propagated from the Nexus caller that started this update." } }, @@ -13922,7 +13922,7 @@ "description": "The time at which the first activity task is made available for dispatch, computed as\n`schedule_time + start_delay`. Same as `schedule_time` if `start_delay` is not set." }, "propagatedNexusSerializationContext": { - "$ref": "#/definitions/v1PropagatedNexusSerializationContext", + "$ref": "#/definitions/v1PropagatedSerializationContext", "description": "Serialization context propagated from the Nexus caller that started this activity." } }, @@ -18455,7 +18455,7 @@ "description": "Operation token. Only populated for asynchronous operations after a successful StartOperation call." }, "propagatedNexusSerializationContext": { - "$ref": "#/definitions/v1PropagatedNexusSerializationContext", + "$ref": "#/definitions/v1PropagatedSerializationContext", "description": "Serialization context for this operation's payloads, derived from its stored target.\nFor a reused operation, this is the original execution's context." }, "result": { @@ -18582,7 +18582,7 @@ "description": "The weighted, versioned list of poller groups IDs that client should use for future polls to\nthis task queue. Client should ignore this if it has already applied a snapshot with a\nversion greater than or equal to `poller_groups_info.version`. Client is expected to:\n 1. Maintain minimum number of pollers no less than the number of groups.\n 2. Try to assign the next poll to a group without any pending polls,\n 3. If every group has some pending polls, assign the next poll to a group randomly\n according to the weights." }, "propagatedNexusSerializationContext": { - "$ref": "#/definitions/v1PropagatedNexusSerializationContext", + "$ref": "#/definitions/v1PropagatedSerializationContext", "description": "Serialization context propagated from the Nexus caller that started this workflow." } } @@ -18699,7 +18699,7 @@ }, "description": "Priority contains metadata that controls relative ordering of task processing\nwhen tasks are backed up in a queue. Initially, Priority will be used in\nmatching (workflow and activity) task queues. Later it may be used in history\ntask queues and in rate limiting decisions.\n\nPriority is attached to workflows and activities. By default, activities\ninherit Priority from the workflow that created them, but may override fields\nwhen an activity is started or modified.\n\nDespite being named \"Priority\", this message also contains fields that\ncontrol \"fairness\" mechanisms.\n\nFor all fields, the field not present or equal to zero/empty string means to\ninherit the value from the calling workflow, or if there is no calling\nworkflow, then use the default value.\n\nFor all fields other than fairness_key, the zero value isn't meaningful so\nthere's no confusion between inherit/default and a meaningful value. For\nfairness_key, the empty string will be interpreted as \"inherit\". This means\nthat if a workflow has a non-empty fairness key, you can't override the\nfairness key of its activity to the empty string.\n\nThe overall semantics of Priority are:\n1. First, consider \"priority\": higher priority (lower number) goes first.\n2. Then, consider fairness: try to dispatch tasks for different fairness keys\n in proportion to their weight.\n\nApplications may use any subset of mechanisms that are useful to them and\nleave the other fields to use default values.\n\nNot all queues in the system may support the \"full\" semantics of all priority\nfields. (Currently only support in matching task queues is planned.)" }, - "v1PropagatedNexusSerializationContext": { + "v1PropagatedSerializationContext": { "type": "object", "properties": { "endpoint": { @@ -18712,7 +18712,7 @@ "type": "string" } }, - "description": "PropagatedNexusSerializationContext represents the context of the Nexus caller that started this execution.\nNexus callers can share a workflow or standalone activity with USE_EXISTING only when their\nendpoint, service, and operation match. A request with a different context is rejected." + "description": "PropagatedSerializationContext represents the context of the Nexus caller that started this execution." }, "v1QueryRejectCondition": { "type": "string", @@ -18960,7 +18960,7 @@ "description": "Links to be associated with this update." }, "propagatedNexusSerializationContext": { - "$ref": "#/definitions/v1PropagatedNexusSerializationContext", + "$ref": "#/definitions/v1PropagatedSerializationContext", "description": "Serialization context propagated from the Nexus caller that started this update." } }, @@ -21694,7 +21694,7 @@ "description": "Information about time skipping of the workflow execution.\nIf the execution has never enabled time skipping, it will be nil." }, "propagatedNexusSerializationContext": { - "$ref": "#/definitions/v1PropagatedNexusSerializationContext", + "$ref": "#/definitions/v1PropagatedSerializationContext", "description": "Serialization context propagated from the Nexus caller that started this workflow." } }, @@ -22125,7 +22125,7 @@ "description": "The time-skipping state propagated from a previous run of this workflow. This can be nil\nif no time skipping has occurred or there is no previous run." }, "propagatedNexusSerializationContext": { - "$ref": "#/definitions/v1PropagatedNexusSerializationContext", + "$ref": "#/definitions/v1PropagatedSerializationContext", "description": "Serialization context propagated from the Nexus caller that started this workflow." } }, diff --git a/openapi/openapiv3.yaml b/openapi/openapiv3.yaml index 6c6edc38a..4da1686a9 100644 --- a/openapi/openapiv3.yaml +++ b/openapi/openapiv3.yaml @@ -9917,7 +9917,7 @@ components: format: date-time propagatedNexusSerializationContext: allOf: - - $ref: '#/components/schemas/PropagatedNexusSerializationContext' + - $ref: '#/components/schemas/PropagatedSerializationContext' description: Serialization context propagated from the Nexus caller that started this activity. description: Information about a standalone activity. ActivityExecutionListInfo: @@ -14713,7 +14713,7 @@ components: description: Operation token. Only populated for asynchronous operations after a successful StartOperation call. propagatedNexusSerializationContext: allOf: - - $ref: '#/components/schemas/PropagatedNexusSerializationContext' + - $ref: '#/components/schemas/PropagatedSerializationContext' description: |- Serialization context for this operation's payloads, derived from its stored target. For a reused operation, this is the original execution's context. @@ -14868,7 +14868,7 @@ components: according to the weights. propagatedNexusSerializationContext: allOf: - - $ref: '#/components/schemas/PropagatedNexusSerializationContext' + - $ref: '#/components/schemas/PropagatedSerializationContext' description: Serialization context propagated from the Nexus caller that started this workflow. PollerGroupInfo: type: object @@ -15081,7 +15081,7 @@ components: Not all queues in the system may support the "full" semantics of all priority fields. (Currently only support in matching task queues is planned.) - PropagatedNexusSerializationContext: + PropagatedSerializationContext: type: object properties: endpoint: @@ -15090,10 +15090,7 @@ components: type: string operation: type: string - description: |- - PropagatedNexusSerializationContext represents the context of the Nexus caller that started this execution. - Nexus callers can share a workflow or standalone activity with USE_EXISTING only when their - endpoint, service, and operation match. A request with a different context is rejected. + description: PropagatedSerializationContext represents the context of the Nexus caller that started this execution. QueryRejected: type: object properties: @@ -17172,7 +17169,7 @@ components: description: Time to wait before making the first activity task available for dispatch. This delay is not applied to retry attempts. propagatedNexusSerializationContext: allOf: - - $ref: '#/components/schemas/PropagatedNexusSerializationContext' + - $ref: '#/components/schemas/PropagatedSerializationContext' description: Serialization context propagated from the Nexus caller that started this activity. StartActivityExecutionResponse: type: object @@ -17683,11 +17680,8 @@ components: description: Time-skipping configuration. If not set, time skipping is disabled. propagatedNexusSerializationContext: allOf: - - $ref: '#/components/schemas/PropagatedNexusSerializationContext' - description: |- - Serialization context propagated from the Nexus caller that started this workflow. - With WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING, this must match the existing execution's - context because all attached completion callbacks receive the same encoded outcome. + - $ref: '#/components/schemas/PropagatedSerializationContext' + description: Serialization context propagated from the Nexus caller that started this workflow. StartWorkflowExecutionResponse: type: object properties: @@ -20179,7 +20173,7 @@ components: If the execution has never enabled time skipping, it will be nil. propagatedNexusSerializationContext: allOf: - - $ref: '#/components/schemas/PropagatedNexusSerializationContext' + - $ref: '#/components/schemas/PropagatedSerializationContext' description: Serialization context propagated from the Nexus caller that started this workflow. description: Holds all the extra information about workflow execution that is not part of Visibility. WorkflowExecutionFailedEventAttributes: @@ -20727,7 +20721,7 @@ components: if no time skipping has occurred or there is no previous run. propagatedNexusSerializationContext: allOf: - - $ref: '#/components/schemas/PropagatedNexusSerializationContext' + - $ref: '#/components/schemas/PropagatedSerializationContext' description: Serialization context propagated from the Nexus caller that started this workflow. description: Always the first event in workflow history WorkflowExecutionTerminatedEventAttributes: diff --git a/temporal/api/activity/v1/message.proto b/temporal/api/activity/v1/message.proto index a0bb66c18..862729526 100644 --- a/temporal/api/activity/v1/message.proto +++ b/temporal/api/activity/v1/message.proto @@ -198,7 +198,7 @@ message ActivityExecutionInfo { google.protobuf.Timestamp execution_time = 38; // Serialization context propagated from the Nexus caller that started this activity. - temporal.api.nexus.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 39; + temporal.api.nexus.v1.PropagatedSerializationContext propagated_nexus_serialization_context = 39; } // Limited activity information returned in the list response. diff --git a/temporal/api/history/v1/message.proto b/temporal/api/history/v1/message.proto index bec532db5..1c6efd305 100644 --- a/temporal/api/history/v1/message.proto +++ b/temporal/api/history/v1/message.proto @@ -215,7 +215,7 @@ message WorkflowExecutionStartedEventAttributes { temporal.api.common.v1.TimeSkippingStatePropagation time_skipping_state_propagation = 43; // Serialization context propagated from the Nexus caller that started this workflow. - temporal.api.nexus.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 44; + temporal.api.nexus.v1.PropagatedSerializationContext propagated_nexus_serialization_context = 44; } diff --git a/temporal/api/nexus/v1/message.proto b/temporal/api/nexus/v1/message.proto index ea49b230a..b3581ac49 100644 --- a/temporal/api/nexus/v1/message.proto +++ b/temporal/api/nexus/v1/message.proto @@ -17,10 +17,8 @@ import "temporal/api/enums/v1/nexus.proto"; import "temporal/api/failure/v1/message.proto"; import "temporal/api/sdk/v1/user_metadata.proto"; -// PropagatedNexusSerializationContext represents the context of the Nexus caller that started this execution. -// Nexus callers can share a workflow or standalone activity with USE_EXISTING only when their -// endpoint, service, and operation match. A request with a different context is rejected. -message PropagatedNexusSerializationContext { +// PropagatedSerializationContext represents the context of the Nexus caller that started this execution. +message PropagatedSerializationContext { string endpoint = 1; string service = 2; string operation = 3; diff --git a/temporal/api/update/v1/message.proto b/temporal/api/update/v1/message.proto index 1178cb392..45dac1955 100644 --- a/temporal/api/update/v1/message.proto +++ b/temporal/api/update/v1/message.proto @@ -70,7 +70,7 @@ message Request { // Links to be associated with this update. repeated temporal.api.common.v1.Link links = 5; // Serialization context propagated from the Nexus caller that started this update. - temporal.api.nexus.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 6; + temporal.api.nexus.v1.PropagatedSerializationContext propagated_nexus_serialization_context = 6; } // An Update protocol message indicating that a Workflow Update has been rejected. diff --git a/temporal/api/workflow/v1/message.proto b/temporal/api/workflow/v1/message.proto index 6308ec807..9c013b1dc 100644 --- a/temporal/api/workflow/v1/message.proto +++ b/temporal/api/workflow/v1/message.proto @@ -141,7 +141,7 @@ message WorkflowExecutionExtendedInfo { temporal.api.common.v1.TimeSkippingInfo time_skipping_info = 9; // Serialization context propagated from the Nexus caller that started this workflow. - temporal.api.nexus.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 10; + temporal.api.nexus.v1.PropagatedSerializationContext propagated_nexus_serialization_context = 10; } // Holds all the information about worker versioning for a particular workflow execution. diff --git a/temporal/api/workflowservice/v1/request_response.proto b/temporal/api/workflowservice/v1/request_response.proto index 58d1e5190..2586257de 100644 --- a/temporal/api/workflowservice/v1/request_response.proto +++ b/temporal/api/workflowservice/v1/request_response.proto @@ -220,9 +220,7 @@ message StartWorkflowExecutionRequest { // Time-skipping configuration. If not set, time skipping is disabled. temporal.api.common.v1.TimeSkippingConfig time_skipping_config = 29; // Serialization context propagated from the Nexus caller that started this workflow. - // With WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING, this must match the existing execution's - // context because all attached completion callbacks receive the same encoded outcome. - temporal.api.nexus.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 30; + temporal.api.nexus.v1.PropagatedSerializationContext propagated_nexus_serialization_context = 30; } message StartWorkflowExecutionResponse { @@ -389,7 +387,7 @@ message PollWorkflowTaskQueueResponse { // according to the weights. temporal.api.taskqueue.v1.PollerGroupsInfo poller_groups_info = 19; // Serialization context propagated from the Nexus caller that started this workflow. - temporal.api.nexus.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 20; + temporal.api.nexus.v1.PropagatedSerializationContext propagated_nexus_serialization_context = 20; } message RespondWorkflowTaskCompletedRequest { @@ -619,7 +617,7 @@ message PollActivityTaskQueueResponse { // according to the weights. temporal.api.taskqueue.v1.PollerGroupsInfo poller_groups_info = 22; // Serialization context propagated from the Nexus caller that started this activity. - temporal.api.nexus.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 23; + temporal.api.nexus.v1.PropagatedSerializationContext propagated_nexus_serialization_context = 23; } message RecordActivityTaskHeartbeatRequest { @@ -3279,7 +3277,7 @@ message StartActivityExecutionRequest { // Time to wait before making the first activity task available for dispatch. This delay is not applied to retry attempts. google.protobuf.Duration start_delay = 22; // Serialization context propagated from the Nexus caller that started this activity. - temporal.api.nexus.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 23; + temporal.api.nexus.v1.PropagatedSerializationContext propagated_nexus_serialization_context = 23; } message StartActivityExecutionResponse { @@ -3513,7 +3511,7 @@ message PollNexusOperationExecutionResponse { // Serialization context for this operation's payloads, derived from its stored target. // For a reused operation, this is the original execution's context. - temporal.api.nexus.v1.PropagatedNexusSerializationContext propagated_nexus_serialization_context = 6; + temporal.api.nexus.v1.PropagatedSerializationContext propagated_nexus_serialization_context = 6; // The operation outcome, available if the operation is in a closed state. oneof outcome { From 92a939d8ad7a78108cc156aebc09687e3aaee9ff Mon Sep 17 00:00:00 2001 From: Joshua Frenchwood Date: Fri, 2 Oct 2026 15:34:54 -0500 Subject: [PATCH 9/9] Removing serialization context from PollWorkflowTaskQueueResponse --- openapi/openapiv2.json | 4 ---- openapi/openapiv3.yaml | 4 ---- temporal/api/workflowservice/v1/request_response.proto | 2 -- 3 files changed, 10 deletions(-) diff --git a/openapi/openapiv2.json b/openapi/openapiv2.json index 525599883..88e817526 100644 --- a/openapi/openapiv2.json +++ b/openapi/openapiv2.json @@ -18580,10 +18580,6 @@ "pollerGroupsInfo": { "$ref": "#/definitions/v1PollerGroupsInfo", "description": "The weighted, versioned list of poller groups IDs that client should use for future polls to\nthis task queue. Client should ignore this if it has already applied a snapshot with a\nversion greater than or equal to `poller_groups_info.version`. Client is expected to:\n 1. Maintain minimum number of pollers no less than the number of groups.\n 2. Try to assign the next poll to a group without any pending polls,\n 3. If every group has some pending polls, assign the next poll to a group randomly\n according to the weights." - }, - "propagatedNexusSerializationContext": { - "$ref": "#/definitions/v1PropagatedSerializationContext", - "description": "Serialization context propagated from the Nexus caller that started this workflow." } } }, diff --git a/openapi/openapiv3.yaml b/openapi/openapiv3.yaml index 4da1686a9..e69e946df 100644 --- a/openapi/openapiv3.yaml +++ b/openapi/openapiv3.yaml @@ -14866,10 +14866,6 @@ components: 2. Try to assign the next poll to a group without any pending polls, 3. If every group has some pending polls, assign the next poll to a group randomly according to the weights. - propagatedNexusSerializationContext: - allOf: - - $ref: '#/components/schemas/PropagatedSerializationContext' - description: Serialization context propagated from the Nexus caller that started this workflow. PollerGroupInfo: type: object properties: diff --git a/temporal/api/workflowservice/v1/request_response.proto b/temporal/api/workflowservice/v1/request_response.proto index 2586257de..1e3e4d14f 100644 --- a/temporal/api/workflowservice/v1/request_response.proto +++ b/temporal/api/workflowservice/v1/request_response.proto @@ -386,8 +386,6 @@ message PollWorkflowTaskQueueResponse { // 3. If every group has some pending polls, assign the next poll to a group randomly // according to the weights. temporal.api.taskqueue.v1.PollerGroupsInfo poller_groups_info = 19; - // Serialization context propagated from the Nexus caller that started this workflow. - temporal.api.nexus.v1.PropagatedSerializationContext propagated_nexus_serialization_context = 20; } message RespondWorkflowTaskCompletedRequest {