Suspend and resume
> **Work in progress.** Suspend is implemented in the native engine. > `Engine.resume()` is specified but **not yet implemented** — the engine > throws
Work in progress. Suspend is implemented in the native engine.
Engine.resume()is specified but not yet implemented — the engine throwsRESUME_NOT_IMPLEMENTED. Snapshot persistence adapters (file, SQLite) are implemented. APIs may change.
A step can suspend a run: pause execution, persist a snapshot, and wait for external input. A later resume call reloads the snapshot, injects the resume data as the suspended step's output, and continues scheduling downstream steps.
When to use suspend
- Human-in-the-loop approvals — suspend before a deploy step, wait for manual approval, resume with the decision.
- External service callbacks — suspend after triggering a build, wait for the build system to call back with results.
- Interactive AI workflows — suspend an agent step, present output to a user, resume with their feedback.
How it works
- A step with a
suspendoperation runs its pre-suspend operations normally.suspendmust be the last operation in the step. - The engine persists a
RunSnapshot(completed steps, their scalar outputs, the suspended step id, resume schema) to aSnapshotStore. - The run enters
suspendedstatus. Therun-suspendedevent is emitted. - External caller invokes
Engine.resume()with resume data. - The engine reloads the snapshot, injects the resume data as the suspended step's output, marks the step as succeeded, and continues scheduling downstream steps.
Declaring a suspend step
Planned API. The examples below show the planned API.
SuspendStepandEngine.resume()are not yet implemented.
Construct API
import { Project, Pipeline, SuspendStep, Entry } from "@sverka/workflow";
const proj = new Project("approval");
const p = new Pipeline(proj, "deploy-with-approval");
new SuspendStep(p, "await-approval", {
resumeSchema: { required: ["approved", "approver"] },
});
new ShellStep(p, "deploy", {
command: "kubectl apply -f deploy.yaml",
dependsOn: ["await-approval"],
});
new Entry(p, "on-push", { trigger: { kind: "push" }, roots: ["deploy"] });SDK builder
import { sverka } from "@sverka/sdk";
const p = sverka.pipeline("deploy-with-approval");
sverka.suspend("await-approval");
sverka
.step("deploy")
.sh("kubectl apply -f deploy.yaml")
.dependsOn("await-approval");Resuming a run
Not yet implemented.
Engine.resume()currently throwsRESUME_NOT_IMPLEMENTED. The interface below shows the planned API.
import { createEngine, createInMemorySnapshotStore } from "@sverka/runtime";
const store = createInMemorySnapshotStore();
const engine = createEngine({ drivers: [] });
// `plan` is a RunPlan — obtain it by binding a DefinitionGraph.
// See the Workflow API docs for full details.
// const plan = bindRunPlan({ graph, entryId: "deploy/on-push" });
// Start the run — it will suspend at the await-approval step
const iter = engine.run({
plan,
snapshotStore: store,
workspace: "./ws",
artifactDir: "./art",
});
for await (const event of iter) {
if (event.type === "run-suspended") {
console.log("Run suspended, waiting for resume...");
}
}
// Later: resume with external data
const resumeIter = engine.resume({
runId: "run-123",
data: JSON.stringify({ approved: "true", approver: "alice" }),
snapshotStore: store,
workspace: "./ws",
artifactDir: "./art",
});
for await (const event of resumeIter) {
console.log(event.type);
}Events
| Event | When |
|---|---|
step-suspended | A step has suspended — snapshot is being persisted |
run-suspended | The run is now suspended, waiting for resume |
run-resumed | The run has been resumed from a snapshot |
Snapshot stores
| Store | Status | Use case |
|---|---|---|
createInMemorySnapshotStore | Implemented | Tests, ephemeral runs |
createFileSnapshotStore | Implemented | Local persistent runs |
createSqliteSnapshotStore | Implemented | Local persistent runs (SQLite) |
| Postgres adapter | Planned | Distributed runs |
Limitations (v1)
- One suspended step per run. Concurrent suspend is not supported — in-flight steps are awaited before the snapshot is persisted.
- No mid-step checkpointing.
suspendmust be the last operation in a step. Pre-suspend operations run normally; their outputs are captured. - No CI equivalent yet. Compiled workflows lower steps to native jobs; suspend/resume is not lowered.