Skip to content

[GPT 5.4 v3 Phase 3.C] Plan-mode entry points + approval UX (builds on #61845) #67520

Description

@100yenadmin

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)

  1. Slash command: /plan <optional goal> — one-shot opt-in for the next turn
  2. Config flag: agents.defaults.planMode.enabled: false — per-agent default
  3. Model gate: agents.defaults.planMode.autoEnableFor: [] — regex list (empty by default to preserve Hermes parity)
  4. 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)

  1. Does "ok do it" during Phase A count as approval → Phase B?
  2. Should exec read-only whitelist be user-editable in config?
  3. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions