GPT 5.4 Enhancement v3 — Phase 3.C
Tracking: #66345
Priority: P1 — The marquee Claude Code-quality feature (opt-in only)
Hard depends on: #61845 merging (plan-mode runtime from nick0809cn-ux)
Also depends on: #67514 (task-system parity), #67519 (plan rendering)
Context
PR #61845 already builds the plan-mode runtime core:
SessionRuntimeMode = "plan" | "normal" | "auto"
enter_plan_mode / exit_plan_mode agent tools
plan-mode-hook.ts mutation gate (blocks 11+ tool categories)
todo_write / task_create / task_update plan-mode tools
- Session-metadata persistence of plan state
This issue covers the layer above #61845: user-facing entry points and the approval UX that makes plan mode trustworthy. Without this, plan mode is two phases with no human review gate.
Scope
Entry points (all opt-in, never auto-enabled)
- Slash command:
/plan <optional goal> — one-shot opt-in for the next turn
- Config flag:
agents.defaults.planMode.enabled: false — per-agent default
- Model gate:
agents.defaults.planMode.autoEnableFor: [] — regex list (empty by default to preserve Hermes parity)
- Control UI toggle: button + keyboard shortcut mirroring Claude Code's Shift+Tab and Codex's /plan
Approval state machine
exit_plan_mode called
→ plan_approval_requested event emitted
→ UI renders plan checklist + Approve / Edit / Reject buttons
→ On Approve: inject approved plan as system message, enter Phase B (normal mode)
→ On Edit: re-enter Phase A with user's edited plan
→ On Reject: abort turn
→ On timeout (configurable, default 10min): auto-reject with message
Channel-native approval UX
| Channel |
Mechanism |
| Control UI |
Modal with 3 buttons |
| Telegram |
Inline keyboard buttons (reuses existing approval infra) |
| Discord |
Button row on embed |
| Slack |
Block kit buttons |
| CLI |
Terminal prompt with 3 options |
Tool-name reconciliation
#61845 introduces todo_write / task_create / task_update alongside the existing update_plan. This PR ships an adapter so both tool surfaces produce the same AgentPlanEventData events. Both names resolve to the same handler. Deprecation of one name deferred to Phase 4.
Strict-agentic interaction
- Phase A: planning-only retry guard is disabled (the whole point is to plan)
- Phase B: strict-agentic operates normally
Files to create/modify
- new
src/commands/plan.commands.ts
src/config/types.agent-defaults.ts, src/config/zod-schema.agent-defaults.ts
- new
src/agents/plan-approval.ts + test
src/infra/agent-events.ts (new event types)
src/channels/plugins/approvals.ts (extend for plan approval)
- Control UI approval modal
- Per-channel approval handlers
src/agents/pi-embedded-runner/run/incomplete-turn.ts (bypass guard in Phase A)
Estimated size: ~600 LoC
Open questions (resolve at implementation)
- Does "ok do it" during Phase A count as approval → Phase B?
- Should
exec read-only whitelist be user-editable in config?
- Should plan mode block
sessions_spawn during Phase A?
Verification
gpt54-plan-mode-approve.scenario.yaml — plan → approve → execute
gpt54-plan-mode-reject.scenario.yaml — plan → reject → abort
gpt54-default-no-plan-mode.scenario.yaml — default GPT-5 does NOT enter plan mode
GPT 5.4 Enhancement v3 — Phase 3.C
Tracking: #66345
Priority: P1 — The marquee Claude Code-quality feature (opt-in only)
Hard depends on: #61845 merging (plan-mode runtime from nick0809cn-ux)
Also depends on: #67514 (task-system parity), #67519 (plan rendering)
Context
PR #61845 already builds the plan-mode runtime core:
SessionRuntimeMode = "plan" | "normal" | "auto"enter_plan_mode/exit_plan_modeagent toolsplan-mode-hook.tsmutation gate (blocks 11+ tool categories)todo_write/task_create/task_updateplan-mode toolsThis issue covers the layer above #61845: user-facing entry points and the approval UX that makes plan mode trustworthy. Without this, plan mode is two phases with no human review gate.
Scope
Entry points (all opt-in, never auto-enabled)
/plan <optional goal>— one-shot opt-in for the next turnagents.defaults.planMode.enabled: false— per-agent defaultagents.defaults.planMode.autoEnableFor: []— regex list (empty by default to preserve Hermes parity)Approval state machine
Channel-native approval UX
Tool-name reconciliation
#61845 introduces
todo_write/task_create/task_updatealongside the existingupdate_plan. This PR ships an adapter so both tool surfaces produce the sameAgentPlanEventDataevents. Both names resolve to the same handler. Deprecation of one name deferred to Phase 4.Strict-agentic interaction
Files to create/modify
src/commands/plan.commands.tssrc/config/types.agent-defaults.ts,src/config/zod-schema.agent-defaults.tssrc/agents/plan-approval.ts+ testsrc/infra/agent-events.ts(new event types)src/channels/plugins/approvals.ts(extend for plan approval)src/agents/pi-embedded-runner/run/incomplete-turn.ts(bypass guard in Phase A)Estimated size: ~600 LoC
Open questions (resolve at implementation)
execread-only whitelist be user-editable in config?sessions_spawnduring Phase A?Verification
gpt54-plan-mode-approve.scenario.yaml— plan → approve → executegpt54-plan-mode-reject.scenario.yaml— plan → reject → abortgpt54-default-no-plan-mode.scenario.yaml— default GPT-5 does NOT enter plan mode