FabroHooks always declares required run finalization instead of only
when the run publishes or checkpoints. Every run takes one path, the
best-effort diff branch in run_finished goes away, and a fork always
declares what its worker's hooks will declare on resume, so the fork no
longer carries its source's flag across.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A failed checkpoint cancels the run, so Petri recorded it as cancelled
and the worker overrode its own outcome in memory. Runs that checkpoint
now declare required finalization, and finalize_run rejects with
checkpoint_failed before publishing. The projection and the engine
outcome report a cancelled finish carrying that failure as a workflow
failure with the checkpoint's message, and the in-memory override is
gone. A run whose checkpoint failed is never published.
Retry a host failure that storage rejects with a short backoff, so a
brief storage fault does not leave the run active and holding its
scheduler slot. A failure that never commits still leaves the run's
status alone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Track Petri main now that required run finalization has merged there,
read workflow execution from the engine state, resume the failed-publication
regression with its admitted workflow, and keep the worker lifecycle helper
usable for rejected appends.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>