Skip to content

Make /auto continuous, autonomous, and narrated - #215

Merged
TroyHernandez merged 6 commits into
mainfrom
auto-continuous
Sep 17, 2026
Merged

TroyHernandez merged 6 commits into
mainfrom
auto-continuous

Conversation

@TroyHernandez

Copy link
Copy Markdown
Contributor

/auto now behaves like a Codex-style autonomous run rather than a fixed-iteration loop.

What changed

  • Continuous by default. A bare /auto <goal> (no --loops) runs until done, governed by the monitor subagent and the resource caps (tool calls, tokens, time, cost, stall) instead of a loop count. --loops N still sets an explicit cap. max_loops = Inf is accepted only for this case; max_tool_calls/stall_loops stay finite by validation, so a run is never truly unbounded. A goal is still required.
  • Autonomy policy. The first prompt states the operating policy: act on reasonable assumptions rather than pausing, stop only for an outcome-changing ambiguity, judge completion by evidence. The per-iteration continuation carries a one-line reminder so the stance survives compaction cheaply.
  • Belief-state narration, rendered. The runtime guidance asks for brief belief-state updates with adaptive batching, not a line before every call. The model's commentary is now actually rendered in the live progress stream (CLI + chat()), once per model response and independent of the approval prompt — including denied/refused first calls. Previously it appeared only inside an approval prompt, which auto-approved calls skip.
  • Unblockable auto mode. task_create no longer blocks on human plan approval inside an auto run (it hung interactive runs and default-denied non-interactive ones); the task guidance drops the ask-first / wait-for-approval steps in auto mode. Attended approval is unchanged.
  • Real escalation. AUTO_STATUS: blocked stops the run for a human before the monitor query, parsed from the status token so prose ("blocked - cannot continue") or a stray continue line can't flip a fail-closed stop into a continuation.

Tests

Full test_package suite green (4861 assertions, 0 failures). New coverage for continuous mode, the autonomy/continuation prompts, blocked parsing and loop behaviour, task auto-approval in auto mode, and commentary rendering including denied first calls.

A bare /auto <goal> previously stopped after the configured iteration
cap (default 10). It now runs continuously: the loop count no longer
halts it (max_loops = Inf), and the run is governed by the monitor
subagent and the finite resource caps -- tool calls, tokens, time,
cost, and the stall guard -- rather than an iteration count. That
matches the "work until done, stop at the boundary" model of an Auto
approval mode, where completion is judged (the worker's AUTO_STATUS,
checked by the monitor against disk evidence) rather than counted.

--loops N still sets an explicit iteration cap. auto_validate_bounds
accepts Inf only for max_loops and still rejects it for every other
cap; max_tool_calls and stall_loops stay finite, so a continuous run
always stops on some cap or a monitor verdict and is never truly
unbounded. A goal is still required, same as a fresh Codex run.
The first prompt of an auto run now states its operating policy the way
a well-phrased Codex task states its own: act on reasonable assumptions
rather than pausing to ask or report progress; stop only for an
ambiguity that would materially change the intended outcome, and report
it for a human instead of guessing; and judge completion by evidence
such as passing tests. Auto mode governs how freely the worker acts, not
what the goal is or when it is done -- the model decides those, and this
is the policy it decides under.

The policy is stated in full once, in the initial prompt. The
per-iteration continuation prompt keeps only a one-line reminder, so the
stance survives compaction without paying for the whole policy on every
turn (the continuation prompt stays under its length budget).
The "communicating while you work" policy leaned toward a line before
every tool call ("don't go more than a couple of tool calls without a
word"), which reproduces a cadence rather than the behaviour worth
having. Rewrite it around belief-state updates with adaptive batching:
send a brief update when a chunk of work finishes, when evidence changes
the working hypothesis, when the approach is about to change
substantially, or after several silent tool calls -- and keep working
after, since an update is informational, not a stop. Routine calls that
only confirm an expectation need no narration, and a question is not an
update.

The silent-streak backstop already existed (nudge after
corteza.narration_streak tool-call turns, default 3); its wording is
aligned to ask for what was learned and what's next, not just "what
you're doing".
Codex review found the narration and autonomy behaviour was described but
not delivered. Three fixes:

1. Render the model's running commentary. Previously assistant_text
   reached only cli_tool_explanation() inside the approval prompt, so an
   auto-approved call (every call in an unattended run) showed nothing --
   forcing verbose did not help. cli_commentary_lines() now prints the
   commentary once per model response, independent of approval, on both
   the CLI observer and chat()'s observer_progress().

2. Stop auto runs blocking on plan approval. task_create routed to the
   human task_approval_cb before the auto gate, so an unattended run hung
   (interactive readline) or default-denied and stalled. .task_read_approval()
   now accepts a plan when session$auto_run_id is set, and the task
   addendum drops the ask-first / wait-for-approval steps in auto mode.
   Attended sessions prompt exactly as before.

3. Give a human-input request a real stop. The autonomy prompt told a
   blocked worker to emit AUTO_STATUS: continue with prose, which parses
   as continuation and depends on the monitor reading the prose. Add
   AUTO_STATUS: blocked, treated as a fail-closed escalation that stops
   the loop before the monitor query. Also reconcile the attended
   "check in whenever it could go more than one way" posture with the
   auto reasonable-assumptions policy, which now explicitly overrides it.
Two edge cases from the Codex review:

1. auto_parse_status() scanned the whole AUTO_STATUS line for status
   words and defaulted to continue on a multi-match, so "blocked -
   cannot continue" and a separate blocked line alongside a continue
   line both read as continue -- a fail-closed stop silently downgraded.
   Parse the status token (the first word after the colon) apart from
   its explanation, and let a blocked token win outright. Prose is no
   longer load-bearing: "continue, not blocked" stays continue, and
   "blocked - cannot continue" stops. The permissive done/continue
   default is unchanged.

2. The running commentary rendered only on "start"/"task", and
   cli_commentary_lines() only fires for the first call of a batch. When
   that first call was denied (a monitor refusal fires "deny"/"declined",
   never "start"), the whole response went uncommented even though a
   later call ran. Both observers now render commentary on a denied or
   refused first call too, still once per response.
@TroyHernandez
TroyHernandez merged commit 0a4eaab into main Sep 17, 2026
2 checks passed
@TroyHernandez
TroyHernandez deleted the auto-continuous branch September 17, 2026 14:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant