Wire pause resume end to end: triggers now wake paused missions - #295
Open
mcclowes wants to merge 1 commit into
Open
Wire pause resume end to end: triggers now wake paused missions#295mcclowes wants to merge 1 commit into
mcclowes wants to merge 1 commit into
Conversation
…ggers into execute({resumeFrom})
A paused mission never woke up on its own: PauseManager.handleWebhook and
startMonitoring had no production callers, so `pause resumeOn: webhook`
registered the endpoint and then nothing continued the run, and a timeout
pause had no component watching its deadline.
This adds the orchestration layer:
- PauseOrchestrator wires a webhook server and a pause store into automatic
resumes: routes inbound deliveries to the waiting pause on that path,
polls for expired deadlines (with a startup sweep so pauses that expired
while nothing was running resume immediately), re-registers webhook paths
lost to a restart, picks up deliveries that landed before it started, and
hands each resumed pause to a host resume callback.
- executeWithResume runs a mission to completion: execute, wait for a
trigger, re-execute with resumeFrom, repeat. Resume runs are serialized
through a queue so a webhook landing mid-unwind can't race the paused run.
- PauseManager.handleWebhookEvent maps a delivery (registration id, path
fallback) to the waiting pause holding that trigger.
- WebhookServer gains onEvent() subscription, registration/event read
accessors, a path on delivered events, and getPort() now reports the
actual bound port (so port 0 works).
The e2e tests the issue asked for: pause a mission, deliver a real webhook
over HTTP, assert the pipeline tail runs exactly once (and a duplicate
delivery 404s); plus timeout-driven resume via the poll.
Fixes #197
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #197
Problem
pause resumeOn: webhookregistered the endpoint, the caller POSTed to it, the server recorded the event — and nothing continued the run.PauseManager.handleWebhookandstartMonitoringhad zero production callers, so timeout pauses likewise had no running component watching the deadline. The resume mechanism (execute({ resumeFrom })replaying the durable log past an already-resumed pause) was sound; the trigger that invokes it was missing.What this adds
PauseOrchestrator(src/pause/orchestrator.ts) — the wiring between the webhook server, the pause store, and a host resume callback:resume(pause); a throwing callback is reported, never an unhandled rejection, and the pause stays recoverable via a manual resumeexecuteWithResume(source, config)(src/index.ts) — run a mission to completion: execute, wait for a trigger, re-execute withresumeFrom, loop. Resume runs are serialized through a queue so a webhook landing while the paused run is still unwinding can't start a concurrent run. Requiresconfig.executionLog(replaying past a pause is log-based) and throws a clear error without it.Supporting changes:
PauseManager.handleWebhookEvent(event → pause mapping),WebhookServer.onEvent()post-construction subscription, registration/event read accessors,pathon delivered events, andgetPort()reporting the actual bound port soport: 0works in tests.The test that would have caught this
src/interpreter/executor-pause-resume-e2e.test.ts: pause a mission, deliver a real webhook over HTTP, assert the pipeline tail runs exactly once — onepause.created, onepause.resumed, onemission.completed, one stored record carrying the webhook payload — and a duplicate delivery 404s without re-running anything. Plus a timeout-driven resume with no webhook at all, and orchestrator unit tests covering live routing, early delivery, restart recovery, failing resume callbacks, and the webhook-vs-timeout race resuming exactly once.Docs updated (
docs/durability/pause.md, README, CLAUDE.md): the "you drive the resume" warning is replaced with theexecuteWithResume/PauseOrchestratorstory; plain CLI runs still exit on pause and resume via--resume.🤖 Generated with Claude Code