You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(dsl): derive action CPN vars from incoming arcs (ground truth)
The previous compile_transition_action/2 inferred which keys to
`Keyword.fetch!/2` out of `event.binding` from `ExpressionHelper.free_vars/1`
on the action body. That over-approximates: any locally-introduced name
inside the body (a literal `pid = options[:test_pid]` or a pattern-match
temporary inside an `if`/`case`) was treated as a CPN var, so
`Keyword.fetch!(event.binding, :pid)` raised `KeyError`, the spawned
`Task` crashed, and `LifecycleHooks.safe_invoke/3` swallowed it — the
action silently never ran.
Switch the injection set to ground truth: at `__close_transition__!`
time we already know which CPN variables this transition's incoming
arcs bind. Use that list, drop the body-free-var step from the action
macro entirely, and let the body's pattern-match locals stay local.
To keep the compiler quiet under `--warnings-as-errors` when the body
only references a subset of the bound vars, every fetched binding gets
a paired `_used = var` discard. The injection still happens uniformly
(simpler reasoning, matches "all CPN vars are available") but unused
vars never trigger the unused-variable lint.
Drive-by: rename the misleading `describe "lifecycle dispatch (bare
module hooks)"` block to `"lifecycle dispatch (hooks options carry
test_pid only)"` — the test does not exercise the bare-module path
(that's covered by `LifecycleHooks.validate!/1` unit tests). Revert the
two-step `pid = options[:test_pid]; if pid do` workaround in the e2e
test back to the natural inline `if pid = options[:test_pid] do …` form
now that local pattern-match names no longer collide with CPN-var
injection.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
**Status:** keep **Decision:** principle is "each callback fires after its own telemetry event"; current code obeys that. Cross-callback ordering (workitem_enabled before enactment_start) is acceptable because each callback follows its own emit point.
**Status:** fix **Decision:** extract `dispatch_lifecycle/3` + `dispatch_post_calibration/3` into new module `ColouredFlow.Runner.Enactment.LifecycleHooks.Dispatcher`. API takes `%Enactment{}` state struct directly (internal helper, coupling acceptable). `:abnormal_exit` line stays in `terminate/2`.
0 commit comments