import type { GoalState } from "./goal-state.ts"; export type GoalContinuationAction = "continue" | "ask-user" | "finalize" | "stop" | "waiting"; export type GoalContinuationReasonCode = "goal_active" | "goal_completed" | "goal_paused" | "goal_blocked" | "goal_usage_limited" | "goal_budget_limited" | "goal_cancelled" | "stall_limit_reached" | "goal_completion_required" | "acceptance_evidence_required" | "blocked_requirements_present" | "missing_goal_state" | "worker_in_flight" | "tool_task_in_flight" | "worker_wait_timeout" | "lane_sync_conflict" | "lane_sync_required"; export interface GoalContinuationDecision { action: GoalContinuationAction; reasonCode: GoalContinuationReasonCode; message: string; goalId?: string; stallTurns?: number; maxStallTurns?: number; openRequirementIds: readonly string[]; blockedRequirementIds: readonly string[]; satisfiedRequirementIds: readonly string[]; } export interface GoalContinuationSettings { maxStallTurns: number; } export declare function evaluateGoalContinuation(args: { state?: GoalState; settings: GoalContinuationSettings; /** * LaneIds currently queued/running AND tagged with THIS goal's id (see `LaneRecord.goalId`). * When an open requirement is bound (`Requirement.boundLaneId`) to one of these lanes, the * goal is WAITING on that worker rather than stalled or ready for another pass: the loop must not * submit a hollow continuation prompt (which would waste a turn while no parent work can advance), * and the idle scheduler must not race a re-dispatch against the same open requirement. Optional * so every pre-existing (in-flight-unaware) caller keeps compiling and behaving unchanged. */ inFlightGoalLaneIds?: ReadonlySet; /** * Current time as an ISO string, paired with `maxWorkerWaitMs` to detect a bound in-flight * requirement that has hung past its deadline (see below). Optional so every pre-existing * caller that omits it keeps behaving byte-identically -- the goal waits indefinitely, exactly * as before this field existed. */ now?: string; /** * Maximum milliseconds a bound in-flight requirement (`Requirement.boundAt`) may wait before * this returns `action:"continue"`/`reasonCode:"worker_wait_timeout"` for autonomous recovery * instead of `"waiting"` -- a worker that is alive-but-hung past its deadline must not wait * forever. Only takes effect when BOTH `now` and this are supplied; recovery fires only once EVERY * bound-in-flight open requirement has individually passed `boundAt + maxWorkerWaitMs`, so a * goal with a mix of fresh and stale bindings keeps waiting on the fresh one. */ maxWorkerWaitMs?: number; /** * Bound lanes (`Requirement.boundLaneId` -- SAME id-space as `inFlightGoalLaneIds`, not the raw * worktree-sync `laneKey`) whose worktree-sync lane has a rebase stopped on conflicts * (`LaneFacts.rebaseInProgress`). The caller (`goal-runtime-snapshot.ts`) is responsible for * translating live per-worktree-lane status into this id-space by matching each status entry's * own `boundLaneId` against the requirement -- this function stays pure and never resolves a * worktree laneKey itself, exactly like `inFlightGoalLaneIds` never resolves a tmux job id. * Checked BEFORE the waiting branch (see `lane_sync_conflict` below): a stalled-but-conflicted * worker must get the resolve directive, not silently wait forever. Optional so every * pre-existing caller keeps compiling and behaving byte-identically when omitted or empty. */ laneSyncConflictLaneKeys?: ReadonlySet; /** * Bound lanes (`Requirement.boundLaneId`, same id-space note as {@link laneSyncConflictLaneKeys}) * whose worktree-sync lane is stale and must sync with current main before further work * (`sync_required`, i.e. NOT already covered by `laneSyncConflictLaneKeys` -- a lane with a * rebase in progress is reported as a conflict, never double-counted here). Checked BEFORE the * waiting branch, same precedence rationale as above. Optional so every pre-existing caller keeps * compiling and behaving byte-identically when omitted or empty. */ syncRequiredLaneKeys?: ReadonlySet; /** * Background tool_task ids that are still running and cited by this goal's evidence or by * linked open task_steps. The loop must wait for those terminals the same way it waits on * a bound worker — a handoff stub is not completion. */ inFlightToolTaskIds?: ReadonlySet; }): GoalContinuationDecision; //# sourceMappingURL=goal-continuation-controller.d.ts.map