Skip to content

Add support for workflow history propagation #312

@cicoyle

Description

@cicoyle

Background

Dapr Workflows now supports propagating execution history from a parent workflow to its child workflows and activities. This lets downstream code inspect what happened upstream — useful for chain-of-custody verification, fraud detection, audit, and AI-agent context flow.

Two scopes are exposed:

  • PropagateLineage — caller's own events plus the full ancestor chain
  • PropagateOwnHistory — caller's events only (a trust boundary; ancestors are dropped)

The Go path is implemented end-to-end. To use this feature from a Rust app, this SDK needs the matching API.

Proto surface

From dapr/durabletask-protobuf (PR #38):

  • history_events.proto
    • TaskScheduledEvent.historyPropagationScope (optional, field 7)
    • ChildWorkflowInstanceCreatedEvent.historyPropagationScope (optional, field 7)
    • new PropagatedHistory { repeated HistoryEvent events; HistoryPropagationScope scope; repeated PropagatedHistoryChunk chunks; }
    • new PropagatedHistoryChunk { string appId; int32 startEventIndex; int32 eventCount; string instanceId; string workflowName; }
  • orchestration.proto
    • new HistoryPropagationScope enum: HISTORY_PROPAGATION_SCOPE_NONE = 0, HISTORY_PROPAGATION_SCOPE_OWN_HISTORY = 1, HISTORY_PROPAGATION_SCOPE_LINEAGE = 2
  • orchestrator_actions.proto
    • ScheduleTaskAction.historyPropagationScope (optional, field 6)
    • CreateChildWorkflowAction.historyPropagationScope (optional, field 6)

What needs to happen here

1. Proto regen + plumbing

  • Pull the updated .proto files from dapr/durabletask-protobuf and regenerate the prost/tonic-generated code
  • Plumb the new historyPropagationScope field through the schedule-task / create-child-workflow code paths
  • Surface the received PropagatedHistory to the workflow runtime so it can be handed to user code

2. User-facing API to add

Schedule-side (parent workflow author):

  • with_history_propagation(scope) builder method on the activity-call and child-workflow-call types
  • HistoryPropagationScope::Lineage and HistoryPropagationScope::OwnHistory enum variants

Receive-side (child workflow / activity author):

  • ctx.propagated_history() -> Option<PropagatedHistory> on workflow and activity contexts
  • PropagatedHistory struct with:
    • events: Vec<HistoryEvent>
    • scope: HistoryPropagationScope
    • chunks: Vec<PropagatedHistoryChunk> (each with app_id, workflow_name, instance_id, start_event_index, event_count)
    • app_ids() -> Vec<String> — deduplicated list of app IDs in the chain
    • convenience filters: workflow_by_name(name), events_by_app_id(app_id), events_by_instance_id(id), events_by_workflow_name(name)
    • returns Result<_, PropagationNotFoundError> for missing names

3. Example to add

examples/workflow-history-propagation/ mirroring the Go demo: a 3-tier payment workflow (parent → activity → child workflow with Lineage → activity with OwnHistory). Standalone dapr run mode at minimum; K8s + signing variant a stretch.

4. Tests

At least one test per scope:

  • Lineage: parent → child receives parent's events
  • OwnHistory: parent → child receives caller's events but NOT grandparent's

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions