V207: job runs, the table (dev_docs/plans/2026-10-03-job-runs.md, §3.1 and §14).
A run is a durable record of one logical piece of long work — a backfill,
a reconcile of one library, later a broadcast or an import — that Oban executes
batch by batch and an admin can watch, pause, resume, cancel and retry. One
table, phoenix_kit_job_runs:
- identity —
kind,module,scope_type/scope_uuid(a library, or neither for the site) and atitlefixed at start; state—queued,running,pausing,paused,cancelling,completed,failed,cancelled;- progress —
done,failed_count,total(NULL when unknown) and thecursorthe next batch resumes from; - attribution —
mode(manual,auto,cron,script) and who started, paused and cancelled it; - the execution protocol (§14 R1, R2, R5) —
generation(every dispatch bumps it; an Oban job of an older generation is inert),claim_tokenandclaimed_at(a batch holds the run while it works),claim_owner(queuefor an Oban batch,inlinefor a script — the sweeper judges the two differently; a script keeps it between its batches too),wake_at(when the next batch should start, after a delay),interruptions(batches that were interrupted and run again: the counts of such a run are approximate),owner_token(which script invocation owns the run between its batches — another invocation is refused while that owner's lease stands),oban_job_id(the current dispatch),restart_seq/restart_ack(a trigger that arrived, and the last one a batch has seen),rescuesandlast_rescued_at(the sweeper's durable budget) andheartbeat_at.
One active run per kind and scope, by a partial unique index over the five
active states. pausing and cancelling are active on purpose: a retry or a
new run cannot start while the old one is still draining its batch.
There are no foreign keys: a run must outlive what it was about (a purged
library) and who started it (a deleted user), the same choice V206 made for
owner_uuid.
Nothing is copied, moved or rewritten; the table starts empty.
Locks
CREATE TABLE and CREATE INDEX on a table nothing references. Re-runnable.
Summary
Functions
The states of a run that has not finished: at most one per kind and scope.
Rolls V207 back: the runs are only history, so the table simply goes.
The states a run can be in.