Skip to main content

Module loop_runtime

Module loop_runtime 

Source
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§

DispatchCtx
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.
GlobalJournalPath
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.
LoopBudget
Walk-level iteration budget. Prevents unbounded loops when sessions never produce termination events.
LoopOutcome
The result of a complete walk.
ProjectJournalPath
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.
UnitResult
The result of closing a single unit (after its session produced a TerminationReason event).

Enums§

CloseOutcome
Outcome of queue.close() for a single unit.
LoopError
Errors returned by the loop runtime.
NextStep
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 next either returns the next unit to dispatch or None to 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.