Implement simulate_crash_restart(core) — a scenario runner over your TaskFlowCore from the core-loop milestone:
1. a = core.submit('alpha', {'op': 1}) and b = core.submit('beta', {'op': 2})
2. deliver once; record the delivered batch
3. SIMULATE CRASH: call core.shutdown() — which must stop intake and requeue everything in-flight back to pending (exactly-once effects make this safe) — and then call core.restart() (adds 'restarted': True to metrics; running again)
4. after restart: deliver, and process(job_id, True) for every delivered job
The function returns {'a': core.status(a), 'b': core.status(b), 'metrics': core.metrics} where both jobs end 'succeeded', and metrics show submitted == 2, succeeded == 2, failed == 0 (the crash requeued; it did not fail anything).
Add shutdown() and restart() to TaskFlowCore: shutdown() moves all in-flight jobs back to pending (running = False); restart() clears drained state and sets metrics['restarted'] = True.
Difficulty: advanced