Re-derive a cell's rows without any input having changed — the code moved, not the data.
The frontier says "an input moved, redo this". That is the wrong sentence for a changed prompt, a fixed fold, or a suspect result: the inputs are identical and the function is not. Mechanically the mark is the same, but the reason matters, and a job is the honest place to put it.
Selecting what to redo
Whole cell, and everything below it:
%{"cell" => "budget_rollups"} |> ReactiveDag.ReprocessWorker.new() |> Oban.insert()A slice — the common case, and what slice exists for:
%{"cell" => "budget_rollups", "where" => %{"fiscal_year" => "FY25"}}
|> ReactiveDag.ReprocessWorker.new()
|> Oban.insert()Or exact keys, when a UI has already chosen them:
%{"cell" => "budget_rollups", "keys" => ["gf|FY25", "water|FY25"]}Whole-cell means everything downstream
A "*" claim propagates :all, so reprocessing a cell re-derives every cell
beneath it. That is usually what "the code changed" means and occasionally
much more work than intended — a slice or an explicit key list keeps it
proportional, which is the whole point of the engine.
The fingerprint still applies
A per_key node skips rows whose declared inputs have not moved, and after a
prompt change they have not. So reprocessing such a node marks its keys and
the recompute skips them — the job reports how many were claimed against how
many actually moved, so a no-op is visible rather than mistaken for success.
Making the recompute ignore its fingerprint is a separate, deliberate change.
Telemetry
[:reactive_dag, :reprocess, :stop] with claimed and changed, so a
dashboard can say "queued 412, 88 actually moved".