Parameterized runs and run configs
What is a run's identity once it takes parameters, and what goes wrong when config is read late?
Once runs take parameters beyond the interval key, the run's identity becomes the tuple (workflow version, interval, parameters). Three consequences follow, all about that tuple being complete.
"Re-run" becomes ambiguous. Re-running with the original parameters is a replay. Re-running with new parameters is a different computation that shares a name. Only the first is safe under the idempotency argument. So parameters must be stored with the run, not read from a config file at execution time. Otherwise a retry six hours later picks up whatever the config says now, and the retry is not a retry. It is the same discipline as banning now(), applied to configuration: any input the task reads that is not pinned to the run makes replay nondeterministic, and configuration is an input.
Config is late binding. A parameter error appears when the run executes, not when the code is deployed. Failure at run time is guaranteed by the design of late binding. Validating parameters at submission moves the failure earlier and is nearly free. It is skipped more often than not.
Parameters must reach provenance. If a parameter changes the output and is not recorded in the output's metadata, the table is a mixture of computations with nothing to tell them apart. This is the same disease as the versioning problem (Safe re-execution) from a second source. The minimum provenance triple (record of where data came from) is interval key, code version and parameter set. Orchestrators natively record only the first.
A run's identity is (version, interval, params); anything read at execution time rather than pinned to the run makes replay a lie.