TanstackTemplate
Reference Contracts

Durable AI Job Lifecycle Protocol

Candidate: durable-ai-job-lifecycle

Target owner: future-shared-package

Target package: ai-media-product-kit/packages/jobs

Purpose

This protocol freezes the portable lifecycle for long-running AI media work before job code moves out of this vertical template. The goal is to let future image, avatar, product-photo, and batch media products reuse the same claim, submit, collect, complete, fail, retry, delete, and polling contract without inheriting one product's presets, prompt versions, library copy, or storage namespaces.

This is a contract freeze only. The current D1 repository, route handlers, UI copy, and conversion execution services stay product-local until a second template proves the same lifecycle.

Shared Contract

The future job package should own schemas and validators for:

  • durable job status labels
  • execution timestamps and attempt counters
  • claim and lock envelopes
  • submitted async provider references
  • poll scheduling hints
  • completion envelopes
  • terminal failure envelopes
  • retry eligibility envelopes
  • delete and cleanup summaries
  • public-safe ops summaries

The shared contract may define lifecycle stage names, idempotency expectations, terminal-state rules, and safe summary shape. It must not define product settings, preset validation, prompt versions, quota policy, provider SDK calls, or public result copy.

Lifecycle Boundary

A portable job lifecycle separates persisted statuses from derived phases.

Persisted statuses:

  • pending: product input has passed policy and is ready to claim
  • running: product work is locked for execution or collection
  • succeeded: at least one persisted output exists
  • failed: execution or collection ended in a recoverable terminal failure
  • blocked: product policy or entitlement denied the request before runtime

Derived phases:

  • submitted: provider accepted async work and collection is required; this can be stored as running plus a server-only provider reference
  • deleted: product removed the visible job and queued best-effort cleanup

Products may store submitted as a running job with provider metadata if the runtime only needs a smaller status set. The shared evidence contract still needs to distinguish submitted async work from active synchronous execution.

Claim And Collection Rules

Portable rules:

  • claims must be lock-scoped and time-bounded
  • claiming a terminal job must fail closed
  • only pending jobs can be claimed for first execution
  • submitted async jobs must not be submitted to the provider a second time
  • async provider references must stay server-only or redacted in public evidence
  • collection can return pending, completed, or failed
  • poll hints are advisory and must be bounded by product configuration
  • attempt counts must be monotonic
  • terminal timestamps must be explicit
  • retry must create a new job or record a new attempt without overwriting the original terminal evidence
  • duplicate queue messages, lock races, duplicate webhooks, and unknown provider callbacks must be reported as skipped or no-op results without leaking provider internals

Product adapters keep D1 table names, concrete SQL, provider reference storage, queue mode, scheduled entrypoints, route composition, and result copy.

Product Adapters

Each product template keeps adapters for:

  • mapping product settings into a job payload
  • enforcing entitlement, quota, and safety gates
  • writing product-specific D1 rows
  • persisting media assets
  • submitting provider work
  • collecting provider work
  • rendering progress states and library language
  • deciding retry and reuse UX

Adapters emit lifecycle and summary envelopes into the shared contract. The shared package validates and reports; it does not run jobs.

Privacy Rules

The shared validators must reject artifacts containing:

  • API tokens, bearer tokens, webhook secrets, or provider credentials
  • raw actor, user, account, workspace, provider job, or owner ids
  • R2 object keys, provider input keys, output keys, or signed URLs
  • raw provider response bodies, gateway metadata, image bytes, or private URLs
  • product prompt text, preset copy, or public visual identity

Artifacts may include status labels, lifecycle stage names, redacted job references, aggregate counts, public failure categories, UTC timestamps, attempt counts, and reviewer-owned evidence labels.

Acceptance Fixture

The product-free fixture lives at durable-ai-job-lifecycle.media-fixture.json. Before extraction, the fixture must keep these constraints true:

  • it references durable-ai-job-lifecycle
  • it names ai-media-product-kit/packages/jobs as the target
  • it includes draft, claim, submit, collect, terminal, retry, delete, and ops summary stages
  • it keeps product adapters separate from shared validators
  • it contains no vertical product name, raw provider id, storage key, token marker, or actor identifier

Extraction Sequence

  1. Keep current job repository, execution service, route handlers, and UI inside the product template.
  2. Build or start a second AI/media product that uses the same lifecycle with different settings, provider behavior, and public copy.
  3. Move only lifecycle schemas, lock envelope validation, terminal-state rules, retry/delete summary validation, privacy scanning, and report formatting into the media kit.
  4. Keep database migrations, provider submission, product settings, quota policy, prompt versions, and UI language inside each product.
  5. Re-run both product templates end to end before claiming the extraction complete.

Non-Goals

  • No shared queue provider.
  • No shared D1 table ownership.
  • No shared quota policy.
  • No provider SDK execution.
  • No product-specific progress copy.
  • No guarantee that submitted async jobs are completed without a product-owned collector or webhook path.

On this page