- Extract _step() as the single prefill-group + task_extend + decode primitive - _run_generation_loop and run_batch now both call it, so the two cannot drift - run_batch now records prefix hashes (paged mode) and uses input order for decode, matching the loop thread