Skip to content

fix(dispatch): run scheduled_actions + spawn_requests on the inline integration path (ARN-188)#349

Open
rita-aga wants to merge 1 commit into
mainfrom
claude/arn-188-inline-integration-effects
Open

fix(dispatch): run scheduled_actions + spawn_requests on the inline integration path (ARN-188)#349
rita-aga wants to merge 1 commit into
mainfrom
claude/arn-188-inline-integration-effects

Conversation

@rita-aga

@rita-aga rita-aga commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Closes ARN-188 (High, Bug) under epic ARN-165. Draft for review — do not merge.

Bug

run_post_dispatch_effects (dispatch/effects.rs): when await_integration=true and a transition's custom effect maps to an inline WASM/adapter integration returning a callback response, the code returned before the spawn_requests + scheduled_actions steps. Those belong to the original transition (the callback is a separate action), so the original transition's child-entity spawns and scheduled timers were silently dropped. Reachable in prod via OData ?await_integration=true.

Fix

Extracted the deferred-effects steps into a shared dispatch_transition_deferred_effects, called on both the normal path and the inline early-return path, so the original transition's spawns + scheduled actions always run. Deliberately did not re-run steps 5b/7b/8 on the inline path — the callback already armed the final-state timer, so re-running 7b on the stale intermediate state would arm a superseding wrong-state timer (a regression). Both reviewers confirmed this scoping.

Red→green

inline_integration_still_runs_scheduled_and_spawn_effects: a Trigger transition emits a custom effect (→ inline http callback → Done) plus a scheduled Tick plus a spawn Child, under await_integration=true. RED: parent stuck at Done (Tick dropped). GREEN: parent reaches Ticked, child Initialized. Scoped: adapter_dispatch 6/6, wasm_dispatch 6/6, --lib dispatch 102/102. Code review PASS + DST-READY (both genuine).

🤖 Generated with Claude Code

…ath (ARN-188)

When await_integration=true and a transition's custom effect maps to an inline
WASM/adapter integration that returns a callback response, run_post_dispatch_effects
early-returned that callback response before dispatching the ORIGINAL transition's
spawn_requests and scheduled_actions. Those effect lists belong to the original
transition (the callback is a separate action), so the original transition's
child-entity spawns and scheduled timers were silently dropped. The path is
reachable in production via OData ?await_integration=true.

Extract the spawn + scheduled dispatch into a shared helper
dispatch_transition_deferred_effects and invoke it on both the normal path and the
inline early-return path, so the original transition's deferred effects always run
before returning the integration-updated response. Steps 5b (platform hooks), 7b
(state-timeout arming) and 8 (query projection) stay owned by the callback's own
dispatch on the inline path: re-running 7b on the stale intermediate state would
arm a superseding wrong-state timer, and 8 is sequence-guarded.

Adds a red-green regression test: a transition emitting a custom_effect (inline
adapter callback) plus a schedule and a spawn, dispatched with
await_integration=true, now observes the scheduled action fire and the child
entity spawn.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
@rita-aga rita-aga marked this pull request as ready for review July 9, 2026 23:34
@rita-aga

rita-aga commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator Author

@greptile review

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rita-aga has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rita-aga has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@rita-aga

Copy link
Copy Markdown
Collaborator Author

ARN-165 principle audit — request changes

Moving scheduled/spawn effect handling before one early return fixes the reported local reproduction, but it does not fix the durability root.

Blocking findings

  • Schedule and spawn paths are still detached tokio::spawn work.
  • A crash after the parent transition commits but before the task runs loses the effect permanently.
  • Other error/return branches can still discard the original effect set.
  • Retry/idempotency ownership is not defined, so simply re-running can duplicate non-idempotent work.

Required direction

Represent timer/spawn/cross-entity work as durable intents co-committed with the accepted transition. Claim them with leases/idempotency keys, retry with classified backoff, and recover after restart. Add deterministic crash points before/after parent commit, claim, child dispatch, and acknowledgment.

Please keep the control-flow fix as a regression test, but move responsibility out of the inline branch. The current PR is a surface repair and should not close ARN-188.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant