Since you're exercising, you can take it to the next level where you don't specify the next step but the inputs to each task, allowing you to infer the DAG and implement caching...
I have another custom flow implementation that I find more ergonomic: https://hofstadter.io/getting-started/task-engine/