Skip to content

fix: Pause & Outline Plan — enforce outline before ExitPlanMode retry #87

@nathanschram

Description

Problem

When the user clicks "Pause & Outline Plan", Claude Code sometimes retries ExitPlanMode without writing a visible outline (~3-4 times out of 10). The user sees approval buttons again with no plan text.

Root Cause

The cooldown mechanism (check_discuss_cooldown) only blocks ExitPlanMode retries within a time window (30s, 60s, 90s, 120s). Once the window expires, ExitPlanMode goes through normally — even if no outline was written.

The _OUTLINE_PENDING set tracks that an outline is expected, and max_text_len_since_cooldown tracks how much text Claude wrote, but neither is checked when the cooldown expires. The code falls through to the normal 3-button flow.

Fix

A. Code guard (src/untether/runners/claude.py): Before checking the time-based cooldown, check if the session is in _OUTLINE_PENDING AND max_text_len_since_cooldown < 200. If so, auto-deny ExitPlanMode regardless of cooldown expiry.

B. Prompt strengthening (src/untether/telegram/commands/claude_control.py): Rewritten _DISCUSS_DENY_MESSAGE to open with "STOP. Do NOT call ExitPlanMode", add explicit "it does not matter what you already know", and warn about automatic rejection.

C. Escalation messages (src/untether/runners/claude.py): _DISCUSS_ESCALATION_MESSAGE now says "REJECTED" with clear reason; _OUTLINE_WAIT_MESSAGE warns further calls will be rejected.

Impact

  • Only affects the failure case (no outline written after discuss click)
  • Happy path (outline written, buttons shown, user clicks) unchanged
  • Cooldown timing, synthetic buttons, session cleanup all unchanged

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingengine:claudeClaude Code CLI (Anthropic)

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions