Expand description
Unified loop runtime primitive for target, megawalk, and megatron drivers.
This module is the generic “walk a queue of units, dispatch sessions, handle termination” engine. Drivers differ only in their Queue and Dispatcher implementations. The runtime itself has no opinion about what a “unit” is (backlog node, fleet project, …) or how sessions are launched.
§Why journal write failure is fatal (contrast with loopcheck.rs)
loopcheck.rs runs as a stop hook: it is a read-only observer that must
never block the session from exiting. Journal writes there are best-effort
(logged to stderr, never propagated as errors) because a failed write
cannot undo a decision the runtime already made.
Here the journal is the observability record of an active walk. If the runtime cannot record that it dispatched a session, an operator watching the log sees nothing and cannot tell whether work is happening. An unobservable walk that continues spending compute (and potentially money) is worse than stopping loudly. The invariant: “The system must handle journal write failure by stopping dispatch loudly; an unobservable walk must not continue spending.”
The global mirror (~/.fno/events.jsonl) is best-effort: a write
failure there is logged to stderr but never fatal, because the project
journal is the authoritative record.
§Source field
Events written by this runtime carry source: "loop", distinct from the
source: "hook" that loopcheck uses. The two streams have different
semantics: hook events are stop-hook decision records; loop events are
walk-level orchestration records. Consumers that aggregate both streams
can use the source field to distinguish them.
§Module naming
The module name starts with loop so that the LOC-ratchet glob
crates/fno-agents/src/loop* counts this file’s LOC toward the ratchet
budget deliberately (alongside loopcheck.rs).
Structs§
- Dispatch
Ctx - Runtime-varying context passed to each Dispatcher::run call. Static configuration (project root, env vars, etc.) lives in the Dispatcher impl.
- Evidence
- Evidence of termination extracted from the project journal.
- Global
Journal Path - Newtype for the global mirror journal path (
~/.fno/events.jsonl). Writes are best-effort only. - Journal
- Append-only event log with a project-authoritative path and a best-effort global mirror.
- Loop
Budget - Walk-level iteration budget. Prevents unbounded loops when sessions never produce termination events.
- Loop
Outcome - The result of a complete walk.
- Project
Journal Path - Newtype for the project-authoritative journal path. Writes are FATAL on failure. Using a distinct type prevents silent positional swap of the two same-type args.
- Unit
- A single unit of work to be dispatched. Drivers map their domain objects (backlog nodes, fleet projects, …) to this common shape.
- Unit
Result - The result of closing a single unit (after its session produced a TerminationReason event).
Enums§
- Close
Outcome - Outcome of queue.close() for a single unit.
- Loop
Error - Errors returned by the loop runtime.
- Next
Step - The richer return type for Queue::next_step(). Used by policy-aware queues (MegawalkQueue) to signal a walk-level pause without returning an error.
Traits§
- Dispatcher
- Launches sessions for units. Stateless with respect to the walk loop; any per-dispatch state is internal to the impl.
- Queue
- Source of work units. Each call to
nexteither returns the next unit to dispatch orNoneto signal that the walk is complete. - Session
- A live session handle returned by a Dispatcher.
Functions§
- run_
loop - Run a walk over the queue until the queue is empty, the budget is exhausted, or the cancel sentinel fires.