fabro/lib/foundation
Bryan Helmkamp 523f831a7a
Serve a Petri run's events as one stream with a stream_seq cursor
`GET /runs/{id}/events` and `GET /runs/{id}/attach` serve a Petri run's
public events and Fabro's platform records as one ordered stream in a
Fabro envelope (`RunStreamItem`: `run_id`, `stream_seq`, `kind`, `id`,
`recorded_at`, `item`), read from the projector's `petri_stream` table.
The cursor is `stream_seq` (`?after=`); the item's own identity (the
Petri `EventId` as `<log>/<seq>/<index>`, or the platform record's seq)
travels beside it for deduplication. A legacy run keeps its envelope on
the same endpoints; the OpenAPI response is the union of the two lists,
and the stream list reports Petri's `EVENT_CONTRACT_VERSION`.

The attached stream follows the projector's commit signal (a wake-up,
with a poll as the fallback) and ends after the platform record of the
run's terminal lifecycle transition, the analog of the legacy stream's
`run.completed`, or a bounded grace after the projection went terminal.

`RunSpec.engine` (`RunEngine`, `PetriAdmission`, `PetriGraphRef`) is
named in the spec and reuses the Rust types. `fabro-client` matches the
union and adds `list_run_stream`, `list_run_stream_page` and
`attach_run_stream`.

A server test attaches to a two-branch parallel run, disconnects once
both branches started, records a platform notice while both branch
scripts run, reconnects from the last `stream_seq`, and checks the
union is the whole stream: every item once, in order, no gap, no
duplicate, the notice between the branch events, and the same as the
paged listing. The Petri scenarios capture their settled projection and
stream as JSON fixtures for the web app under
`FABRO_CAPTURE_PETRI_FIXTURES`.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-18 00:47:26 -04:00
..
build-support refactor: organize crates into three layers 2026-07-23 17:59:34 -04:00
fabro-api Serve a Petri run's events as one stream with a stream_seq cursor 2026-09-18 00:47:26 -04:00
fabro-auth Name built-in providers through lithos catalog::builtin 2026-09-10 09:48:37 -06:00
fabro-client Serve a Petri run's events as one stream with a stream_seq cursor 2026-09-18 00:47:26 -04:00
fabro-config Add the engine flag and record the engine on the run spec 2026-09-17 20:02:47 -04:00
fabro-core Harden succeed failure policy routing 2026-08-26 09:13:04 -04:00
fabro-db Add platform records and the Petri projection tables 2026-09-17 21:46:21 -04:00
fabro-dev Document the catalog overlay without the metadata.fabro namespace 2026-09-09 23:26:48 -06:00
fabro-http Depend on lithos-llm and the published twin-openai crate 2026-09-09 17:26:57 -06:00
fabro-macros refactor: organize crates into three layers 2026-07-23 17:59:34 -04:00
fabro-oauth refactor: organize crates into three layers 2026-07-23 17:59:34 -04:00
fabro-options-metadata refactor: organize crates into three layers 2026-07-23 17:59:34 -04:00
fabro-proc Consolidate server Git subprocess ownership 2026-09-11 17:36:40 -06:00
fabro-redact Give the checkout its GitHub credentials through the driver's store 2026-09-11 10:02:01 -06:00
fabro-static Carry Petri's sandbox plugin variables into workers and test servers 2026-09-17 21:20:22 -04:00
fabro-telemetry refactor: organize crates into three layers 2026-07-23 17:59:34 -04:00
fabro-template Simplify model stylesheet template plumbing 2026-08-25 18:54:06 -04:00
fabro-test Carry Petri's sandbox plugin variables into workers and test servers 2026-09-17 21:20:22 -04:00
fabro-types Serve a Petri run's events as one stream with a stream_seq cursor 2026-09-18 00:47:26 -04:00
fabro-util Neutralize runtime for_each labels before display 2026-07-28 19:52:59 -04:00
fabro-vault refactor: organize crates into three layers 2026-07-23 17:59:34 -04:00