Plan mode lets the agent inspect and discuss a repository without changing it. Build mode restores normal tools only after explicit user approval. Disposable shell experiments remain possible in a per-session /tmp sandbox.
- Native Pi UI — themed mode selector, footer badge, working indicator, transcript cards, and responsive checklist widget
- Read-only Plan mode — only an explicit allowlist of inspection and question tools remains active
- Defense in depth — unexpected tool calls are blocked even if another extension reactivates them
- Sandboxed experiments —
plan_scratchpermits writes only inside/tmp/pi-plan-*on macOS - Explicit Build approval —
/buildrequires confirmation before repository writes are restored - Mandatory plan review — approve every complete step contract individually, then confirm the final DAG
- Markdown handoffs — safely create, update, or snapshot plans under
.pi/plans/ - Dependency DAG — every plan records prerequisite edges and displays them in Pi's native UI
- Dependency enforcement — dependent steps remain pending until all prerequisites complete
- Progress tracking — numbered plans become checklists;
[DONE:n]updates completion - Session persistence — mode, plan, tool state, progress, pending proposals, and audits survive reloads and resumes
- Governed scope expansion — out-of-plan Build work requires a full impact contract and hard user approval
- Independent recommendations — implementer and auditor positions are synthesized before approval
- Post-turn scope auditing — non-mutating Git snapshots detect undeclared changes; risky diffs receive semantic review
- Fork-aware scratch space — forked sessions receive a separate scratch directory
Install directly from GitHub:
pi install git:github.com/MachineLearning-Nerd/pi-plan-build-modeThen run /reload in Pi, or start a new Pi session.
To try it without installing:
pi -e git:github.com/MachineLearning-Nerd/pi-plan-build-modeIf you previously copied this extension manually into
~/.pi/agent/extensions/plan-build-mode, remove or disable that copy before installing the package to avoid duplicate commands.
Pi starts in Build mode to preserve its normal behavior. Enter Plan mode when you want safe exploration:
/plan
Or open the visual mode selector:
/mode
| Command | Purpose |
|---|---|
/mode |
Open the Plan/Build selector |
/mode plan |
Enter Plan mode |
/mode build |
Request Build mode with confirmation |
/plan |
Enter repository read-only Plan mode |
/build |
Request Build mode with confirmation |
/plan-status |
Show mode, governance state, scratch path, DAG, and checklist progress |
/plan-review |
Resume step-by-step plan review, a pending scope proposal, or an audit review |
/plan-export |
Create, update, or copy the current Markdown handoff under .pi/plans/ |
/plan-resolve-audit |
Confirm manually corrected/reverted undeclared changes and clear the audit gate |
/plan-clear |
Clear the checklist and pending governance state without deleting scratch files |
Ctrl+Alt+P |
Open the selector while Pi is idle |
Start Pi directly in Plan mode:
pi --planPlans are recognized when an assistant response contains an exact Plan: section:
Plan:
1. Inspect the authentication flow [depends: none]
2. Update token validation [depends: 1]
3. Add regression tests [depends: 2]
Pi displays the plan as a themed checklist and opens a Plan-ready menu:
- Approve & Build
- Review step by step
- Export plan to Markdown
- Refine plan
- Continue investigating
- Discard plan
Every step must be reviewed before Build. The native review shows exactly one step at a time with its description, dependencies, downstream dependents, rationale, implications, affected files, risks, alternatives, recommendation, acceptance criteria, and verification commands. Review progress survives reloads and can be resumed with /plan-review. Legacy text-only plans show a missing-impact-contract warning.
After every step is approved, Pi asks for final merged-DAG confirmation. /build, /mode build, and the visual mode selector all use this same gate and cannot bypass it. Refining material plan content invalidates the affected approvals; execution completion remains independent. Once approved, the agent emits exact [DONE:n] markers to update progress.
Completion tracking is explicit and dependency-aware:
- One turn may mark multiple steps, and marker text may be out of order.
- Only specifically named steps are considered; prose such as “step 2 is done” never changes the checklist.
- Independent steps may complete in any order.
- A dependent
[DONE:n]remains pending until all listed prerequisites are complete. - A single batch may include prerequisites and dependents in any marker order; Pi resolves the explicitly marked batch topologically.
For example, if step 3 depends on step 1, [DONE:3] [DONE:1] completes both in one turn. If step 1 is neither already complete nor explicitly marked in that batch, [DONE:3] is blocked and step 3 stays pending.
Use /plan-export or Export plan to Markdown from the Plan-ready menu. The first export previews and confirms an exact repository-relative path:
.pi/plans/<timestamp>-<plan-slug>.md
The handoff includes plan identity and revision, review and Build status, execution progress, the dependency table, every complete impact contract, the exact fallback Plan: list, and [DONE:n] instructions. Draft or partially reviewed exports are prominently marked not approved for execution.
The first export establishes a session-owned active handoff. Later exports offer:
- Update existing file — ownership-validated atomic replacement at the stable path
- Create new copy — a collision-safe snapshot that does not become active unless explicitly selected
- Cancel
Manual edits are detected by content hash. When they exist, Pi offers a new copy or a separately confirmed force update. Updates reject ownership-marker mismatches, symlink escapes, non-directory path components, and unrelated existing files. Discarding or clearing a plan removes only the session reference; it never deletes exported files.
Plan mode remains read-only for agent tools. The only repository write available while planning is an explicit, interactive /plan-export operation under the fixed .pi/plans/ root. It requires exact-path confirmation and never switches mode, marks steps complete, resets review progress, or enables normal mutation tools. Noninteractive export fails closed.
New plans should be submitted through the structured submit_plan tool. It records a full impact contract for every step:
- rationale and implications
- affected file globs
- risks and alternatives
- implementer recommendation
- acceptance criteria and verification
- dependency edges
Whenever Build mode has a plan, the agent must call propose_plan_change before implementing work outside those contracts. A proposal may add a batch of related steps and rewire unfinished steps, but it cannot renumber steps, alter completed-step dependencies, or create a cycle.
The approval flow:
- Pauses Build mutations.
- Runs a configurable independent audit.
- Shows the implementer recommendation, auditor recommendation, implications, risks, alternatives, acceptance criteria, and verification.
- Grills through each proposed step individually.
- Shows the final merged DAG for explicit approval.
- Appends approved steps, updates dependencies, reopens the checklist, and records a session audit entry.
Without an interactive UI, proposals fail closed and remain pending. Resume them later with /plan-review.
For each governed Build turn, the extension creates before/after Git trees through a temporary alternate index. This does not stash, commit, switch branches, or modify the real Git index. It then:
- compares changed paths with approved file globs;
- triggers semantic review for ambiguous, broad, or high-risk diffs;
- pauses future mutation tools if undeclared scope is found;
- asks whether to formalize a plan change, request correction/revert guidance, or inspect manually.
The extension never auto-reverts mixed working-tree changes. After manually correcting or reverting an audit violation, use /plan-resolve-audit to clear the hard gate.
Strict post-turn auditing requires a Git repository. Non-Git projects fail closed rather than claiming complete audit coverage.
Optional global config: ~/.pi/agent/extensions/plan-build-mode.json
Optional trusted project config: .pi/plan-build-mode.json
{
"auditorModel": "anthropic/claude-sonnet-4-5",
"riskPaths": ["**/auth/**", "**/migrations/**", "**/.github/**"],
"semanticAuditFileThreshold": 5,
"semanticAuditLineThreshold": 200
}When auditorModel is unavailable or omitted, the active Pi model is used and labeled as a reduced-independence fallback.
In Plan mode, normal bash, edit, and write tools are unavailable. The agent can instead call plan_scratch for disposable experiments. The user-driven /plan-export safety exception is limited to confirmed files under .pi/plans/ as described above.
- Working directory:
/tmp/pi-plan-<session-id> $PI_PROJECT_ROOT: repository path, readable but not writable$PI_SCRATCH: writable scratch pathHOME,TMPDIR, andXDG_CACHE_HOME: redirected inside scratch- Output: limited to Pi's standard 50 KB / 2000-line bounds
The write sandbox currently uses macOS /usr/bin/sandbox-exec. On other platforms, Plan mode remains read-only but disables plan_scratch. Contributions for a Linux sandbox backend are welcome.
Plan mode protects against agent-initiated tool calls by:
- Replacing the active tool set with an explicit read-only allowlist.
- Blocking unexpected calls in a
tool_callevent handler. - Running shell experiments under an OS profile that denies filesystem writes outside scratch.
Pi extensions execute with full user permissions. This package cannot protect against malicious or independently mutating third-party extensions, user-issued shell commands, OS-level sandbox escapes, or writes performed outside Pi. Review extensions before installing them.
npm install
npm run checkThe test suite includes a macOS integration test that verifies scratch writes succeed while sibling writes are denied.