-- Bound how many times a permanently-failing upload can be re-processed. -- -- Without this, one poisoned row is an outage. The upload row is committed BEFORE compression -- starts, `derivatives_rev` defaults to 0, and `set_derivatives_rev` only runs on success — so -- a row whose processing kills the container survives at rev 0, the unconditional startup -- backfill re-selects it on the next boot, and `restart: unless-stopped` turns that into an -- infinite kill loop. Every restart also drops every SSE stream and truncates every in-flight -- upload. That was reachable via a single large PNG (see services/compression.rs), but the -- shape is general: any input that can kill or hang the worker repeats forever. -- -- The counter is incremented WRITE-AHEAD, before the work is attempted, because the failure -- mode being defended against is a SIGKILL — no error is returned, no handler runs, no Drop -- fires. A counter bumped in an error path increments zero times per crash and changes nothing. ALTER TABLE upload ADD COLUMN IF NOT EXISTS derivative_attempts SMALLINT NOT NULL DEFAULT 0; -- Last failure text, so a row that has given up can be diagnosed without reproducing it. -- Nothing reads this in code; it exists for the operator. ALTER TABLE upload ADD COLUMN IF NOT EXISTS derivative_last_error TEXT; -- Serves the backfill selection, which now filters on both columns. CREATE INDEX IF NOT EXISTS idx_upload_derivative_backfill ON upload (derivatives_rev, derivative_attempts) WHERE deleted_at IS NULL;