/**
 * Orchestrator loop runner.
 *
 * Drives `decideNextActions → dispatch* → replay → repeat` until either
 * the run reaches a terminal status or the orchestrator returns no
 * actions (which on a non-terminal run means we're paused on an open
 * `waitCreated`).
 *
 * Per-tick dispatch model (v0.1.3+):
 *   1. Split ready actions into `dispatch*` (gate / work) and `complete*`
 *      (settle node / run).  The two phases have different concurrency
 *      semantics — dispatch can race, settles must not.
 *   2. Within the dispatch phase: cap concurrency by `defaults.maxConcurrency`
 *      (default 4) and enforce per-bot serialization (one in-flight subagent
 *      per bot within a tick).  Deferred dispatches just stay in the next
 *      tick's ready set; no separate scheduling state needed.
 *   3. Run dispatches via `Promise.allSettled` so a sibling throwing doesn't
 *      starve the rest.  After settle, replay fresh and patch any non-terminal
 *      activity with an `activityFailed` (errorClass=fatal, errorCode=
 *      WorkerCrashed; closest fit in the existing enum — see payloads.ts) —
 *      but NEVER write a second terminal if the dispatch already wrote one
 *      before throwing.  If a dispatch throws BEFORE writing `attemptCreated`,
 *      we have no attempt to attach the failure to; the tick returns
 *      `no-progress` rather than re-dispatching the same action forever.
 *   4. Settle actions (`completeNode*` / `completeRun*`) run sequentially so
 *      event log order stays readable and `completeRun*` is never racy.
 *
 * Re-entry: external events (e.g. `waitResolved` written by the lark
 * card handler) don't drive this loop — the caller is responsible for
 * invoking `runLoop` again when it knows new events have landed.  See
 * `src/workflows/fanout.ts` (Slice D-4) for the daemon-side trigger.
 */
import { type Snapshot } from './events/replay.js';
import { type WorkflowRuntimeContext } from './runtime.js';
export type RunLoopStopReason = 'terminal' | 'awaiting-wait' | 'no-progress' | 'max-ticks';
export type RunLoopResult = {
    reason: RunLoopStopReason;
    ticks: number;
    lastSnapshot: Snapshot;
};
export type RunLoopOptions = {
    /**
     * Defensive cap on tick count.  A correctly modeled workflow with N
     * nodes terminates in O(N) ticks; the cap exists to keep buggy
     * orchestrator output from spinning forever.  Default 1000.
     */
    maxTicks?: number;
};
export declare function runLoop(ctx: WorkflowRuntimeContext, options?: RunLoopOptions): Promise<RunLoopResult>;
//# sourceMappingURL=loop.d.ts.map