fix(pilot): applied_at stamps on run-declaring actions, not Apply click
Per Phase 9 §5. Before: banner Apply click stamped applied_at regardless of whether the engineer had committed to running anything, starting the Verifying timer prematurely. After: - handleApplyFix no longer calls applyFix(). It just routes to the right surface (TemplateMatchPanel / InlineNoTemplateDialog / Script Builder tab). - handleScriptDecision stamps applied_at for one_off + draft_template (both labels are 'Run now, …' — the click is the declaration). build_template does not stamp. - TemplateMatchPanel's new 'I ran this' button calls applyFix via a new onMarkRun prop. - Script Builder tab Submit does not stamp (a draft is not a run). No backend change — the /apply endpoint is unchanged. Only call sites move. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -515,6 +515,17 @@ export default function AssistantChatPage() {
|
||||
} else if (decision === 'draft_template') {
|
||||
toast.success('Draft template queued — review after Resolve')
|
||||
}
|
||||
// Phase 9 §5: one_off and draft_template declare a run ("Run now, …").
|
||||
// Stamp applied_at to transition the fix into Verifying.
|
||||
// build_template does NOT run — no stamp.
|
||||
if (decision === 'one_off' || decision === 'draft_template') {
|
||||
try {
|
||||
const updated = await sessionSuggestedFixesApi.applyFix(
|
||||
activeChatId, activeFix.id,
|
||||
)
|
||||
setActiveFix(updated)
|
||||
} catch { /* non-fatal: engineer can still mark outcome later */ }
|
||||
}
|
||||
// Keep the panel open so the engineer can copy the rendered script.
|
||||
} catch {
|
||||
toast.error('Failed to record decision')
|
||||
@@ -552,6 +563,20 @@ export default function AssistantChatPage() {
|
||||
setChatTab('script_builder')
|
||||
}, [activeFix])
|
||||
|
||||
// Phase 9 Task 13: TemplateMatchPanel "I ran this" — stamps applied_at so the
|
||||
// ProposalBanner transitions from Proposed to Verifying. Shared useCallback so
|
||||
// both render sites (narrow-drawer + side-panel) are identical.
|
||||
const handleMarkRun = useCallback(async () => {
|
||||
if (!activeFix || !activeChatId) return
|
||||
try {
|
||||
const updated = await sessionSuggestedFixesApi.applyFix(
|
||||
activeChatId, activeFix.id,
|
||||
)
|
||||
setActiveFix(updated)
|
||||
setScriptPanelOpen(false)
|
||||
} catch { /* non-fatal: engineer can still mark outcome later */ }
|
||||
}, [activeFix, activeChatId])
|
||||
|
||||
// Phase 8: record a terminal outcome for the active fix. Updates local state
|
||||
// on success. For applied_success also opens the Resolve preview.
|
||||
const handleSetOutcome = useCallback(async (outcome: FixOutcome, notes?: string) => {
|
||||
@@ -1697,6 +1722,7 @@ export default function AssistantChatPage() {
|
||||
fix={activeFix}
|
||||
sessionId={activeChatId}
|
||||
onClose={() => setScriptPanelOpen(false)}
|
||||
onMarkRun={handleMarkRun}
|
||||
/>
|
||||
)}
|
||||
<div className="flex items-center gap-3 px-3 mt-1">
|
||||
@@ -1767,6 +1793,7 @@ export default function AssistantChatPage() {
|
||||
fix={activeFix}
|
||||
sessionId={activeChatId}
|
||||
onClose={() => setScriptPanelOpen(false)}
|
||||
onMarkRun={handleMarkRun}
|
||||
/>
|
||||
)}
|
||||
<div className="flex items-center gap-3 px-3 mt-1">
|
||||
|
||||
Reference in New Issue
Block a user