> Canonical guide: https://developers.foxlight.ai/build/guides/durable-jobs/
> Contract snapshots: Skulk 2.0.0 (b0af39c79b6b7102b2478062904f1d7cc8619975); SDK 0.4.0 (31bb090b8f64689f87514e48385e22b6ad94a6c2). Check the installed runtime when versions differ.

# Build a durable job

A video render may occupy a model for minutes. Its initiating capability call should reserve intent and return quickly; a background worker owns submission and observation. This is the pattern used by [Video Studio](https://developers.foxlight.ai/build/tutorials/video-studio/render-lifecycle/).

## 1. Define the operation

Use `operations.operation_descriptor` with your typed input and result schemas. Declare operation bounds in the installation manifest. The SDK supplies a verb envelope for `plan`, `start`, `status`, `list`, `log` and `cancel`; your backend adapter implements actual work.

## 2. Reserve identity before effects

An operation is scoped to the installed node, descriptor and canonical input digest. The same id and input address the existing operation. Reusing the id for a different input is refused. Allocate a fresh id for intentionally different work, not for a retry of the same intent.

## 3. Submit and record the backend reference

Use `OperationJournal`, `OperationRunner` and `OperationService` with a `JobAdapter`. Persist the external job reference once known. A timeout after sending is potentially uncertain: do not automatically submit another job. Distinguish definite pre-send refusal, uncertain acceptance and accepted work.

## 4. Observe, cancel and reconcile

Translate backend states to operation states and retain actionable failures. Cancellation requests the backend to stop, then observes its terminal outcome; receiving an HTTP acknowledgement is not proof that inference ended. Restart reconciles interrupted records through saved references instead of replaying submission.

## 5. Keep media separate

Return metadata and artifact references in bounded results. The SDK caps an operation result at 8 KiB; video or audio bytes do not belong in a JSON result, replicated State or an event log. Your application owns artifact retrieval, integrity checks and retention.

[Operations guide](https://developers.foxlight.ai/build/sdk/operations/) describes limits and states. [Reference](https://developers.foxlight.ai/build/sdk/reference/operations/) provides exact constructor and adapter signatures.
