Skip to main content
Version: 1.0.0

Bounded durable resume

Durable resume continues the same operation after process interruption. Touba loads a checkpoint, revalidates current authority and reconciles each external effect with its journal before proceeding. Restart never resumes automatically.

Choose the recovery mechanism​

Checkpoints serve several different paths. Select the path for the interrupted boundary instead of restarting the program from the beginning:

NeedPathState and boundary
Wait for a human decision--human-checkpoint-out, then --human-resume-checkpoint with an exact decision; durable waits through the serverSource/agent stacks, loops and parallel continuations are preserved; each decision belongs to one occurrence.
Persist a parallel group's progress--parallel-checkpoint-out, then --parallel-resume-checkpointCompleted branches return without new calls; private journals and budgets are preserved at group boundaries, not at every instruction after the join.
Resume an interrupted sequential operation/operations/{id}/recovery projection, then explicit resume requestThe direct, acyclic profile below, a touba-run-checkpoint-v1 checkpoint and effect journal.

Retain the same build and compatible artifacts, private checkpoints and effect journal. Incomplete or altered state is refused, not converted. Reconcile an unknown external outcome according to its effect contract; never assume success. Handlers still implement the external service's real idempotency. See Human validation, the CLI reference and SDK guide.

Eligible sequential workflows​

The supported entry graph is direct, sequential and acyclic: pure bind nodes, direct call_tool nodes, and a terminal give or stop. A human decision can be consumed only if it is already available and still valid at entry. Reachable tools must declare their effect contracts in a V1 manifest, including tools with kind: none.

Raw runtime inputs currently exclude this durable-resume path. The project server can execute runs with inputs normally, but does not label them resumable. Intermediate human pauses, loops and nested agent calls are not covered by this resume mechanism. Human checkpoints remain a separate mechanism.

Recover an operation after a lost HTTP response​

Create a session with POST /interactions/sessions and retain its session_id. Submit work to POST /interactions/sessions/{session_id}/messages with a unique, client-generated message_id retained by your application.

After a lost response, GET /interactions/sessions/{session_id} lists operations with their message IDs. Use the matching operation_id to read GET /operations/{operation_id}/recovery. Resending the exact same message with the same identity also returns its existing operation. Use a new identity for new business work. The server persists this correlation before execution.

These authenticated APIs work after a server restart. The host application controls user access. Sessions retain at most 100 messages and 50 operations; the store holds at most 100 sessions. Keep identifiers in your application and recover missing responses promptly. HTTP 202 means accepted; the operation carries the execution result.

Budget interrupted attempts​

Before dispatch, Touba reserves the handler's timeout_ms. A crashed attempt keeps that reservation because its exact elapsed time could not be confirmed. A retry reserves its own timeout.

Run budgetInterrupted attemptNew reservationOutcome
15,000 ms10,000 ms10,000 msrefused before dispatch
40,000 ms10,000 ms10,000 msreservation possible, with room for remaining work

Add confirmed active time, other operations and a margin. The total must stay strictly below max_run_ms. Time spent with the server stopped is excluded.

RunTimeBudgetExceeded details expose activeElapsedMs, reservationMs and remainingMs. The dispatch_refused_budget_exceeded event exposes active_elapsed_ms, reservation_ms, remaining_ms and limit_value.

Inspect before requesting resume​

GET /operations/operation%3Aexample/recovery

The touba-operation-recovery-v1 response contains state, freshness, correlations, effect summaries, allowed actions and structured refusal reasons. A client must use this response rather than infer authority from a visible button or cache.

POST /runs/sandbox/resume
Content-Type: application/json

{
"schema_version": "touba-operation-resume-request-v1",
"operation_id": "operation:example",
"checkpoint_revision": 4,
"checkpoint_digest": "sha256:...",
"resume_request_id": "resume:example:1"
}

Use the actual revision and digest returned by the server. Reading requires executions.read; resuming requires executions.run. Duplicate requests with the same identity and revision are coalesced. A stale revision or conflicting concurrent request produces DurableResumeConflict. Cancellation, revoked authority and changed artifacts are checked before a handler is launched.

Effects and budgets​

Recovered stateOutcome
applied, result availableRestore without launching the handler.
applied, result unavailableRefuse with EffectResultUnavailable.
unknown, idempotency keyRetry with the same effect_id and a new call_id.
unknown, reconciliationRequire provider-specific reconciliation.
unknown, no safe retryRefuse with EffectOutcomeUnknown.
kind: none, result lostMay repeat the call with a new attempt and budget charge.

Interrupted attempts remain charged. Restoring an already-applied result does not consume another tool call. Journal and checkpoint reconciliation requires exact call, attempt and effect-ordinal correlation; it does not skip to an unrelated later journal entry.

Persistence and trust​

touba-run-checkpoint-v1 stores execution position, validated JSON bindings, artifact digests, consumed budgets, effect identity and trace-prefix correlation. It does not store resolved secrets or authority tokens. Secrets are resolved again; a dynamic identity service is rechecked immediately before handler spawn.

The supplied store is single-host and single-process. A digest detects drift, not hostile rewriting by someone able to replace the file and recompute it. Produced values can remain in later checkpoints even after their last use. The runtime cannot identify an unknown credential incorrectly returned as business data. After a host SIGKILL, a handler may outlive the host unless the configured sandbox terminates descendants; the parent timeout does not survive that crash. There is no distributed transaction or exactly-once claim.

See Effect contracts and Durable human waits.