Skip to content

[Bug]: Plan mode performs real write / side-effecting actions (file edits, git commits, MCP tool calls) before the plan is approved #3744

Description

@proxet-p35

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/server

Steps to reproduce

  1. Start a thread with a Claude model (Claude Fable 5), access level set to Full access, and turn on Plan mode — the Plan toggle stays lit in the composer.
  2. Let the model produce a plan so the thread reaches the "plan captured / awaiting review" state. Do not press Implement.
  3. Keep sending follow-up messages that refine the plan and give operational instructions — clarifying questions, specifying where an output artifact should be placed, asking to notify specific people — all while the Plan toggle is still on.
  4. Eventually press Implement to approve the plan.

Expected behavior

Plan mode should stay read-only until the plan is explicitly approved via Implement. Follow-up messages should only refine the plan. No file edits, no git branches/commits, and no side-effecting external tool calls (MCP integrations, e.g. creating a wiki/doc page or posting an issue-tracker comment) should happen during the planning phase. This should match Claude Code's own behavior, where plan mode never performs write operations.

When Implement is finally pressed, it should hand off the current plan — reflecting all the refinements made during the conversation — not a stale snapshot.

Actual behavior

1. Writes happen during planning. While the composer still showed Plan mode active (Implement never pressed), the model performed real, irreversible side effects:

  • modified files in the working tree,
  • created an external wiki/documentation page via an MCP integration,
  • posted a comment on an external issue tracker via an MCP integration, mentioning/notifying several people.

A follow-up whose only intent was to specify where to place an output artifact (something like "put the document in folder X") appears to have been interpreted as approval to leave plan mode and execute — even though no approval was given and Plan mode was still active.

In a separate session the same behavior went further: from the plan-ready state, the model created and transitioned an issue-tracker ticket, posted comments on a pull request, edited files, created a git branch, and committed the changes — despite an explicit instruction to only plan the implementation.

2. "Implement" hands off an outdated plan snapshot. When Implement is finally pressed, the composer switches from Plan to Build and injects a PLEASE IMPLEMENT THIS PLAN: message containing a stale copy of the original full plan (all of the original "to-do" steps), rather than the latest refined plan / current state. Because the side-effecting work had already been carried out during the planning phase (symptom 1 above), the injected plan describes changes that were already done. The agent runs briefly and then reports that "the plan is already fully implemented", and the genuinely-pending follow-up actions the model had promised to do after approval are not what the Implement flow targets.

Impact

Major degradation or frequent failure — irreversible side effects (git commits, external ticket/doc/comment mutations, notifications to other people) performed without approval, from what is supposed to be a read-only planning phase. On top of that, the approval handoff replays an outdated plan, so Implement does redundant/no-op work instead of the actually-pending steps.

Version or commit

T3 Code (Alpha) 0.0.28 (fda6486)

Environment

macOS · Claude provider (Claude Fable 5) · access level Full access · Plan → Build on Implement

Workaround

Switching the access level to Supervised stops writes during planning, since it forces an approval prompt on every command/file change — but it's very heavy-handed for a phase that should already be read-only.

Likely area / root-cause hypothesis

The plan-mode permission gate in the Claude adapter appears not to cover MCP tool calls or git/file writes. PR #3696 installs the SDK permission callback in plan mode and intercepts ExitPlanMode via canUseTool, which confirms plan-mode enforcement lives in the Claude adapter's permission-callback path (apps/server). The bug is that, before the plan is approved, that policy does not deny write / side-effecting tools — file edits, git commits, and MCP integration calls all execute. It also looks like a plainly-phrased planning instruction can be treated as implicit approval to leave plan mode, so the gate should not depend on how the follow-up is phrased.

The second symptom suggests the plan captured for the Implement handoff is a snapshot taken at initial plan proposal and is not updated as the plan is refined across subsequent turns, so approval replays an outdated plan.

Additional context

  • Differs from [Bug]: Plan mode is ignored when using claude and it implemented #1884 (closed): that report was about Enter on a follow-up triggering implementation instead of "Iterate on plan." This is broader — Plan mode performs real writes and external MCP mutations before the plan is approved, regardless of the selected access level.
  • Expectation is that Plan mode enforces read-only semantics independent of the access level (Full access / Auto-accept edits), the way Claude Code does natively, rather than requiring Supervised as a workaround.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions