# Debug Plan: Half Question Button Locks QueryBox **Date:** 2026-05-18 **Symptom:** After clicking "Half Question", the textarea appears locked (grayed out, cursor-not-allowed), raising concern that incoming ASR text chunks won't accumulate. --- ## Root Cause Analysis ### The Disable Chain ``` User clicks "Half Question" → QueryInput.onClick: onHalfQuestion(trimmed) → LTTPage.handleHalfQuestion: queryStream.decomposeOnly({ question }) → queries.tsx decomposeOnly: setState({ phase: 'decomposing' }) [IMMEDIATE] → LTTPage: isLoading = true (phase !== 'idle' && !== 'completed' && !== 'error') → QueryInput.textarea: disabled={isLoading} = true ← TEXTAREA LOCKS → QueryInput.buttons: disabled={isDisabled} = true ← BUTTONS LOCK ``` ### What ACTUALLY Happens vs What User Perceives | Concern | Reality | |---------|---------| | Text accumulation stops? | **No.** React controlled `value={displayValue}` updates even when `disabled`. ASR text continues to display. Playwright confirmed: 250→421 chars during Half Question processing. | | Buttons permanently locked? | **No.** When SSE `completed` event arrives, phase→`completed`, `isLoading`→`false`, all re-enabled. | | Textarea editable during wait? | **No.** This IS the issue. Textarea is `disabled={isLoading}`, so user cannot edit/select text during the 5-30s LLM decomposition call. | ### The Real Bug The textarea should NOT be disabled during half-question processing. The half-question feature is meant to be non-blocking — users should be able to: 1. **Continue seeing ASR text accumulate** ✅ (works via controlled component) 2. **Edit the accumulating text** ❌ (textarea disabled prevents typing/selection) 3. **Click "Final Submit" later** ❌ (button disabled during API call) 4. **Click "Half Question" again** ❌ (button disabled during API call) **But** #2 is the primary concern. Users physically cannot interact with the textarea while the LLM decomposes the question — and they can't even see that text IS still accumulating because the grayed-out disabled style makes it look frozen. --- ## Where Every Prop Wires ``` frontend/src/pages/LTTPage.tsx line 73: handleHalfQuestion → queryStream.decomposeOnly({ question }) line 81: isLoading = phase !== 'idle' && !== 'completed' && !== 'error' line 166: ← shared isLoading frontend/src/components/QueryInput.tsx line 52: isDisabled = isLoading || displayValue.trim() === '' line 66: