The runner's half of the control plane.
Holds one run's control state, maintains snapshot.json and the subscriber
event stream, and consumes pending requests at event boundaries — never
mid-event. A request that cannot be parsed, names an unknown command, or
targets a run that is no longer current is logged and dropped; nothing
arriving through this transport is ever fatal to a run.
Consumers use PromptRunner.Control, not this module.
A plan with no state directory — an in-memory API run — gets a disabled plane. Embedded use stays free of filesystem side effects, and every function here is a no-op returning the same state.
Summary
Functions
An event boundary: consume every pending request, then rewrite the snapshot.
Marks the run finished. The snapshot survives the runner, so a reader that arrives afterwards sees how it ended rather than a run apparently still in flight.
Folds one canonical event into the snapshot and appends it to the subscriber stream.
Opens the control plane for a run and writes its first snapshot.
Records that a prompt attempt has started, resetting the per-prompt counters.
Appends an entry to the control log.
Records a steer that was actually delivered, and counts it against the budget.
Records a steer the lane refused. Costs no budget and leaves no artifact.
Types
@type t() :: %PromptRunner.Control.Plane{ max_steers: non_neg_integer(), packet_dir: String.t() | nil, prompt_started_mono: integer() | nil, run_started_mono: integer() | nil, snapshot: PromptRunner.Control.Snapshot.t() }
Functions
An event boundary: consume every pending request, then rewrite the snapshot.
Returns the commands the caller has to act on. Only the caller knows how to reach the live renderer, so this decides what was asked for and leaves how to the runner.
@spec close(t(), PromptRunner.Control.Snapshot.status()) :: t()
Marks the run finished. The snapshot survives the runner, so a reader that arrives afterwards sees how it ended rather than a run apparently still in flight.
Folds one canonical event into the snapshot and appends it to the subscriber stream.
Deliberately not persisted here: boundary/1 writes the snapshot once per
event, and rewriting it twice per event doubles the IO for nothing.
Opens the control plane for a run and writes its first snapshot.
packet_dir of nil disables the plane.
Records that a prompt attempt has started, resetting the per-prompt counters.
Appends an entry to the control log.
@spec steer_count(t()) :: non_neg_integer()
Records a steer that was actually delivered, and counts it against the budget.
Called by the runner rather than by boundary/1, because only the runner
knows whether the text reached the session — a steer refused by the lane must
not spend budget or leave an artifact claiming the agent was told something.
Records a steer the lane refused. Costs no budget and leaves no artifact.
@spec view(t()) :: PromptRunner.Control.Snapshot.view()