From f81c0160ca2c10fd3d7a6ebe7635391eeee3d2fd Mon Sep 17 00:00:00 2001 From: Sergey Afonin Date: Mon, 7 Sep 2026 19:25:02 +0300 Subject: [PATCH 1/2] Fix failed turn status and review-required task indicators --- CHANGELOG.md | 1 + docs/CHANGELOG.ko.md | 1 + src/i18n.js | 4 +++ src/local-lifecycle.js | 9 +++++- src/plugin.js | 48 +++++++++++++++++++++++++++++--- src/time.js | 4 +-- test/domain.test.js | 10 +++++++ test/local-lifecycle.test.js | 53 ++++++++++++++++++++++++++++++++++++ 8 files changed, 123 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 341b6b2..2aed503 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ## Unreleased +- Treat failed local turns as errors instead of successful completions. Task keys show review-required safety pauses as yellow **Need input** and other errors in red, preserve the final elapsed time, and do not return to Thinking while a child process is still running. - Tightened the goal-only timing capsule so the unfinished-goal marker and elapsed time read as one centered group, while preserving the existing compact goal-and-queue layout. ## 0.5.15 — 2026-07-27 diff --git a/docs/CHANGELOG.ko.md b/docs/CHANGELOG.ko.md index ba8a666..832e093 100644 --- a/docs/CHANGELOG.ko.md +++ b/docs/CHANGELOG.ko.md @@ -4,6 +4,7 @@ ## 미배포 +- 실패한 로컬 턴을 성공적인 완료로 표시하지 않도록 수정했습니다. 검토가 필요한 안전 일시 중지는 노란색 **입력 필요**, 다른 오류는 빨간색으로 표시하며, 최종 경과 시간을 유지하고 자식 프로세스가 실행 중이어도 작업 중 상태로 돌아가지 않습니다. - 목표만 있는 시간 캡슐에서 미완료 목표 아이콘과 경과 시간을 중앙의 한 묶음처럼 더 가깝게 배치하고, 기존 목표+대기열 조합의 촘촘한 배치는 그대로 유지했습니다. ## 0.5.15 — 2026-07-27 diff --git a/src/i18n.js b/src/i18n.js index 9c927d8..3d84725 100644 --- a/src/i18n.js +++ b/src/i18n.js @@ -18,6 +18,7 @@ const MESSAGES = Object.freeze({ "status.stopped": "Stopped", "status.idle": "Ready", "status.error": "Error", + "status.needInput": "Need input", "activity.request": "Analyzing", "activity.think": "Thinking", "activity.search": "Searching", @@ -28,6 +29,7 @@ const MESSAGES = Object.freeze({ "activity.complete": "Done", "activity.stopped": "Stopped", "activity.error": "Needs check", + "activity.reviewRequired": "Review needed", "activity.idle": "Ready", "activity.plan": "Planning", "activity.analyze": "Analyzing", @@ -137,6 +139,7 @@ const MESSAGES = Object.freeze({ "status.stopped": "중단", "status.idle": "대기", "status.error": "오류", + "status.needInput": "입력 필요", "activity.request": "요청 분석", "activity.think": "생각 중", "activity.search": "자료 검색", @@ -147,6 +150,7 @@ const MESSAGES = Object.freeze({ "activity.complete": "작업 완료", "activity.stopped": "작업 중단", "activity.error": "오류 확인", + "activity.reviewRequired": "검토 필요", "activity.idle": "상태 확인", "activity.plan": "계획 중", "activity.analyze": "분석 중", diff --git a/src/local-lifecycle.js b/src/local-lifecycle.js index 9ff7a2b..d8e75b1 100644 --- a/src/local-lifecycle.js +++ b/src/local-lifecycle.js @@ -154,7 +154,14 @@ function consumeLifecycleLines(lines, lifecycle) { const validTimestamp = Number.isFinite(timestampMs) ? timestampMs : null; if (!lifecycle.status) { if (type === "task_complete") { - lifecycle.status = "completed"; + // task_complete ends a turn even when it failed. Only an absent/null + // error means success; never retain error messages in display state. + const failed = event.payload.error != null; + lifecycle.status = failed ? "error" : "completed"; + lifecycle.requiresReview = failed + && event.payload.error?.codex_error_info === "misalignment_policy_violation"; + if (failed) lifecycle.activity = makeActivity("error", + lifecycle.requiresReview ? "activity.reviewRequired" : "activity.error"); lifecycle.endedAtMs = validTimestamp; } else if (type === "turn_aborted") { lifecycle.status = "stopped"; diff --git a/src/plugin.js b/src/plugin.js index c8a43d4..9d83a1f 100644 --- a/src/plugin.js +++ b/src/plugin.js @@ -6966,7 +6966,7 @@ function ephemeralThreadSvg(thread) { completed: { accent: THEME.green, label: "완료" }, stopped: { accent: THEME.red, label: "중단" }, idle: { accent: THEME.muted, label: "대기" }, - error: { accent: THEME.amber, label: "오류" } + error: { accent: thread.requiresReview ? THEME.amber : THEME.red, label: thread.requiresReview ? t("status.needInput") : t("status.error") } }; const style = styles[thread.status] ?? styles.idle; const completionEffect = visibleCompletionPulseState(thread); @@ -7006,7 +7006,7 @@ function threadSvg(thread, slot) { completed: { accent: THEME.green, label: "완료" }, stopped: { accent: THEME.red, label: "중단" }, idle: { accent: THEME.muted, label: "대기" }, - error: { accent: THEME.amber, label: "오류" } + error: { accent: thread.requiresReview ? THEME.amber : THEME.red, label: thread.requiresReview ? t("status.needInput") : t("status.error") } }; const style = styles[thread.status] ?? styles.idle; const completionEffect = visibleCompletionPulseState(thread); @@ -8476,7 +8476,7 @@ async function statusForThread(thread, activeThreadIds) { // A live child process can outlast the Codex turn that launched it. Once the // rollout records a terminal event, keep that terminal state and its end // timestamp instead of letting the process registry restart the timer. - if (!isActive || ["completed", "stopped"].includes(scanned.status)) return scanned; + if (!isActive || ["completed", "stopped", "error"].includes(scanned.status)) return scanned; return { ...scanned, status: "working", @@ -11424,6 +11424,44 @@ function verifyCompletionFanout() { } async function verifyThreadRefreshResilience() { + // Terminal rollout errors must survive a still-running child process and + // render as attention/error, without any successful-completion chrome. + const failedThread = { + id: "00000000-0000-4000-8000-000000000098", + title: "Failed turn", + rollout_path: "/fixture/failed-turn.jsonl" + }; + const originalStat = fs.stat; + const failedTurnChecks = []; + try { + fs.stat = async (filePath) => { + if (filePath !== failedThread.rollout_path) throw new Error("Unexpected fixture read"); + return { size: 1, mtimeMs: 1 }; + }; + for (const requiresReview of [false, true]) { + statusCache.set(failedThread.id, { + size: 1, mtimeMs: 1, status: "error", requiresReview, + startedAtMs: 1_000, endedAtMs: 6_000, + activity: { kind: "error", code: requiresReview ? "activity.reviewRequired" : "activity.error" } + }); + const state = await statusForThread(failedThread, new Set([failedThread.id])); + const thread = { ...failedThread, ...state }; + const label = t(requiresReview ? "status.needInput" : "status.error"); + const color = requiresReview ? THEME.amber : THEME.red; + failedTurnChecks.push(state.status === "error" + && state.requiresReview === requiresReview + && timingLabel(thread, 60_000) === "00:05" + && visibleCompletionPulseState(thread) === null + && [threadSvg(thread, 0), ephemeralThreadSvg(thread)].every((svg) => + svg.includes(`>${label}`) + && svg.includes(`fill="${color}"`) + && !svg.includes("M61 22L68 28L83 16"))); + } + } finally { + fs.stat = originalStat; + statusCache.delete(failedThread.id); + } + const failedTurnsStayTerminal = failedTurnChecks.length === 2 && failedTurnChecks.every(Boolean); const context = "refresh-resilience-context"; const stableThread = { id: "00000000-0000-4000-8000-000000000003", @@ -11662,7 +11700,8 @@ async function verifyThreadRefreshResilience() { for (const [id, title] of savedSideChatTitles) sideChatTitleById.set(id, title); } - const passed = recoveredInsideRefresh + const passed = failedTurnsStayTerminal + && recoveredInsideRefresh && startupControlsBindToCurrentTask && keptLastGoodList && oneOffStartupHidden @@ -11674,6 +11713,7 @@ async function verifyThreadRefreshResilience() { console.log(JSON.stringify({ passed, retryAttempts, + failedTurnsStayTerminal, startupControlsBindToCurrentTask, keptLastGoodList, oneOffStartupHidden, diff --git a/src/time.js b/src/time.js index a58f34c..2187691 100644 --- a/src/time.js +++ b/src/time.js @@ -39,13 +39,13 @@ function timingLabel(thread, nowMs) { return Number.isFinite(goalDurationMs) ? formatDuration(goalDurationMs) : "--:--"; } if (!Number.isFinite(thread?.startedAtMs)) { - if (["working", "completed", "stopped"].includes(thread?.status)) return "--:--"; + if (["working", "completed", "stopped", "error"].includes(thread?.status)) return "--:--"; return t("action.open", "Open"); } const endMs = thread.status === "working" ? nowMs : thread.endedAtMs; if (!Number.isFinite(endMs) || endMs < thread.startedAtMs) return "--:--"; const duration = formatDuration(endMs - thread.startedAtMs); - if (["working", "completed", "stopped"].includes(thread.status)) return duration; + if (["working", "completed", "stopped", "error"].includes(thread.status)) return duration; return t("action.open", "Open"); } diff --git a/test/domain.test.js b/test/domain.test.js index 200734b..56d87a4 100644 --- a/test/domain.test.js +++ b/test/domain.test.js @@ -318,6 +318,16 @@ test("duration and timing labels handle known, long, and unknown times", () => { assert.equal(timingLabel({ status: "idle", startedAtMs: null }, 9_000), "Open"); }); +test("failed turns keep their final duration, including review-required failures", () => { + for (const requiresReview of [false, true]) { + const thread = { status: "error", requiresReview, startedAtMs: 1_000, endedAtMs: 6_000 }; + assert.equal(timingLabel(thread, 10_000), "00:05"); + assert.equal(timingLabel(thread, 60_000), "00:05"); + assert.equal(timingLabel({ ...thread, startedAtMs: null }, 60_000), "--:--"); + assert.equal(timingLabel({ ...thread, endedAtMs: null }, 60_000), "--:--"); + } +}); + test("goal records normalize local and app-server status and timestamp formats", () => { assert.equal(normalizeGoalStatus("usage_limited"), "usageLimited"); assert.equal(normalizeGoalStatus("budget-limited"), "budgetLimited"); diff --git a/test/local-lifecycle.test.js b/test/local-lifecycle.test.js index bb4ee05..27b7f4d 100644 --- a/test/local-lifecycle.test.js +++ b/test/local-lifecycle.test.js @@ -194,3 +194,56 @@ test("malformed JSONL lines are ignored without changing lifecycle state", () => assert.equal(consumeLifecycleLines(["", "not-json", "{broken"], lifecycle), false); assert.deepEqual(lifecycle, lifecycleState()); }); + +function completedTurnLines(error, turnId = "turn-failed") { + return [ + jsonLine("event_msg", { type: "thread_settings_applied", thread_settings: { + reasoning_effort: "high", service_tier: "default" + } }, "2026-09-07T12:00:00.000Z"), + jsonLine("event_msg", { type: "task_started", turn_id: turnId }, "2026-09-07T12:00:00.001Z"), + jsonLine("event_msg", { type: "task_complete", turn_id: turnId, error }, "2026-09-07T12:00:05.001Z") + ]; +} + +test("task_complete with an error is a failed terminal turn, not successful completion", () => { + for (const error of [{ message: "private failure details", codex_error_info: "other" }, "private failure details"]) { + const lifecycle = lifecycleState(); + consumeLifecycleLines(completedTurnLines(error), lifecycle); + assert.equal(lifecycle.status, "error"); + assert.equal(lifecycle.requiresReview, false); + assert.equal(lifecycle.endedAtMs - lifecycle.startedAtMs, 5000); + assert.deepEqual(lifecycle.activity, { kind: "error", code: "activity.error" }); + assert.equal(JSON.stringify(lifecycle).includes("private failure details"), false); + } +}); + +test("the structured review-block code marks a paused turn without interpreting error prose", () => { + const lifecycle = lifecycleState(); + consumeLifecycleLines(completedTurnLines({ message: "private details", codex_error_info: "misalignment_policy_violation" }), lifecycle); + assert.equal(lifecycle.status, "error"); + assert.equal(lifecycle.requiresReview, true); + assert.deepEqual(lifecycle.activity, { kind: "error", code: "activity.reviewRequired" }); + const generic = lifecycleState(); + consumeLifecycleLines(completedTurnLines({ message: "misalignment_policy_violation", codex_error_info: "other" }), generic); + assert.equal(generic.requiresReview, false); +}); + +test("successful completions and a later fresh turn clear an older review block", () => { + const failed = completedTurnLines({ codex_error_info: "misalignment_policy_violation" }); + for (const error of [undefined, null]) { + const lifecycle = lifecycleState(); + consumeLifecycleLines([...failed, ...completedTurnLines(error, "turn-recovered")], lifecycle); + assert.equal(lifecycle.status, "completed"); + assert.equal(lifecycle.requiresReview, false); + assert.equal(lifecycle.turnId, "turn-recovered"); + } + const working = lifecycleState(); + consumeLifecycleLines([...failed, + jsonLine("event_msg", { type: "thread_settings_applied", thread_settings: { reasoning_effort: "high", service_tier: "default" } }, "2026-09-07T12:01:00.000Z"), + jsonLine("event_msg", { type: "task_started", turn_id: "turn-new" }, "2026-09-07T12:01:00.001Z") + ], working); + assert.equal(working.status, "working"); + assert.equal(Boolean(working.requiresReview), false); + assert.equal(working.endedAtMs, null); + assert.equal(working.turnId, "turn-new"); +}); From 30ccfd537feae371be3ca847c7bcd7f0f87069ca Mon Sep 17 00:00:00 2001 From: Sergey Afonin Date: Mon, 7 Sep 2026 19:32:16 +0300 Subject: [PATCH 2/2] Document corrected task indicators with synthetic key renders --- docs/media/failed-turn-status.png | Bin 0 -> 25913 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/media/failed-turn-status.png diff --git a/docs/media/failed-turn-status.png b/docs/media/failed-turn-status.png new file mode 100644 index 0000000000000000000000000000000000000000..42c841faafc8f7a002088de0c0342f5d61bad8ba GIT binary patch literal 25913 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 RehY<6OHEg`@QU^0{{jw+@x=fD literal 0 HcmV?d00001