Plan mode not enforced: Write/Edit/Bash mutations execute without prompts while plan-mode reminders active (2.1.183, cli entrypoint); spurious "Exited Plan Mode" events without user approval

Open 💬 1 comment Opened Jul 3, 2026 by dennisgregory-lab

Summary

Plan mode's instruction layer (system reminders) was active while its enforcement layer never engaged: Write, Edit, and mutating Bash calls to files outside the plan file executed with no permission prompt and no denial for the entire armed window. Additionally, spurious "Exited Plan Mode" events fired without corresponding user approvals.

Environment

  • Claude Code 2.1.183, Linux (Debian bookworm container), entrypoint: cli
  • Session driven through a web terminal UI ("CloudCLI") that wraps the real CLI process — but transcript confirms entrypoint:"cli", so the SDK permission path is not involved
  • User settings: permissions.defaultMode: "acceptEdits". No bypassPermissions / skip-permissions anywhere (user-level or project-level)
  • Long session (~8h, large transcript), multiple concurrent sessions in the same workspace

What happened

  1. User armed plan mode (UI toggle → CLI). The model's context received the standard plan-mode system reminder ("You MUST NOT make any edits… This supercedes any other instructions"). The model quoted this reminder verbatim in its visible responses at the time (persisted in transcript), so injection is confirmed contemporaneously.
  2. While armed, the model issued Write (new file ~/.claude/hooks/<script>.py), Bash heredoc writes to ~/.claude/settings.json, chmod, and Edit calls. All executed immediately — no prompt, no deny. Expected: hard denial of any non-plan-file mutation while permissionMode=plan.
  3. Transcript timeline (UTC, single session, sanitized tags):
03:20:04 Write   (hook script — outside plan file)
03:22:21 Bash    (settings.json mutation + chmod)
03:23:11 Write   (hook script)
03:24:09 Bash    (settings.json mutation)
03:26:58 "Exited Plan Mode" event   <- no user approval occurred here
03:27:54 "Exited Plan Mode" event   <- no user approval occurred here
03:29:40 Write   (hook script)
03:30:24 Edit    (hook script)
03:30:48 Edit    (hook script)
03:31:26 Edit    (hook script)
03:33:26 "Exited Plan Mode" event   <- no user approval occurred here
03:37:38 "Exited Plan Mode" (user)  <- the ONE legitimate ExitPlanMode approval
  1. Plan-mode re-entry reminders continued to arrive with user messages between the spurious exit events — i.e., the reminder layer asserted "plan mode active" while the event stream shows the mode flapping and the permission engine behaving as acceptEdits throughout.

Expected

While plan mode is armed: every Edit/Write outside the designated plan file and every non-readonly Bash/tool call is denied by the permission engine, regardless of defaultMode, until ExitPlanMode is approved by the user.

Actual

Only the reminder text was in effect; enforcement never engaged. Compliance was left entirely to the model. Separately, "Exited Plan Mode" events fired 3–4× without user approval (possible toggle-relay double-fire from the wrapping web UI — but the state machine accepting those exits, and/or reminders continuing to assert armed state afterward, is harness-side).

Notes

  • Transcript (JSONL) does not appear to persist the injected plan-mode reminders as user-entry text, which limits post-hoc audit — the model's contemporaneous quotes are the persisted evidence. If reminders are meant to be persisted, that may be a second, minor bug.
  • Happy to provide sanitized transcript excerpts on request.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗