# Chat panel — structured proposal fork

**Status:** Out of scope (deferred, not rejected)
**Captured:** 2026-05-07
**Decision context:** Console v2 + Engine Overhaul build, Phase 17 (chat fork delete) + JT/Claude conversation 2026-05-07 afternoon.

## Decision

The chat surface in Console v2 is the **embedded ttyd terminal** (`<ChatColumn>` in `console-v2/packages/desktop/src/chat/`). Surface backed by `recoil/api/ttyd_routes.py` (`/api/ttyd/start`, `/api/ttyd/health`).

The proposal-based fork (`<ChatPanel>` + `recoil/api/chat_routes.py` + `slash_dispatch.ts`) was deleted in commit `2bee2e6d` (Phase 17 of console-v2-overhaul) because the files were orphaned — `chat_routes` was never registered in `main.py` and `App.tsx` mounted `<ChatColumn>` instead of `<ChatPanel>`. Five files removed; `-971 / +25` net.

## Why ttyd was picked over the proposal-shaped fork

- **Solo workflow.** JT is the only operator today. ttyd's "raw terminal in a panel" pattern doesn't lose anything for a solo user — drag-drop of file paths works, paste works, full Claude Code session inside the iframe. The proposal-shaped surface's value (typed approval gates, multi-user negotiation) doesn't pay for itself with N=1.
- **Reversibility.** Picking ttyd today doesn't foreclose Path B (proposal-shaped) later. The console's queue + proposals architecture remains; only the *chat surface* is terminal-style for now.
- **Functional today.** ttyd binary installs via `brew install ttyd` on both MBP and Studio. Once installed, `<ChatColumn>` works without further wiring. The proposal-shaped fork required ~700 lines of code that was never registered to anything live.

## What this surface is NOT

- It's not the place for typed editorial proposals. That's the **Queue tab** (`/api/queue`), backed by `proposals_routes.py`. Proposals can come from anywhere (chat, automation, model output) and land in the queue for approval/defer/reject.
- It's not consuming the right-side `SELECTED CONTEXT · BINDS CLICKS → CHAT` pane semantically. That pane was designed for the proposal-shaped fork. With ttyd, it's ornamental until either (a) we wire context-injection into the terminal, or (b) Path B comes back.

## Re-litigation triggers (when to revisit)

Open this file again when ANY of the following becomes true:

1. **A second user joins.** The proposal-shaped pattern earns its keep when multiple humans are touching the same show — typed proposals + approval gates avoid stepping on each other. Solo doesn't need it.
2. **Editorial workflow demands typed input.** If JT finds himself routinely typing the same shape ("rewrite prompt for SH04 to remove X, add Y") and would benefit from a structured form + auto-fill from selection state, that's the signal Path B is overdue.
3. **The right-pane `BINDS CLICKS → CHAT` becomes load-bearing.** Today it's cosmetic. If a workflow emerges where the selection-bar's signal *must* flow into chat input automatically, Path B's design wins.

## Re-litigation cost

If/when triggered, the rebuild is:

- **Backend:** ~230 lines (`recoil/api/chat_routes.py` recoverable from `git show 2bee2e6d^:recoil/api/chat_routes.py`)
- **Frontend:** ~427 lines (`ChatPanel.tsx` recoverable from `git show 2bee2e6d^:recoil/console-v2/packages/desktop/src/chat/ChatPanel.tsx`)
- **Slash dispatch:** ~85 lines (`slash_dispatch.ts` recoverable from same commit)
- **Tests:** ~252 lines across two test files (recoverable)
- **Wiring not in the deleted files:** register router in `main.py`; mount `<ChatPanel>` in `App.tsx`; thread selection context into chat input

So roughly a 2-day build for one operator (or one overnight harness build with a tight spec).

## Cited Laws

- Law 14 (anti-pattern memory) — this file IS the durable rejection memo
- Law 15 (ADRs) — ADR-0014 (chat surface = ttyd-only) is the parallel architectural decision; this file is its `.out-of-scope/` complement
- Law 8 (theory before typing) — Path B re-litigation must answer Hak's three questions for the chat surface: where does state live (queue? chat session? both?), where does feedback live (queue badges? chat scrollback?), what breaks if I delete this (and is that meaningfully different from today's delete-cost?)
