Skip to content

feat(goal): goal/operate runs are chopped mid-pass by the interactive max_steps — add a goal-scoped step budget #5994

Description

@7jrxt42BxFZo4iAnN4CX

Problem

A goal/operate run is documented as unbounded by default: [goal] max_continuations defaults to 0 = unlimited, and the only terminal stops are completion, blocked, or the opt-in continuation backstop (goal_loop.rs: "Goals are unlimited by default: completion, blocked status, or explicit user control ends the run", DEFAULT_MAX_GOAL_CONTINUATIONS = 0; docs/CONFIGURATION.md "Goal loop").

But a single goal pass is still one turn, and every turn is capped by the interactive [tui].max_model_steps (default 200 — the R1 runaway guard). The turn loop itself says the intra-turn goal-continuation hook is "bounded by the step budget" (turn_loop.rs ~4912). So when a model enters a long tool loop inside one pass and does not close the turn, that pass is cut at 200 model steps with Maximum model steps reached before completion (limit: N) and the turn ends Failed — even though the goal is meant to run until done.

Result: an autonomous goal run is simultaneously unbounded (no pass/step cap at the goal level by default) and arbitrarily chopped mid-pass at the interactive ceiling. The knob designed to catch an interactive runaway loop is what stops an intentional autonomous run.

Current behavior

  • Goal run started (operate mode); the model works a long tool loop inside one pass without emitting a tool-less closing answer → the turn never closes → max_steps (200) fires mid-pass → TurnOutcomeStatus::Failed with Maximum model steps reached before completion (limit: 200). Work done up to that point stays in the transcript, but the run is over.
  • Goal-level budgets already exist but do not gate: GoalBudget { token_budget, time_budget_seconds, max_continuations } (goal_loop.rs), and "token/time accounting stays visible as telemetry but does not gate continuation".
  • [goal] max_continuations counts passes, not steps, and defaults off (0).
  • The only way to give an autonomous run more room today is to raise [tui].max_model_steps globally — which loosens the interactive runaway guard for everyone, including non-goal turns that a human is watching.

Desired behavior (options — maintainer's choice)

Give goal runs a step budget of their own, independent of the interactive max_steps:

  • Option A — [goal] max_steps: a model-step ceiling scoped to goal runs (total across the run, or per pass), separate from [tui].max_model_steps. Default could stay generous/unbounded at the goal layer (matching the goal "unlimited" contract) or inherit a large finite default — but it must not be the interactive 200.
  • Option B — surface the governing budget: wherever the 80% soft-landing / exhaustion notice is shown, name which budget governs (interactive max_steps vs goal budget), so "200" is not ambiguous.
  • Either way, exhaustion of a goal step budget should end the run with the existing honesty contract (soft landing at ~80%, one bounded final-report turn) rather than a bare Failed that looks like a crash.

The goal layer already owns a natural home for this: GoalBudget in goal_loop.rs gains a step dimension alongside token_budget / time_budget_seconds / max_continuations.

Motivation

Autonomous/operate runs (including overnight or long unattended work) are an intended use of the goal loop. Today a long single pass inside such a run dies at the interactive guard, which the operator did not expect to govern autonomous work — the goal documentation says "unlimited by default". Splitting the budgets keeps the interactive runaway protection intact (default 200 untouched for watched turns) while letting autonomous runs have their own honest, visible limit.

Acceptance criteria

  • A goal run that would previously die at 200 model steps inside one pass now runs under its own goal step budget and ends with the soft-landing/final-report honesty contract, not a bare Failed.
  • Interactive [tui].max_model_steps default stays 200 for non-goal turns (guard unchanged).
  • The effective governing budget is visible/disclosed where the exhaustion notice is shown (Option B).
  • docs/CONFIGURATION.md goal section and config.example.toml document the new key.

Environment

  • codewhale 0.9.12 (dev), Linux, tmux. Reproduced in an operate-mode goal run.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions