pub fn run_shadow_cli(args: &[String]) -> ExitCodeExpand description
shadow [-h host] [-p port] --old "<cmd>" --new "<cmd>" [--old-pairs] [--new-flat] [--samples n]
Both sides are whole commands, quoted, because the old path is
whatever the application already runs — a ZRANGE, an LRANGE, a
SMEMBERS — and the new one is an IDX.QUERY. Nothing here knows
which; it compares the two orders of row keys they produce.
Exits non-zero on any divergence, so a cutover script can gate on it without parsing the text.