Auto-Caption Runs
The audit trail for automated captioning batches — run status, per-media outcomes, and failure reasons.
This is where you go after captioning has already happened, to find out what it did and what it failed on. A run is one batch sweep: it takes the media documents eligible for a caption, up to the configured batch size, dispatches a caption job per document, and records the outcome of each one. The batch size is a cap, so a run is not necessarily the whole backlog — the nightly window sets its own size from the estimator's plan rather than using the configured one.
The list has no nav entry; reach it by typing /auto-caption-runs. Individual runs do have links: from the run id in Recent caption activity on Stats, and from the View run details action on a caption notification in the bell drawer. The list page is what you want when you are working backwards from "captioning has been off for two days" rather than forwards from a specific alert.
/settings/auto-caption-runs/<runId> is an old address for the detail page. It still works, and redirects straight here — the run detail has one home.
For what the sweep is actually doing between these records — queue topology, executor host, window semantics, retention — see docs/architecture/auto-caption-operations.md.
Runs list (/auto-caption-runs)
The fifty most recent runs, newest first, as one table. Only the Run ID cell is a link, even though the blurb above the table says to click the run.
Columns are Status, Mode, Started, Duration, then the three counts (Queued, Completed, Failed) and Run ID. Started renders in your local time. Duration is written as 1h 4m 12s, dropping the leading units when they are zero — a short run reads simply 47s — and an unfinished run reads "in progress". The Failed column is failures and cancellations added together, so a run you stopped by hand contributes to it.
Status is derived, not stored verbatim:
| Badge | What it means |
|---|---|
| In progress | Still dispatching |
| Empty | Found nothing eligible to caption |
| Completed | Finished with no failures |
| Completed with issues | Finished, some jobs failed or were cancelled |
| Failed | Finished with zero completions and at least one failure or cancellation |
Empty is a success, not an error. It means the sweep ran and found nothing to do — every candidate was filtered out by the eligibility pipeline below, whether because it already had a usable caption, because a caption job for it was already in flight, or because its job key was a duplicate. A long run of Empty rows is the pipeline being caught up.
Failed counts cancellations too, because the badge is derived from the same failures-plus-cancellations total as the column. A run you stopped by hand before anything completed therefore reads Failed, not "stopped" — the list has no badge for that.
Mode is not a reliable "who started this". It reads manual both for a run you started by hand and for the caption sweep the nightly automation window kicks off — the two go through different entry points, but both stamp every run they create manual. scheduled is written only when the internal caption endpoint is driven by a non-manual trigger. If you need to know which nightly window a run belongs to, match it up by its start time rather than trusting this column.
Run detail (/auto-caption-runs/$runId)
Open a run id from the list, from Stats, or from a notification.
The header carries the status badge, the run id, and three stamps — Started, Completed, Total duration. The line above the title reads Manual auto-caption run or Scheduled auto-caption run, mirroring the Mode column on the list — and inheriting the same caveat: a nightly window's caption run is stamped manual, so that line will read "Manual" on it too.
Stopping a live run
While a run is still going, a red Stop run button sits beside the run id. It disappears once the run reaches a terminal state, so its absence means the run is already finished.
It is not a hard kill, and the confirmation says so: queued caption jobs are cancelled, jobs already in flight are left to finish on their own. Expect a stopped run to keep gaining completions for a while afterwards, and expect the cancelled jobs to land in the Failed column on the list.
The counters
Four cards: Queued, Media docs, Completed, Failed. Queued is jobs dispatched; Media docs is how many media documents this run attached, which is the number the tiles below correspond to.
Completed and Failed are buttons, not just numbers. Press one to filter the media list below to that outcome, press it again to clear. Failed also brings in cancelled media, matching the Failed column on the list page. This is the fastest route to "show me only what broke" on a large run.
A second row breaks the run down by platform — Reddit, Instagram, Telegram, and an Other card that only appears when something did not fit those three.
Eligibility query
A collapsed panel showing the four filtering steps a sweep uses to decide what to caption: non-archived media, minus anything with an in-progress caption job, minus duplicate job keys, minus anything that already has a caption matching the current configuration fingerprint.
It describes the pipeline as it exists now, not the query this particular run ran. It is the same four steps on every run detail page, with placeholders where the per-page values would go. Read it as documentation of why a media document was or was not picked up — not as a record of this run.
Media docs in this run
One tile per media document the run dispatched. Each shows the preview, the platform, the caption outcome (completed, failed, cancelled, or processing), the media id and duration, the source key and author, the caption job id, and the post date.
A failed tile carries its own "Failure reason:" panel with the message the caption job recorded. That message is the first thing to read on any failure — it distinguishes an LM Studio timeout from a media document that could not be fetched at all, and the two need completely different fixes.
Below each tile, Show / Hide expands the per-job outcomes attached to that media document. There is usually one, but a retried media document has several, and this is where you see them separately: job id, status, the stage it reached, how long it took, and when it started and ended.
The tiles are fetched after the summary, so the header and counters paint first and the tiles fill in behind skeletons a moment later. On a run with hundreds of media that gap is noticeable and expected.
How runs get created
Two things create a run, and neither of them is the one people reach for first:
- Start Auto-Captioning on Settings → Captioning. This is the manual trigger. It is single-flight: press it while a manual run is still going and you get "A manual auto-caption run is already in progress." rather than a second run. If nothing is eligible, the run is still recorded — with status Empty.
- The nightly automation window. When the window opens it sizes a caption batch and dispatches it as a run of its own. Configure the window on Settings → Automation.
Queue captioning on the Caption Gaps page does not create a run. It starts an individual caption job per selected media document, with no run to group them, so work you queue there will never appear on this screen. Look for those on Stats' Recent caption activity, where they show up individually as type Manual.