Goal
Ship M3 of the Chat V2 / Phase 1 Chat UX overhaul: edit, retry, and per-conversation instructions — built on top of message branching so edits and retries are non-destructive (matching Claude.ai / ChatGPT / LibreChat / Open WebUI).
Scope expanded vs. spec §12 M3: added branching infrastructure. Scope shrunk: dropped retry-with-different-model dropdown (regular retry only). Spec §1, §16.9, §16.10, and the "linear-only" non-goal are updated as part of this work.
What's in this milestone
Backend
- Migration:
Message.parent_message_id UUID NULL FK messages.id, Conversation.active_leaf_message_id UUID NULL FK messages.id, Conversation.instructions TEXT NULL. Backfill parent_message_id from sequence for existing rows; backfill active_leaf_message_id to the last message of each conversation.
agent_executor._build_message_history walks active_leaf_message_id → root via parent_message_id instead of ORDER BY sequence. Tool-call ID remap logic stays (operates on the resolved linear path).
- New endpoint
POST /api/conversations/{id}/messages/{msg_id}/edit — creates a sibling user message under the same parent, sets new active leaf, dispatches a turn.
- New endpoint
POST /api/conversations/{id}/messages/{msg_id}/retry — creates a sibling assistant message under the same parent, sets new active leaf, dispatches a turn.
- New endpoint
PATCH /api/conversations/{id}/active-leaf — switches active leaf (sibling navigation).
- New endpoint
PATCH /api/conversations/{id} accepts instructions field. System prompt assembly in _build_message_history appends conversation.instructions after agent prompt + workspace instructions.
Frontend
- Pencil hover icon on user message bubbles → inline editable textarea + Save/Cancel. Save creates a sibling and switches active leaf.
- RotateCcw hover icon on assistant message bubbles → single-click retry creates a sibling.
- Sibling navigation:
< 2/3 > arrows on any message that has siblings. Arrows update active leaf; chat re-renders the active path.
- Conversation header overflow → "Customize this chat" Dialog with autosize textarea + live token cost preview. Save persists
Conversation.instructions.
- Chat store: branch-aware message rendering (flat array of the active path, derived from
active_leaf_message_id), editMessage, retryMessage, switchBranch actions.
Spec updates (in this PR)
docs/superpowers/specs/2026-04-27-chat-ux-design.md:
- §1.1: replace "no branching" with branching-on-edit semantics.
- §1.2: drop "Switching models via retry sets the conversation's current model" + drop the model override dropdown.
- §16.9: drop AlertDialog confirm.
- §16.10: drop the Popover-with-ModelPicker; just a RotateCcw button.
- Non-goals: remove "Branching/tree conversations (linear-only)."
docs/superpowers/plans/2026-04-27-chat-v2-master-plan.md: add a note in the decisions log.
Out of scope
- Retry-with-different-model dropdown.
- Compaction-aware branch handling (M5's problem).
- Branch-aware export (v1 exports active branch only — already correct).
Tests
- Unit:
test_message_history_branching.py — parent-chain walk, sibling resolution, active-leaf switching, edit creates sibling, retry creates sibling.
- E2E (
api/tests/e2e/): edit creates new branch + dispatches turn; retry creates new branch + dispatches turn; PATCH instructions persists and shows up in next turn's system prompt; sibling switch endpoint.
- Vitest: chatStore branch-aware path resolution; editMessage/retryMessage/switchBranch reducers; instructions dialog component.
- Playwright: edit a user message and confirm both branches accessible via arrows; retry an assistant message and switch back; set per-conversation instructions and confirm next response reflects them.
Branching strategy
- PR target:
feature/chat-v2 (NOT main).
- Worktree at
.worktrees/<issue#>-m3-edit-retry-instructions/.
- Branched from
origin/feature/chat-v2, not main.
Closes
This issue closes when M3 ships into feature/chat-v2. The phase-1 tracking issue (#139) stays open.
Goal
Ship M3 of the Chat V2 / Phase 1 Chat UX overhaul: edit, retry, and per-conversation instructions — built on top of message branching so edits and retries are non-destructive (matching Claude.ai / ChatGPT / LibreChat / Open WebUI).
Scope expanded vs. spec §12 M3: added branching infrastructure. Scope shrunk: dropped retry-with-different-model dropdown (regular retry only). Spec §1, §16.9, §16.10, and the "linear-only" non-goal are updated as part of this work.
What's in this milestone
Backend
Message.parent_message_id UUID NULL FK messages.id,Conversation.active_leaf_message_id UUID NULL FK messages.id,Conversation.instructions TEXT NULL. Backfillparent_message_idfromsequencefor existing rows; backfillactive_leaf_message_idto the last message of each conversation.agent_executor._build_message_historywalksactive_leaf_message_id→ root viaparent_message_idinstead ofORDER BY sequence. Tool-call ID remap logic stays (operates on the resolved linear path).POST /api/conversations/{id}/messages/{msg_id}/edit— creates a sibling user message under the same parent, sets new active leaf, dispatches a turn.POST /api/conversations/{id}/messages/{msg_id}/retry— creates a sibling assistant message under the same parent, sets new active leaf, dispatches a turn.PATCH /api/conversations/{id}/active-leaf— switches active leaf (sibling navigation).PATCH /api/conversations/{id}acceptsinstructionsfield. System prompt assembly in_build_message_historyappendsconversation.instructionsafter agent prompt + workspace instructions.Frontend
< 2/3 >arrows on any message that has siblings. Arrows update active leaf; chat re-renders the active path.Conversation.instructions.active_leaf_message_id),editMessage,retryMessage,switchBranchactions.Spec updates (in this PR)
docs/superpowers/specs/2026-04-27-chat-ux-design.md:docs/superpowers/plans/2026-04-27-chat-v2-master-plan.md: add a note in the decisions log.Out of scope
Tests
test_message_history_branching.py— parent-chain walk, sibling resolution, active-leaf switching, edit creates sibling, retry creates sibling.api/tests/e2e/): edit creates new branch + dispatches turn; retry creates new branch + dispatches turn; PATCH instructions persists and shows up in next turn's system prompt; sibling switch endpoint.Branching strategy
feature/chat-v2(NOT main)..worktrees/<issue#>-m3-edit-retry-instructions/.origin/feature/chat-v2, not main.Closes
This issue closes when M3 ships into
feature/chat-v2. The phase-1 tracking issue (#139) stays open.