Rio
adr/0101-plan-mode.mdRaw Markdown · GitHub ↗

ADR-0101: Plan mode: a core tool and a readable plan view

  • Status: Accepted; amended by ADR-0102, ADR-0103
  • Date: 2026-09-11
  • Deciders: jka
  • Decision: D101

Context

An agent that starts editing on a one-line request acts on an understanding nobody checked. The maintainer asked for a planning mode like the one in the VS Code Claude extension: the model investigates, presents a plan as a readable document, and does nothing until it is approved.

Decision

A core tool. Tools are core-owned (ADR-0020), so a plan presented through a tool call works with every provider without provider changes. The tool is present_plan {title, plan}, of kind plan, and goes through the existing approval gate beside edit and command.

A mode with enforcement. rio::agent::mode is build or plan. In plan mode the core gives the model only read tools and present_plan, and appends a shipped agent/plan.md prompt layer (overridable). Both are applied in the core, so a provider cannot ignore the mode. The mode is part of agent.status, so every frontend on a core agrees. A plan is never auto-accepted.

Approval continues the same turn. Tool specifications and the system prompt are recomposed on every step of a turn, so write tools become available on the call after approval. Rejection keeps plan mode on and asks the model what the user wants changed.

The plan takes the document area. It is shown in a view where the editor normally is, like a large proposed edit in the compare view (ADR-0028), rendered with the manual's renderer (ADR-0100). The decision stays on the chat's approval bar. The view can be closed and reopened; deciding, or sending a new message, dismisses it. Links in a plan are styled but inactive.

Every plan is filed in the project at .rio/plans/<timestamp>-<slug>.md as it is presented, including rejected ones. With no project open, no file is written.

Consequences

  • Plans work with every provider, and plan mode is enforced, not requested.
  • Sharing the renderer required per-widget link state, so painting a plan cannot break an open manual page.
  • Clearing the conversation now also removes pending review UI.
  • Whether a model chooses to call present_plan can only be verified with a live provider.
  • ADR-0102 moved the edit-policy choice to the plan's approval, and ADR-0103 made the plan tool available outside plan mode.