Plan mode & goals
Roder separates planning from execution through policy modes. plan mode blocks writes and process execution, records plan-exit requests, and requires an explicit transition before the agent can move into implementation.
Runtime events
PolicyModeChangedrecords mode changes.PolicyExitPlanRequestedrecords a request to leave plan mode.PolicyExitPlanResolvedrecords the user's decision and resulting mode.PolicyDecisionRecordedcaptures per-tool allow, deny, approval, or auto-approval decisions.
Client surface
The app server exposes thread/set_mode, thread/state, andthread/exit_plan. The TUI uses those methods to keep the current mode visible and to gate the move from planning to edits.
{"jsonrpc":"2.0","id":1,"method":"thread/set_mode","params":{"mode":"plan","reason":"design first"}}
{"jsonrpc":"2.0","id":2,"method":"thread/exit_plan","params":{"requestId":"PLAN_REQUEST_ID","approved":true}}Goals
Long-running goal state belongs above individual turns: a client can keep a visible objective, show progress, and persist status alongside thread state. The runtime injects active goal instructions into later turns and continues idle active goals until they are completed, paused, blocked, usage-limited, budget-limited, or cleared.
App-server clients manage goals through thread/goal/get,thread/goal/set, and thread/goal/clear. Model-facing tools are deliberately narrower: get_goal, create_goal, andupdate_goal let the agent inspect, create, complete, or mark a goal blocked, while pause/resume, budget changes, and clearing remain user-controlled.create_goal only fails while an active goal is still in progress; once a goal is completed, blocked, paused, usage-limited, or budget-limited, a resumed session can replace it with the next objective.
{"jsonrpc":"2.0","id":3,"method":"thread/goal/set","params":{"threadId":"THREAD_ID","objective":"Ship docs parity","tokenBudget":20000}}
{"jsonrpc":"2.0","id":4,"method":"thread/goal/get","params":{"threadId":"THREAD_ID"}}