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: durable signal delivery preserves source port for edge config eval
v0.4.0 had a real bug exposed by in-cluster validation: durable-port
persist captures msg.Data BEFORE MsgHandler runs edge config evaluation.
The signal stored the source's raw output (e.g. an http response), but
the target port (e.g. kv:store) expected an already-mapped target shape
(e.g. StoreRequest with primary key populated by edge expressions).
Reconciler delivery would then unmarshal raw source bytes as target type
and the component would reject with structural errors ("primary key
not found in document"), the reconciler would treat as transient,
retry forever, and signals would accumulate.
Fix:
- TinySignalReconciler now sends msg.From = signal.Spec.From (the
original source port) when the spec carries it, instead of always
FromSignal. This makes MsgHandler treat the message as a regular
edge delivery and run edge config evaluation, mapping source's raw
payload into the target port's expected shape.
- To prevent infinite re-persist (msg.From != FromSignal would normally
retrigger the durable-port persist branch), reconciler marks the
delivery context with utils.WithDurableDelivery, and scheduler.Handle
checks this flag in addition to From.
Externally-injected signals (send_signal MCP, ticker fire) keep their
existing behavior: Spec.From is empty, msg.From defaults to FromSignal,
MsgHandler treats data as already-typed.
New test in scheduler_durable_test.go covers the
durable-delivery-context-skips-persist case so future regressions
can't reintroduce the loop.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 commit comments