Per-step retries are the right unit, and they pull a second requirement in behind them: each step has to leave a record of what it produced and from which input, or a retry can silently redo work against a newer version of the document than the step before it saw. We run intake this way for a house — assessor harvest, facade vision, sketch reconciliation, compression — and the thing that made retries safe wasn't the queue, it was giving every step's output a source and a version, so a re-run that disagrees with the earlier run shows up as a conflict instead of overwriting it.