Main event stream#519
Open
fkukuck wants to merge 6 commits into
Open
Conversation
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR Summary
This PR adds the first durable main event stream: a server-wide, coarse lifecycle log stored in SlateDB under
events/main/<seq-ts>.Today,
RunEvents are durable but run-scoped:runs/<run_id>/events/<seq-ts>. They drive projections, run APIs, attach/SSE, and CLI progress, and they go away with the run.global_event_txis only an in-memory live fanout. This branch keeps those systems unchanged and adds a separate internalMainEventStorefor future automation/audit use.Technically, the branch adds:
fabro-types::main_event: typedMainEvent,MainEventEnvelope, lifecycle bodies, and unknown-event preservation.fabro-store::MainEventStore: append/list/subscribe, sequence recovery, and storage under globalevents/main/....fabro-server::main_event_mirror: maps selectedRunEvents into compactfabro.run.*main events.run.createdis mirrored immediately after run creation, before live forwarders exist.forward_run_events_to_global.No public API, CLI, SSE, webhook ingestion, automation matching, or listener cursor persistence is added here.
Reviewer FAQ
Is this replacing the run event stream?
No. Run events remain canonical for per-run detail, projections, APIs, attach/SSE, and CLI progress. Main events are a compact global mirror for cross-run consumers.
Why a second stream?
Run events are scoped to one run and deleted with that run. Automation triggers and audit need a durable server-wide stream that can survive run deletion and be consumed globally.
Why not use
global_event_tx?global_event_txis live-only memory fanout. It has no replay, no persistence, and no recovery after restart.What gets mirrored?
Only coarse lifecycle events: created, started, running, completed, failed, cancelled, paused, unpaused.
What is intentionally not mirrored?
Stage, agent, tool, transcript, sandbox, detailed progress events, full graphs/settings/patches/tool output, and
run.cancel.requested.How is cancellation represented?
Terminal cancellation still arrives as
run.failedwithFailureReason::Cancelled; the main stream maps that tofabro.run.cancelled.Who owns filtering policy?
fabro-server.fabro-storeonly stores and replaysMainEvents; it does not decide which run events matter.What happens if mirroring fails during live execution?
The failure is logged and normal run event forwarding continues. This PR does not make automation correctness guarantees yet.
Does deleting a run delete main events?
No. Run deletion remains under
runs/<run_id>/...; main events live underevents/main/....Verification
Focused tests cover serde, storage/recovery/delete behavior, mapper behavior, and server mirroring. Format and clippy passed.