A workflow definition cannot name which executor runs it, so nothing but WorkflowRunner can drive a run
- Dominant language
- C#
- Stars
- 6
- Forks
- 7
- Avg merge
- 4h 21m
- Merged PRs (30d)
- 307
Description
`IWorkflowAction` lets a module add a step. Nothing lets a module execute a run.
`WorkflowRunner` is `internal`, `WorkflowRunQueue` dispatches to it implicitly by writing a `WorkflowRun` document the runner polls, and there is no registration point in between. So a module that wants to hand a whole workflow to something else (Temporal, Wolverine, a hosted queue) can only do it from inside a single action, which gets the hand-off but not the run.
This came out of evaluating Temporal, recorded as D19 in `DECISIONS.md` on `claude/temporal-module-integration-3yypgt`. The conclusion there is that core should not ship such an integration, and separately that core should stop being the reason nobody else can.
### Shape
Routing, not replacement. A `WorkflowDefinition` names its executor, defaulting to the built-in one, so a module claims only the workflows an operator points at it and every other workflow is untouched.
Wholesale replacement of the runner is deliberately not the shape. It would make one module's choice global, which is not what a module is, and it would put the failure mode of every workflow in a package core does not ship. It also fails the default rule: a config default must preserve existing behaviour.
### The interface is the smaller half of the contract
A replacement executor has to keep the `WorkflowRun` document current, because that document is what `/api/workflow-runs` serves and what barakoBrew reads, and section 6 now treats that JSON as contract. So what an executor is actually promising is the invariants, and they need stating with the interface rather than being inferred from `WorkflowRunner`:
- attempts within a run advance in `Ordinal` order
- an outcome is written only by the holder of the lease
- a timeout records `Unknown`, not a failure, because the request may have arrived
- the idempotency key stays stable across retries of one action
### Keep it internal until a second implementation exists
A seam designed against one caller is a guess, and section 6 freezes a public member for the rest of the major. There are no modules outside this repository yet, which is D18's argument for settling module questions now and is equally the argument for not publishing this one early. Ship the routing internal, make it public in 5.0 once something other than `WorkflowRunner` has been built against it.
### Relationship to existing issues
#687 spikes replacing the hand-rolled outbox and retry with Wolverine. That is the same question asked about a different library, and it currently has the same obstacle: there is nowhere to plug an alternative in without editing core. Whatever #687 concludes, this seam is what would let it be tried without a fork.
### Where I checked
`barakoCMS/Features/Workflows/` (`WorkflowRunner`, `WorkflowRunQueue`, `IWorkflowAction`), `barakoCMS/Models/WorkflowDefinition.cs`, `MODULES.md`, `DECISIONS.md` D18. Searched open issues for workflow executor and pluggable runner. #687 is adjacent, not the same ask.
Contributor guide
Research direction
Start with barakoCMS/Features/Workflows/WorkflowRunner and WorkflowRunQueue, then read Models/WorkflowDefinition.cs, MODULES.md, and DECISIONS.md D18. Trace how runs are dispatched and how WorkflowRun documents are updated. Done means internal per-definition routing preserves the built-in default and documents the stated ordering, lease, timeout, and idempotency invariants without publishing the seam.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- backend, backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100