elsa-core/test
Sipke Schoorstra f99f37407c
feat(bpmn): host port and command applier (#7942)
* feat(bpmn): host-side applier for the Bpmn.Semantics port

Translates the interpreter's three host commands onto ActivityExecutionContext
and feeds its four entry points, plus the minimum BpmnProcess container needed
to exercise them end to end through IWorkflowRunner.

StartWork schedules the bound activity, CancelWorkSubtree calls the public
CancelActivityAsync extension (already recursive), and SignalEnclosingScope
sends a BpmnScopeSignal up the ancestor chain. OnWorkFaulted rides the
FaultSignal seam: it asks the interpreter what BPMN made of the fault and calls
StopPropagation only on a Caught disposition, leaving a Propagated one strictly
alone so an enclosing scope or the incident strategy takes it.

A unit of work is keyed on the child ActivityExecutionContext.Id, recorded in
the scope's own persisted ledger, never on Tag: the completion-callback dispatch
rewrites the receiving context's Tag, so a nested scope wears a different tag
than its parent remembers it by. Interpreter correlation travels on the child's
context rather than on the shared activity instance.

Evaluations go through one queue per workflow instance, so a scope signalled
mid-apply is drained after the command list rather than re-entering the
interpreter. Commands are applied in the order returned.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* test(bpmn): cover the teardown refusal path

Adds a focused unit test that drives BpmnWorkTeardown.CancelSubtreeAsync
into the NotSupportedException branch by constructing a real context tree
with a scheduled-but-not-invoked descendant, so a regression that silently
drops the detection is caught. Also records why BpmnWorkLedger's
append-only, handle-keyed Records list cannot strand a context on a
duplicate StartWork for a live (BindingRef, IterationId) slot, a case the
port's own guarantee makes unreachable from this applier.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(bpmn): keep a refused teardown from stranding ledger state

A subtree cancellation refused with NotSupportedException is absorbed
into an incident under ContinueWithIncidentsStrategy rather than
crashing, so the end-of-command ledger save was being skipped and the
persisted ledger kept claiming work BPMN had just torn down. Save the
ledger removal before the possible throw instead of after, so a later
completion callback for the stranded activity finds no live record and
is discarded instead of being fed to the interpreter.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 01:42:31 +02:00
..
component Add output converter support at binding boundaries 2026-07-31 04:10:48 +02:00
integration feat(bpmn): host port and command applier (#7942) 2026-08-14 01:42:31 +02:00
performance Add output converter support at binding boundaries 2026-07-31 04:10:48 +02:00
TlsSmoke [codex] Fix console log metadata and type resolution (#7542) 2026-05-30 22:52:01 +02:00
unit feat(bpmn): host port and command applier (#7942) 2026-08-14 01:42:31 +02:00
Directory.Build.props Upgrade projects to target .NET 10, add conditional System.Linq.Async dependencies for compatibility with earlier frameworks, and update project files for consistency across the solution. (#7062) 2025-11-21 20:55:30 +01:00
Directory.Build.targets [codex] Harden initial security remediation slice (#7495) 2026-05-22 00:45:47 +02:00