mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-10-12 03:51:01 +00:00
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>
59 lines
3.7 KiB
Markdown
59 lines
3.7 KiB
Markdown
# Required run finalization
|
|
|
|
Petri owns the durable run result. Fabro declares required finalization for
|
|
every run and implements it in `FabroHooks::finalize_run`, so a resume or a
|
|
fork always matches the stored declaration. A failed checkpoint rejects with
|
|
`checkpoint_failed` and skips publication. The checkpoint failure cancelled the
|
|
run, so Petri may commit `cancelled`; Fabro reports that finish as a workflow
|
|
failure with the checkpoint's message.
|
|
For successful workflow execution this prepares the final diff, then uses the
|
|
existing publisher to retry the push and reconcile or create the pull request.
|
|
A preparation or publication error rejects with `publish_failed` and a rendered
|
|
message. Missing branch, checkpoint or workspace evidence is a rejection.
|
|
Failed or cancelled execution skips publication; its diff remains best effort.
|
|
Local workflow run-end hooks remain observational.
|
|
|
|
The coordinator awaits finalization and cleanup before committing `run.finished`.
|
|
Until that record, the run stays active without a conclusion, even when every
|
|
stage has succeeded. The run stream, API projection, managed server status,
|
|
worker return and CLI verdict use the committed overall status and structured
|
|
finalization failure. Stage outcomes, metrics and invocation results keep their
|
|
execution meaning. Successful stages stay successful when publication fails.
|
|
|
|
Both HTTP and in-process worker transports store the finish before settling
|
|
managed status. A rejected append cannot settle the run. The later platform
|
|
terminal lifecycle record acknowledges the same outcome; it cannot replace a
|
|
terminal result or conclusion. Early worker failures without a Petri finish
|
|
still end through their committed platform lifecycle record. Run scope,
|
|
authorization and lease ownership checks remain required for every worker write.
|
|
|
|
## Recovery and stored history
|
|
|
|
This integration requires a Petri with required run finalization (coordinator
|
|
format 9) and event contract 6. Petri retains its strict stored-format policy: version-8 coordinator
|
|
logs cannot resume, inspect or replay with this engine. Fabro does not rewrite
|
|
source history or relax that policy. Existing materialized views and stream
|
|
rows remain stored; a projector replay failure holds Petri positions and reports
|
|
incomplete record health. A historical run without a materialized view cannot
|
|
recover its old Petri stage evidence through the new engine. Operators requiring
|
|
inspection or recovery of old execution logs must keep the prior compatible
|
|
binary and its storage backup.
|
|
|
|
Existing incorrect historical publication-success projections are not repaired
|
|
by this change. Consumed cursors and immutable conclusions remain unchanged;
|
|
historical-view repair requires a separate, bounded process over preserved
|
|
source records. No publication is invoked by projection or replay.
|
|
|
|
A committed resume returns the same overall result without publishing again.
|
|
A fork declares required finalization while seeding its records, as every
|
|
Fabro run does; its worker restores the actual publication hooks before resume.
|
|
Unfinished recovery must restore the same finalization requirement. Petri may
|
|
call the restored finalizer again after interruption, including a crash after
|
|
the callback returns but before the terminal record commits. Existing GitHub
|
|
reconciliation is retained; this contract does not provide independent retry
|
|
orchestration or guarantee external-effect deduplication after every crash.
|
|
Lost terminal-execution workspaces are not recreated for finalization. Fabro
|
|
rejects publication when it cannot establish the required evidence. Push
|
|
attempts retain their existing five-minute timeout; this integration adds no
|
|
overall finalizer deadline. Cancellation arriving after
|
|
execution ends does not interrupt Petri's awaited finalizer.
|