Skip to Content
SDK referenceRustHuman Review

Continue Rust work after human review

When policy asks for review, govern returns a result with status ReviewRequired and a review checkpoint. HumanReviewRuntime in veriproof-sdk owns the rest of the flow: it stores the checkpoint, verifies the signed callback, claims execution once, revalidates policy, runs the protected action, and acknowledges the result.

Create the review runtime

use veriproof_sdk::{HumanReviewOptions, HumanReviewRuntime, SqliteReviewStore, Veriproof}; let veriproof = Veriproof::from_env()?; let store = SqliteReviewStore::open("./state/veriproof-review.db")?; let options = HumanReviewOptions::default(); let reviews = HumanReviewRuntime::new(veriproof.clone(), store, options).await?;

SqliteReviewStore is the durable store for one application service. Each operation opens its own connection, so several workers may coordinate through the same file. Use with_callback_registration_version to select the active registration.

The runtime checks each callback against the signing keys VeriProof publishes at your endpoint, so there’s no callback secret to manage. If your host can’t reach VeriProof, pass a pinned copy of the same key set with with_webhook_keys(Arc::new(PinnedWebhookKeySet::new(key_set_json)?)).

Save the checkpoint before returning

let result = veriproof.govern("claims.pay", claim, pay_claim, options).await; if reviews.save_if_required(&result)? { return Ok(Pending(result.evidence_reference)); }

save_if_required stores the checkpoint when the result carries one and returns true. Persist your own workflow state next to it, keyed by the checkpoint’s review_reference, before you return control to the caller.

Receive the signed callback

let mut headers = WebhookHeaders::new(); for (name, value) in request_headers { headers.append(name, value); } let receipt = reviews.receive(&raw_body, &headers).await?;

Pass the unchanged request body. receive rejects an empty body, a body over 65,536 bytes, and a timestamp outside the accepted skew window before it checks the signature. It verifies VeriProof’s signature, confirms the webhook-id header matches the signed delivery, records the outcome atomically, and returns a ReviewReceipt. Pass every header, including repeats, so the runtime can reject duplicates. A replayed delivery returns the stored receipt with replayed set and does not change state.

VeriProof sends the webhook-id, webhook-timestamp, and webhook-signature headers on every callback. Return HTTP 503 when verification fails with key_set_unavailable, so VeriProof retries the delivery.

A receipt confirms that the callback was accepted. It does not confirm that protected work completed.

To check review event webhooks, call verify_webhook with WebhookVerificationOptions::keys(...) for VeriProof’s key set or WebhookVerificationOptions::secrets(...) for your whsec_ subscription secret.

Resume the action from a worker

let result = reviews .resume(checkpoint, |context| async move { context.throw_if_stopped()?; pay_claim(context.input, &context.idempotency_key).await }) .await;

Run resume outside the callback request. It loads the stored outcome, claims execution once, revalidates current policy with the reviewer’s response, and runs the action at most once. The context carries the same idempotency_key as the original run, so your side effect can stay idempotent. A follow-up request keeps the checkpoint paused. A rejection, cancellation, or expiry returns a typed result without running the action.

Rig applications can pass the same runtime and checkpoint to VeriproofRig::resume_tool.

Reconcile uncertain execution

If the process stops after the action may have run but before the result was recorded, the store keeps the checkpoint fenced. After your application confirms what happened, call reconcile:

use veriproof_sdk::ReconciliationOutcome; reviews.reconcile(&checkpoint, ReconciliationOutcome::ConfirmedCompleted)?;

Use ConfirmedNotExecuted when the side effect did not run. Do not retry a fenced checkpoint until the application has reconciled the durable effect.

Call flush_acknowledgments from a background task so that every execution acknowledgment reaches VeriProof even if the first attempt failed.

Keep the binding exact

The runtime matches the callback to the stored checkpoint by its review reference, protected action, decision, and application. Never resume a paused action by position or action name. Store one checkpoint per paused action, and let each callback resume only the action it names. Outcomes for different actions can arrive in any order.

Create the checkpoint only from the governed result. Do not add the VeriProof API key, provider credentials, callback secrets, executable tool objects, or continuation handlers to your stored workflow state.

See Core Human Review for the lifecycle contract and the runnable Rust receiver guide for callback hosting.

Last updated on