Skip to content
Skip to content

Reconcile occurrences and replay

If a scheduled run is missed or its response is lost, find the original run and its job instead of starting a new one.

Updated

Start with a missed or lost occurrence

Suppose the 08:00 daily review trigger fired, but the submission response was lost. Find the 08:00 occurrence record and its fixed input, template version and submission key. If it already has a job reference, read that job. If the response is unknown, reconcile the original request before deciding whether a retry is needed. Do not create a second 08:00 occurrence because the first response disappeared.

An occurrence record gives you one stable subject for recovery. A retry time, delivery-attempt number or new trigger does not create a new occurrence identity.

Find the intended run first

An occurrence is one intended run of your customer-operated template. Keep its identity in the scheduler or event handler you already use. It is not a Compute job, a delivery attempt or permission to spend.

Before retrying, find the original occurrence record. Check its template version, intended time or business event, fixed input, submission key and any returned job reference. Recover from that record rather than treating every trigger as new work.

Keep the prepared brief with the occurrence: frozen instructions and rubric, input snapshot, stable IDs, operation and output schema, required evidence and acceptance rule. A replay preserves those identities; a changed task or input is new scoped work.

Keep a stable occurrence record

For timed work, use the intended occurrence instant and template version. For event-driven work, use the authenticated business-event identity and its account scope. Keep the account, intended time or event identity, template version, fixed input snapshot, submission key, current quote, approval reference, job or batch reference, result and delivery outcome together. A retry time or delivery-attempt number must not change the occurrence's identity.

This Python example derives a local identifier from synthetic values. It uses only the standard library and makes no request. It is not a Lithi request schema or a substitute for API idempotency.

import hashlib
import json

identity = ["sample-account", "daily-review", "version-1", "2026-09-09T08:00:00Z"]
encoded = json.dumps(identity, ensure_ascii=False, separators=(",", ":")).encode("utf-8")
occurrence_id = "occ-" + hashlib.sha256(encoded).hexdigest()
retry_id = "occ-" + hashlib.sha256(encoded).hexdigest()
assert occurrence_id == retry_id
changed = [*identity[:-1], "2026-09-10T08:00:00Z"]
changed_bytes = json.dumps(changed, ensure_ascii=False, separators=(",", ":")).encode("utf-8")
assert occurrence_id != "occ-" + hashlib.sha256(changed_bytes).hexdigest()
print(json.dumps({"same_on_retry": occurrence_id == retry_id, "identifier_length": len(occurrence_id)}))

The output reports same_on_retry: true and an identifier length of 68. Keep this local label associated with the actual native submission; do not append an invented occurrence field to the API body.

Choose the recovery action

What happenedAction
Read an admitted job or accepted resultUse its existing reference and current authorized read path. This is not another submission.
Recover a lost submission responseReconcile the original request; retry its exact body and key only under the operation's retry rules.
Deliver an accepted result againRecover the destination operation against that same result.
Run a changed task or new inputReview a new occurrence, quote, and applicable approval.
Recover a missed occurrenceRead the scheduler's allowed-lateness and catch-up settings, then choose a finite set of occurrences that still have fixed input and a useful outcome. Each selected occurrence still needs current quote and approval.

The native idempotency guide owns the API's key scope and retry behavior. Do not assume that a local occurrence record extends the server's retention window indefinitely.

Resolve unknown and conflicting outcomes

A timeout does not establish that submission failed. Check the known job reference or original submission record before creating new work. A missing result may be an access, visibility or completion problem rather than proof that nothing ran.

Keep the exact submitted body and input identity unchanged during reconciliation. If the same local occurrence points to conflicting requests, stop and compare them. Do not assign a fresh key merely to bypass the conflict.

For an expired quote, first establish whether its request was already admitted. Existing accepted work remains a retrieval or delivery task. Work that was not admitted needs a valid quote and applicable approval before another submission.

Recover missed occurrences deliberately

Read the customer scheduler's pause, allowed-lateness and catch-up settings. Select only missed work that still has a useful outcome and available fixed input. Apply a finite catch-up count and the current approval bound. A missed occurrence is a decision to review; it is not automatic permission to submit.

A new snapshot or changed template is new work, not an exact replay. Keep its lineage to the missed occurrence for your own records, while reviewing its scope and quote separately. Do not turn an outage into submissions beyond the finite catch-up count and current approval bound. An automatic schedule does not authorize a broader prompt, release new data or spend beyond that approval.

Confirm the intended result

A recovered occurrence should point to the original admitted work or an explicit unresolved outcome. Check result integrity, returned schema, coverage, uncertainty, accepted items, exceptions, and destination delivery independently. A successful lookup or matching identifier is not a paid-work completion receipt or a semantic acceptance decision.

Your agent makes the final semantic decision for your work. Lithi records the occurrence, submission, result and defined evidence; it does not turn a replay into approval for a changed prompt, data set, budget ceiling or timing policy.

Physical attempts are not automatically customer billing units. Reconcile the accepted unit defined by the quote and its usage policy. If delivery failed after acceptance, retrieve or redeliver that same result instead of replaying Compute.

Use local or synthetic checks to repeat a trigger and lose a submission response. Confirm that your existing handler preserves the occurrence-to-submission association. If a destination import fails, recover that import without rerunning Compute.

Next, pause and recover customer-scheduled work.

Was this page helpful?