The Control Plane: Plan, Goal, Permissions, and Sandbox

Reasonix gives you several ways to control an autonomous coding task, but they answer different questions. This chapter separates collaboration mode, approval posture, task contract, permission policy, and Sandbox enforcement so you can choose them deliberately. The practical goal is not to find the single safest switch; it is to understand which decisions belong to you, which remain with the model, and which the host must enforce around every concrete action.

Imagine asking Reasonix to modernize a project while you are away. “Let it work” could mean “show me a plan first,” “keep going until the objective is done,” “ask before every write,” or “allow routine commands without interruption.” Those are not four names for the same mode. They change different parts of the run, and confusing them can create either needless friction or false confidence.

Four controls, four questions

The first control is collaboration mode. Normal work is an ordinary executor turn: the model investigates, uses tools, interprets results, and ends when it reaches a normal stopping point. Plan mode inserts an explicit pre-implementation boundary. Goal mode changes the turn lifecycle so a saved objective can continue across turns. These modes describe how the work is organized, not whether a particular shell command may run.

The second control is tool approval posture. Ask uses the permission system’s approval path when a call requires it. Auto allows ordinary writer fallback without stopping for each routine approval, while still respecting explicit ask and deny rules. YOLO skips ordinary approval prompts, but it does not erase configured deny rules or every host-owned confirmation boundary. Approval posture changes how the host resolves an approval decision; it does not turn an unapproved target into an approved one.

The third control is a task contract. For work that is more than a one-line request, the contract gives the model five pieces of orientation:

  • Context: what larger situation the task belongs to and who needs the result.
  • Request: the concrete action to complete.
  • Output format: how the result should be delivered and what it must contain.
  • Constraints: assumptions, files, scope, or quality boundaries to preserve.
  • Pause policy: when to keep working and when to ask the user.

The contract improves the model’s judgment by making the objective and stopping conditions explicit. It is not a permission grant. A sentence saying “continue unless the next step is externally visible” does not authorize a publish, credential change, or deployment. Those effects still pass through the host’s policy and enforcement layers.

The fourth control is execution enforcement. Permission policy asks whether a particular call is allowed, denied, or sent to an approver. The Sandbox enforces where that authorized call can operate. A user can configure an agent to proceed automatically with ordinary writers and still keep it inside a workspace root. Conversely, a path inside the workspace does not make a call acceptable if a deny rule blocks it. This separation is the foundation for reasoning about the rest.

flowchart TD T["User task and task contract"] --> C["Collaboration choice: Normal, Plan, or Goal"] T --> A["Approval posture: Ask, Auto, or YOLO"] C --> H["Reasonix host evaluates the concrete action"] A --> H H --> P["Permission policy: deny, ask, allow, fallback"] P -->|blocked| B["Blocked result; no tool execution"] P -->|allowed| S["Sandbox and workspace enforcement"] S --> X["Concrete tool execution"] X --> R["Result and host facts"] R --> G["Goal report: continue, complete, or blocked"] G -->|continue| H PL["Plan before approval: state-changing work is blocked"] --> H

Plan protects the starting boundary

Plan mode is useful when the cost of beginning implementation is high. Before the user approves the plan, Reasonix blocks state-changing actions, including writes, proxy actions, and subagents. The model can investigate within the allowed planning surface and assemble a proposed course of action, but it cannot quietly turn that proposal into implementation.

That is a narrower and more useful claim than “Plan is read-only.” The repository’s current contract treats Plan as a plan-first workflow, not as a third permission system. The tools available during planning still have their own classification, and the host re-checks the real target after resolving a proxy. A wrapper that looks harmless cannot make a destructive target available simply by hiding it behind a read-only-looking interface.

After approval, the boundary changes. Reasonix opens a temporary execution window for the approved plan’s ordinary writer fallback, while explicit ask and deny rules remain authoritative. The Sandbox remains active, and a future plan still requires its own approval. This matters in a long conversation: approving one dependency migration should not silently approve a later request to publish a package or alter an unrelated directory.

Plan also does not certify the plan’s quality. A plan can contain an assumption that the executor later disproves. It can identify a file that has changed since planning. It can omit a needed verification step. The executor remains responsible for validating candidate assumptions and reporting actual results. Plan controls when implementation may begin; it does not make the proposed reasoning true.

Goal continues a saved objective

Goal mode solves a different problem: a useful task may need several ordinary turns. A Goal stores an objective and its runtime state with the session. At the end of a Goal turn, the model reports one of three structured dispositions through update_goal: continue, complete, or blocked.

continue keeps the objective active and supplies the next concrete action. complete says that the model judges the objective finished. blocked preserves a reason and stops continuation. If the model omits a report, the Goal remains active under the current contract rather than treating silence as proof of completion. The host binds the report to the Goal’s current lifecycle, so a late report from a replaced or cleared Goal cannot mutate a newer one.

The important limitation is that complete is a model report, not an independent evaluator’s verdict. Current Reasonix semantics keep the report separate from command outcomes, failed checks, unfinished todos, cancellation, permission waits, and explicit resource pauses. A confident completion statement cannot rewrite any of those facts. The repository also retains older evaluator-related fields for compatibility in some stored or remote data; that historical compatibility should not be confused with the current completion contract.

Goal continuation is not permission-free. Each synthetic turn still enters the normal execution path. A Goal can keep working through ordinary uncertainty, but its task contract should tell it to pause before an irreversible or externally visible operation, a scope change, or information only the user can provide. Users can also set explicit token, step, time, or cost limits. Without a user-selected limit, the current Goal design does not impose a default round, wall-clock, or numeric no-progress quota. That is a choice about continuation, not a promise that the model will always choose wisely.

This distinction makes Goal appropriate for a migration that can be completed within a known workspace but should stop before publishing. The model can inspect, edit, test, and revise over several turns. The host still blocks disallowed calls, records failures, and preserves the point at which an external decision is needed.

Permission policy is a decision about the call

Once Reasonix has resolved a concrete target, permission policy evaluates it. The general precedence is:

  1. Deny rules win and block the call.
  2. Ask rules force an approval path.
  3. Allow rules authorize a matching call.
  4. If no rule matches, the configured fallback applies; read-only calls normally fall back to allow, while writers use the configured posture.

The policy can match a tool family or a subject. For a file operation, the subject may be a path. For Bash, it may be the command. A move has two relevant paths, so a rule that protects either endpoint can affect the whole operation. This subject-based design is more precise than a single global “safe” label because the same writer can be harmless in one directory and consequential in another.

Bash receives extra scrutiny because command syntax can hide effects. A reusable approval for a safe command prefix is intentionally narrower than a broad wildcard. Parameter or arithmetic expansion, assignments, redirects, and globs cannot automatically inherit every remembered approval. More indirect forms—such as command or process substitution, a dynamic command name, eval, source, shell -c, or inline runtime code—normally require a human in interactive Ask or Auto. An advanced configuration can opt into broader dynamic fallback, but explicit ask and deny rules still take precedence.

This is why Auto and YOLO should be chosen with different expectations. Auto reduces interruptions for ordinary writer fallback. YOLO goes further by skipping ordinary prompts, but neither mode changes the meaning of a deny rule. Neither mode answers an ask question about product intent, approves a Plan, or makes a third-party program transparent. The host is reducing approval friction, not transferring all authority to the model.

Sandbox enforcement is a second boundary

Permission policy answers “may this call run?” The Sandbox answers “where and under what operating limits can it run?” Reasonix’s file-writing tools resolve paths, enforce workspace roots, and reject traversal or symlink paths that would escape those roots. A write outside the current workspace can require an explicit extension of write access; in an unattended run, the extra directory must already be configured or supplied as an allowed directory.

Bash has a separate operating-system boundary where the platform supports one. On Linux, Reasonix uses bubblewrap when the OS sandbox is available; on macOS it uses Seatbelt. The jailed command is limited to approved write roots, configured read restrictions, and the permitted network setting. If an enforced OS Sandbox is unavailable, the documented behavior is to refuse Bash rather than silently run it unconfined. Windows is a deliberate exception in the current contract: Reasonix does not ship an OS-level Bash sandbox there, so file tools still enforce their own roots but an approved Bash process is not the same security boundary.

The distinction becomes concrete with a symlink. A permission rule might allow a writer targeting a workspace path. The file tool still resolves the path and checks the real target. If the path reaches outside the approved root through a link, the Sandbox refuses it. Conversely, a command can stay inside the workspace and still be denied because it is on an explicit deny list or because its shell shape requires a human decision.

This layered approach has a cost: the user has more concepts to configure, and the model receives more kinds of blocked result. That complexity is preferable to one control pretending to do every job. A permission system that is also the only filesystem boundary cannot protect against an incorrectly resolved path. A Sandbox that is also the only policy cannot express “allow tests, but ask before publishing.”

Installed MCP servers show the same limit from another direction. Installation is the authorization decision for the server, and explicit deny rules still apply. Reasonix uses server-reported read-only and destructive hints for scheduling, the dedicated Planner, and strict read-only subagents. But the repository states that this is a workflow boundary for trusted servers, not containment against a malicious one. A connected server is an external principal, not a magically sandboxed extension of the local file tools.

Choosing controls before the run

The right configuration depends on the consequence of the next action, not on how impressive the task sounds.

For a bounded inspection or a small local edit, Normal mode may be enough. Keep the Sandbox at the intended workspace, leave ordinary approval in Ask if you want to see writers, and let the model choose the minimum useful investigation. The model remains free to stop without having to satisfy an automatically inferred quality checklist.

For a change with several possible implementation paths, use Plan when you want to examine the proposed direction before any state-changing work begins. Write the output format and constraints into the task contract. Treat approval as authorization for that plan’s execution boundary, not as a permanent grant for later work. After approval, continue to read actual tool results: a plan is a proposal, not a guarantee that the workspace still matches its assumptions.

For a long workspace-scoped objective, use Goal with a clear Request, Constraints, and Pause policy. Specify what “complete” should mean and which checks matter, but remember that those are instructions to the model; actual failures and interruptions remain host facts. Add an explicit budget when an unattended run must have a spend or time ceiling. Use Ask, Auto, or YOLO according to how much ordinary approval friction you accept, not as a substitute for the Goal contract.

Before starting, decide four things explicitly: what the model may investigate, what kinds of effects need human attention, which paths and network boundaries the host must enforce, and how you will recover if the direction is wrong. During execution, let the model choose the next useful step inside those boundaries. That division keeps autonomy useful without asking a single mode selector to carry the whole meaning of trust.

References