fix(suggested-fix-pending): apply PR #156 review fixes

- Page-level Resolve patches applied_pending → applied_success before
  opening the resolution flow, so resolved sessions don't carry a
  provisional pending fix.
- Page-level Escalate intercept now catches applied_pending in addition
  to verifying/partial; intercept copy generalized from "Verifying state"
  to "still needs an outcome."
- PendingBanner gains a Dismiss action, matching the PR body and the
  backend's allowed pending → dismissed transition.
- resolution_note_generator and escalation_package_generator system
  prompts no longer include real-looking pending examples (anti-parrot
  guardrail compliance).

Verified via Docker: prompt anti-parrot 2/2, suggested-fix outcome suite
21/21, frontend tsc -b clean, npm run build clean.

Co-Authored-By: Codex <noreply@openai.com>
This commit is contained in:
2026-04-30 23:02:46 -04:00
parent 7cee7228dc
commit 5bee264d70
8 changed files with 59 additions and 33 deletions

View File

@@ -49,8 +49,8 @@ export function EscalateInterceptDialog({
Before escalating what happened with the fix?
</div>
<div className="text-[12px] text-muted-foreground leading-[1.5] mb-3">
&ldquo;{fixTitle}&rdquo; is still in the Verifying state. Tag its outcome so
the senior picking this up knows what&apos;s been tried.
&ldquo;{fixTitle}&rdquo; still needs an outcome. Tag it so the senior
picking this up knows what&apos;s been tried.
</div>
<div className="flex flex-col gap-1.5">
<button

View File

@@ -260,7 +260,7 @@ function PartialBanner({ fix, onOutcome, onApply }: ProposalBannerProps) {
)
}
function PendingBanner({ fix, onOutcome }: ProposalBannerProps) {
function PendingBanner({ fix, onOutcome, onDismiss }: ProposalBannerProps) {
return (
<div className="relative border-t border-info/30 bg-gradient-to-b from-info-dim/40 to-info-dim/20 px-5 py-3 animate-slide-up">
<div className="absolute left-0 top-0 bottom-0 w-[3px] bg-info" />
@@ -286,6 +286,12 @@ function PendingBanner({ fix, onOutcome }: ProposalBannerProps) {
)}
</div>
<div className="flex items-center gap-2 shrink-0 pt-0.5">
<button
onClick={onDismiss}
className="px-3 py-[9px] rounded-lg text-muted-foreground text-[12.5px] hover:bg-white/[0.08] hover:text-primary"
>
Dismiss
</button>
<button
onClick={() => {
const reason = window.prompt(

View File

@@ -966,7 +966,8 @@ export default function AssistantChatPage() {
const inVerifyState =
activeFix && (
(!!activeFix.applied_at && activeFix.status === 'proposed') ||
activeFix.status === 'applied_partial'
activeFix.status === 'applied_partial' ||
activeFix.status === 'applied_pending'
)
if (inVerifyState && activeFix) {
setEscalateIntercept({ fixId: activeFix.id, fixTitle: activeFix.title })
@@ -1004,10 +1005,15 @@ export default function AssistantChatPage() {
}
}, [activeChatId, escalateIntercept])
// Phase 8: Resolve click — auto-mark applied_success if in verifying state
// Phase 8: Resolve click — auto-mark applied_success if in verifying/pending state
// before opening the resolution note preview.
const handleResolveClick = useCallback(async () => {
if (activeFix && activeFix.applied_at && activeFix.status === 'proposed' && activeChatId) {
const shouldMarkFixSuccessful =
activeFix
&& activeFix.applied_at
&& (activeFix.status === 'proposed' || activeFix.status === 'applied_pending')
&& activeChatId
if (shouldMarkFixSuccessful) {
try {
const updated = await sessionSuggestedFixesApi.patchOutcome(activeChatId, activeFix.id, 'applied_success')
setActiveFix(updated)