Skip to content

Plan review re-opens for a plan already decided in the same session #1075

Description

@jpvarbed

Summary

A plan review re-opens for a plan that was already decided, in two situations. Both reproduce on main (56df64c7, v0.23.1), run from source.

Case 1 — ExitPlanMode: identical plan submitted twice opens two reviews

EVENT='{"tool_name":"ExitPlanMode","session_id":"sess-abc","tool_input":{"plan":"# Add caching layer\n\n- add redis client\n- wire cache into handler\n"}}'
echo "$EVENT" | plannotator     # review opens -> approve it
echo "$EVENT" | plannotator     # a second review opens for the identical plan

Observed: two separate review servers/sessions. There is no dedup on this path — the plan text is read straight from event.tool_input.plan and handed to startPlannotatorServer.

Case 2 — Codex Stop: a bookkeeping-only turn re-opens the previous turn's plan

The Stop hook fires at the end of every turn and scrapes the transcript for the latest plan. If the next turn doesn't propose a new plan (e.g. the agent only wrote a file or recorded a decision), the previously-approved plan is still the latest one in the transcript, so it gets reviewed again.

Repro: send a Stop event whose rollout contains a <proposed_plan> block, approve it, append a non-plan assistant message to the rollout, then send a second Stop event with a new turn_id. A second review opens for the same plan.

getLatestCodexPlan does guard against this, but only within a turn — it requires stop_hook_active and a <hook_prompt marker in the transcript (apps/hook/server/codex-session.ts:244, and the unchanged-plan comparison below it). Once the turn boundary is crossed, neither condition holds and the guard doesn't apply.

Expected

A plan that was already approved isn't re-reviewed unless it changes — at least within the same agent session. saveToHistory already dedups identical resubmissions for version history, but nothing consults a prior decision before opening a session.

Impact

The user is asked to approve the same unchanged plan more than once. In an agent loop where turns end frequently (Codex Stop), this fires on turns that did no planning at all.

Environment

  • Plannotator main @ 56df64c7 (v0.23.1), run from source via bun apps/hook/server/index.ts
  • macOS, bun 1.3.14
  • Reproduced with PLANNOTATOR_BROWSER=/usr/bin/true and an isolated PLANNOTATOR_DATA_DIR, approving via POST /api/approve

Note

Happy to send a PR if this is worth fixing and you have a preference for the shape — I have a working patch that records the approval keyed by (project, session id, normalized plan) and skips re-opening on an exact match within the same session, but I didn't want to presume the design. Branch: https://github.com/jpvarbed/plannotator/tree/jas-248-hook-decision-reuse

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions