dapr / dapr/cpp-sdk

Add support for workflow history propagation

Open
#68 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Makefile
Stars
38
Forks
16
PR merge metrics
No merged PRs in 30d

Description

## 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 C++ app, this SDK needs the matching API.

## Proto surface

From `dapr/durabletask-protobuf` ([PR #38](https://github.com/dapr/durabletask-protobuf/pull/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 C++ protobuf classes
- 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):**
- `WithHistoryPropagation(HistoryPropagationScope scope)` builder method on activity-call and child-workflow-call types
- `PropagateLineage()` and `PropagateOwnHistory()` free functions returning a scope value

**Receive-side (child workflow / activity author):**
- `GetPropagatedHistory()` returning `std::optional` on workflow and activity contexts
- `PropagatedHistory` class with:
- `events()` — list of `HistoryEvent`
- `scope()` — the scope enum value
- `workflows()` — chunks (each with `app_id`, `workflow_name`, `instance_id`, `start_event_index`, `event_count`)
- `app_ids()` — deduplicated list of app IDs in the chain
- convenience filters: `GetWorkflowByName(name)`, `GetEventsByAppID(app_id)`, `GetEventsByInstanceID(id)`, `GetEventsByWorkflowName(name)`
- returns `std::optional<...>` (or throws `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 `PropagateLineage` → activity with `PropagateOwnHistory`). 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

- `dapr/dapr` runtime PR: https://github.com/dapr/dapr/pull/9810
- `dapr/durabletask-go` PR: https://github.com/dapr/durabletask-go/pull/85
- `dapr/durabletask-protobuf` PR: https://github.com/dapr/durabletask-protobuf/pull/38
- `dapr/go-sdk` reference implementation: https://github.com/dapr/go-sdk/pull/823
- Go SDK example: `examples/workflow-history-propagation/`

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.