mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-20 00:11:34 +00:00
The `WorkflowRunCompleted` / `WorkflowRunFailed` event was emitted from `EventLifecycle::on_run_end`, a callback the executor fires at the end of the EXECUTE phase. But the run isn't done at that point — RETRO and FINALIZE still need to run, and FINALIZE writes the meta branch's finalize commit. Observers that treat the event as "done" (CLI attach, daemon SSE consumers) could observe terminal state and act on it before the worker flushed its remaining writes. The recovery scenario test exposed this: it deletes the meta branch right after `fabro run` returns, then asserts the branch is empty. On loaded CI runners the worker's finalize commit landed after the delete, recreating the branch and failing the assertion. Move the terminal event emission to `pipeline::finalize::finalize`, after `write_finalize_commit`. The lifecycle's `on_run_end` overrides for event and git become empty (deleted — the trait already provides a no-op default). Three pieces of cross-cutting state (`final_patch`, `captured_artifact_count`, the dead `EventLifecycle` reads of `last_git_sha`) only existed to ferry data from EXECUTE to the terminal event; deleted those too. The aggregator collapses to a one-line delegate to `hook.on_run_end`. `write_finalize_commit` now takes the conclusion as a parameter and injects it into the projection copy, since the terminal event hasn't run through the run store yet when the meta branch is written. `build_terminal_event` is `pub(crate)` so `test_support` helpers (which stop at EXECUTE) can mirror the production payload. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| it | ||