Use plan mode
Walk the agent through a change without side effects, then flip the switch to execute.
When to use it
Plan mode is the right fit for three moments a charm author routinely hits:
- Design reviews. You want the agent to read the code, look at Juju, and explain what it would do without actually committing.
- Demos. You want to walk an audience through a build without risking stale state on-screen.
- "What if" exploration. You're not sure which refactor is right; plan mode lets the agent propose each one on its own before anything is written.
How to use it
> /plan
**Plan mode on.** I will read the code, Juju state, git history,
and web, and produce a *Proposed changes* summary — but I won't
edit files, run shells, or deploy. Flip back with `/build`.
> Reshape src/charm.py to use collect-status.
... the agent reads files, inspects the relation graph, and ...
## Proposed changes
- `src/charm.py`: replace the `update-status` handler with a
`collect_app_status` observer on `CollectStatusEvent`.
- `tests/unit/test_charm.py`: delete the `test_update_status`
cases and add coverage for `collect_app_status`.
- Run `make check` after the edits to confirm lint + types.
> /build
**Build mode on.** Every tool is available again. Resumed the
plan's *Proposed changes* section as context — the next turn
will execute against it.
What plan mode lets through
Plan mode is implemented as a stricter permission policy layered on top of whatever you already have configured. The allow-list is intentionally narrow:
- File reads:
read_file,list_directory,glob,grep. - Git history:
git_status,git_diff,git_log. - Juju introspection:
juju_status,juju_list_secrets,juju_show_secret,juju_read_relation_data,juju_get_app_config,juju_list_offers,juju_show_unit. - Memory lookup:
memory_list,memory_read,memory_search(writes go through in build mode only). - Network:
web_search,web_fetch.
Every other tool returns a refused ToolResult with
a clear "Plan mode — tool is not available"
message so the LLM knows to stop rather than retrying. MCP-provided
tools bypass plan mode because they are gated by their own
per-server allow-lists and are not
inherently destructive; if you want to tighten those too, tighten
the MCP config.
Capturing Proposed changes
While plan mode is on, Cantrip injects a short guidance block
into the system prompt asking the agent to end each response with
a ## Proposed changes section. When the agent
produces one, Cantrip captures the body into
state.plan_summary. The next /build
splices that summary back in as an assistant-role message so the
agent picks up where the plan left off — no re-planning from
scratch, no re-reading files.
The heading is recognised case-insensitively at any heading
depth (## through ######). A response
without the section leaves whatever summary was captured before
untouched, so a mid-plan clarification question does not blow away
the earlier plan.
Status indicator
Every surface that shows a status bar tints it while plan mode is active:
- The TUI status bar gains a
-plan-modeCSS class backed by the theme's$warning-darken-2colour, plus a literal "plan mode" badge on the left. - The Web UI and CLI listen to the same
STATUS_BAR_CHANGEDevent with amodefield, so any surface that reads it picks up the signal without extra wiring.
Interaction with other guards
- Permissions. The plan overlay composes
onto your existing rules with
most-restrictive-wins semantics. A tool your
permissions.yamlexplicitly allowed is still denied by plan mode while the flag is on. - Hooks. Pre-tool hooks still fire in plan mode — a hook that rewrites arguments runs before the plan-mode gate sees the call, so the decision is made against the rewritten arguments.
- /undo. Plan mode doesn't take snapshots beyond what the session already does — there's nothing to snapshot because nothing mutates. Your pre-plan snapshot is still there if you need it.
- Custom commands. A
user-defined slash
command that uses
!`cmd`shell expansion still hits the permission gate; plan mode makes that gate stricter.
What plan mode is not
- Not a git branch. Plan mode doesn't touch your tree; it prevents tools from touching it.
- Not persistent. The mode is session-scoped. Restarting Cantrip drops the flag back to build mode.
- Not a subagent override. Subagents spawned while plan mode is on see the same permission stack; they can't smuggle in a write by running on the work queue.