fix: preserve live mutating code queue retries

This commit is contained in:
Codex
2026-05-29 23:17:32 +00:00
parent 4326ffe2f5
commit 1445f155b3
3 changed files with 38 additions and 1 deletions
@@ -842,6 +842,10 @@ function applyJudgeSafetyOverrides(task: QueueTask, result: CodexRunResult, judg
return judge;
}
export function applyJudgeSafetyOverridesForTest(task: QueueTask, result: CodexRunResult, judge: JudgeResult): JudgeResult {
return applyJudgeSafetyOverrides(task, result, judge);
}
export async function judgeTask(task: QueueTask, result: CodexRunResult): Promise<JudgeResult> {
if (config().minimaxApiKey.length === 0) {
const judge = applyJudgeSafetyOverrides(task, result, fallbackJudge(result));
@@ -2,7 +2,7 @@
import { minimaxM27Model } from "./code-agent/common";
import { openCodeTransportClosedBeforeTerminal, remoteOpenCodeRunCommandForTest } from "./code-agent/opencode";
import { continuePromptSourceBudgetChars, miniMaxJudgeMessages, parsedContinuePromptForJudge, parseJudgeJson, queueRecoveryRetryPrompt, retryPrompt } from "./judge";
import { applyJudgeSafetyOverridesForTest, continuePromptSourceBudgetChars, miniMaxJudgeMessages, parsedContinuePromptForJudge, parseJudgeJson, queueRecoveryRetryPrompt, retryPrompt } from "./judge";
import { codeQueueEnvironmentHintTitle, injectCodeQueueEnvironmentHint, promptWithCodeQueueEnvironmentHint, userPromptForDisplay } from "./prompts";
import { buildTaskTranscript, safePreview, taskTraceSummaryFixtureResponse, transcriptLineSummaryLines } from "./task-view";
import type { ActiveRunSlotWaiter } from "./code-agent/common";
@@ -265,6 +265,30 @@ async function runReferenceInjectionSelfTest(): Promise<JsonValue> {
...Array.from({ length: 80 }, (_, index) => `验收点 ${index + 1}: 基于当前 thread 上文补齐缺失证据,并在最终 response 中写出真实命令/API/UI 结果。`),
].join("\n");
const explicitRetryPrompt = retryPrompt(retryTask, { decision: "retry", confidence: 1, reason: "Long MiniMax feedback fixture", continuePrompt: explicitLongContinuePrompt, source: "minimax" });
const liveMutatingDevicePodPrompt = [
"DEV test class: live-mutating hardware smoke on G14 DEV device-pod only.",
"",
"Allowed live mutation:",
"- 仅允许通过 `hwpod` 修改 `device-pod-71-freq` 的 `workspace:/projects/01_baseline` 下 firmware 源码和 Keil project membership。",
"",
"Forbidden actions:",
"- 禁止使用 `/app/tools/tran.mjs`,禁止上传临时脚本。",
"",
"Closeout fields:",
"- `DEV test class`、`Allowed mutation actually used`、`Forbidden actions avoided`。",
].join("\n");
const liveMutatingDevicePodTask = testTask("codex_live_mutating_device_pod_retry", liveMutatingDevicePodPrompt, "", [], "2026-05-08T00:32:00.000Z");
const liveMutatingDevicePodRetry = applyJudgeSafetyOverridesForTest(liveMutatingDevicePodTask, {
threadId: "thread_live_mutating_device_pod_retry",
turnId: "turn_live_mutating_device_pod_retry",
finalResponse: "",
terminalStatus: "failed",
terminalError: "unexpected status 503 Service Unavailable",
transportClosedBeforeTerminal: false,
appServerExit: { code: 0, signal: null, stderrTail: "" },
events: [],
}, { decision: "retry", confidence: 0.7, reason: "Codex turn 失败。", continuePrompt: "继续完成原始任务。", source: "fallback" });
const liveMutatingContinuePrompt = liveMutatingDevicePodRetry.continuePrompt ?? "";
let longMiniMaxPromptRejectedAtSource = false;
try {
parsedContinuePromptForJudge({ continuePrompt: `${"x".repeat(continuePromptSourceBudgetChars + 1)}` }, "retry");
@@ -277,6 +301,10 @@ async function runReferenceInjectionSelfTest(): Promise<JsonValue> {
assertReferenceTest(!recoveryAfterDeepReference.includes("Reference Round"), "queue recovery prompt should not re-inject reference rounds");
assertReferenceTest(explicitRetryPrompt === explicitLongContinuePrompt, "explicit continuePrompt should not be tail-truncated");
assertReferenceTest(!explicitRetryPrompt.includes("已截断"), "explicit continuePrompt should not include truncation marker");
assertReferenceTest(liveMutatingContinuePrompt.includes("live-mutating hardware smoke"), "live-mutating retry should preserve the original authorization summary");
assertReferenceTest(liveMutatingContinuePrompt.includes("hwpod"), "live-mutating retry should preserve tool authorization details");
assertReferenceTest(!liveMutatingContinuePrompt.includes("只读 continuation"), "live-mutating retry must not be downgraded to read-only continuation");
assertReferenceTest(!liveMutatingContinuePrompt.includes("不改变运行态、生产态或持久化状态"), "live-mutating retry must not add generic read-only mutation bans");
assertReferenceTest(longMiniMaxPromptRejectedAtSource, "over-budget MiniMax continuePrompt should be rejected for source repair");
return {
ok: true,
@@ -291,6 +319,7 @@ async function runReferenceInjectionSelfTest(): Promise<JsonValue> {
{ name: "retry_prompt_does_not_reinject_reference_graph", ok: true, chars: retryAfterDeepReference.length },
{ name: "queue_recovery_prompt_is_compact", ok: true, chars: recoveryAfterDeepReference.length },
{ name: "explicit_continue_prompt_not_tail_truncated", ok: true, chars: explicitRetryPrompt.length },
{ name: "live_mutating_retry_not_downgraded_to_readonly", ok: true, chars: liveMutatingContinuePrompt.length },
{ name: "over_budget_minimax_continue_prompt_requires_source_repair", ok: true, budgetChars: continuePromptSourceBudgetChars },
],
promptPreview: safePreview(promptC, 1200),