- Before escalating — what happened with the fix?
-
-
- “{fixTitle}” is still in the Verifying state. Tag its outcome so
- the senior picking this up knows what's been tried.
-
-
-
-
-
-
-
+ {!partialStep ? (
+ <>
+
+ Before escalating — what happened with the fix?
+
+
+ “{fixTitle}” is still in the Verifying state. Tag its outcome so
+ the senior picking this up knows what's been tried.
+
+
+
+
+
+
+
+ >
+ ) : (
+ <>
+
+ What partially worked?
+
+
+ A short note for whoever picks this up — what you tried, what worked, what's still broken.
+
+
>
)
diff --git a/frontend/src/pages/AssistantChatPage.tsx b/frontend/src/pages/AssistantChatPage.tsx
index a742f1f4..d1101ff6 100644
--- a/frontend/src/pages/AssistantChatPage.tsx
+++ b/frontend/src/pages/AssistantChatPage.tsx
@@ -656,19 +656,33 @@ export default function AssistantChatPage() {
setShowConclude(true)
}, [activeFix])
- const handleInterceptChoice = useCallback(async (choice: InterceptChoice) => {
+ const handleInterceptChoice = useCallback(async (choice: InterceptChoice, notes?: string) => {
const stored = escalateIntercept
- setEscalateIntercept(null)
- if (!stored || !activeChatId) return
+ if (!stored || !activeChatId) {
+ setEscalateIntercept(null)
+ return
+ }
const outcomeToSend: FixOutcome =
choice === 'never_applied' ? 'dismissed' : choice
try {
const updated = await sessionSuggestedFixesApi.patchOutcome(
- activeChatId, stored.fixId, outcomeToSend,
+ activeChatId, stored.fixId, outcomeToSend, notes,
)
setActiveFix(updated)
- } catch { /* non-fatal — engineer can still escalate */ }
- setShowConclude(true)
+ setEscalateIntercept(null)
+ setShowConclude(true)
+ } catch (err) {
+ // applied_partial without notes (or any other 4xx) must surface — the
+ // previous silent catch let engineers believe the partial outcome was
+ // recorded while it was rejected server-side.
+ const message = choice === 'applied_partial'
+ ? 'Couldn’t record the partial outcome. Add a short note and try again.'
+ : 'Couldn’t record the outcome before escalating. Try again.'
+ toast.error(message)
+ // Keep the intercept open so the engineer can retry (partial path can
+ // re-enter the notes step from the dialog).
+ if (import.meta.env.DEV) console.warn('[AssistantChat] intercept outcome failed:', err)
+ }
}, [activeChatId, escalateIntercept])
// Phase 8: Resolve click — auto-mark applied_success if in verifying state
@@ -1629,7 +1643,12 @@ export default function AssistantChatPage() {
so both scroll positions and state are preserved across tab switches. */}
{showTabStrip && activeFix && activeChatId && (
+ {/* key={activeFix.id} forces a fresh mount when the active
+ fix changes within the same pilot session — otherwise
+ stale messages / editorBuffer / latestScript from the
+ prior fix could submit against the new fix.id. */}