Skip to content

ensemble-workflow.js 硬編碼丟棄 codex-call 的錯誤輸出,跨模型 leg 的失敗原因在報表層不可區分 #27

Description

@kiki830621

Problem

workflows/ensemble-workflow.js 的 codex lens prompt 把 codex-call 的錯誤輸出硬編碼丟棄,使跨模型 leg 的任何失敗在 ensemble 報表上都長成同一句話。

workflows/ensemble-workflow.js:375(codexPrompt 第 4 步):

4. Read "$OUT_FILE" back and map Codex's reported issues into the schema. Present Codex's
   findings faithfully in each finding's body. If the run times out / errors / produces
   nothing useful, return EXACTLY one finding: {severity:"INFO", title:"cross-model pass
   incomplete", file:null, body:"codex-call exceeded its lifetime bound or errored;
   cross-model lens did not complete"} — never silently drop it.

body 是字面常數,不含 codex-call 的 stderr。第二層 backstop(ensemble-workflow.js:554 的 integrity finding)同樣硬編碼 'codex lens errored or was terminated — process gap, surfaced but non-blocking'

Type

bug

來源與活體證據

本項由 /idd-verify #25 --pr 26 的 devil's-advocate lens 提出(該 verify 的 master report:#26 (comment),finding #4,HIGH)。

同一次 verify run 自身即為證據:該 run 的 codex lens 因 ChatGPT 配額用盡而失敗,實際回傳的 finding 正是那句硬編碼字串:

[INFO] lens=codex — cross-model pass incomplete

codex-call 當下實際拿到的後端回應是完整且高資訊量的:

error: HTTP 429: {"error":{"type":"usage_limit_reached","message":"The usage limit has been
reached","plan_type":"pro","resets_at":1785902966,"resets_in_seconds":470169}}

usage_limit_reachedplan_type: proresets_in_seconds ≈ 5.4 天 —— 這些全部在報表層被丟棄。使用者看到的只有「cross-model pass incomplete」。

Expected

codex lens 失敗時,finding body 應帶入 codex-call 的 stderr 尾段,使報表讀者能區分失敗類別:

  • HTTP 429 usage_limit_reached → 配額用盡,等 reset(本例 5.4 天),重試無用
  • server_is_overloaded(HTTP 200 + SSE error)→ 暫時性壅塞,可立即重試
  • HTTP 401 → 憑證失效,需重新登入
  • timeout → 可能 diff 過大,考慮縮小範圍

Actual

全部顯示為 cross-model pass incomplete,無法區分。讀報表的人若想知道原因,必須人工去翻該次 agent transcript 裡那一行 Bash 呼叫的 stderr。

Impact

  • #25 的自陳目的在使用者可見層級無法達成#25 修的是 codex-call 端的訊息提取;即使該端完全修好,只要本 issue 未解,ensemble 報表仍顯示同一句常數。兩者是同一條資訊鏈的上下游
  • 影響所有消費 pai-ensemble 的 caller,包括 idd-verify 的 canonical backend tier
  • 使「該重試還是該停手」在報表層仍不可判定 —— 這正是 #25 想解決的問題,只是換了一層出現

Strategy(初步,待 diagnose 確認)

  • codexPrompt 第 4 步改為要求把 $OUT_FILE / stderr 的尾段(截斷至合理長度)放進 finding body
  • ensemble-workflow.js:554 的 integrity finding 同樣帶入可得的失敗上下文
  • test/ensemble-workflow.test.mjs 釘住:codex leg 失敗時 finding body 不得等於常數字串
  • 考量 stderr 可能含敏感內容(OAuth 相關訊息)—— 需決定截斷/遮罩策略

#25 的關係

刻意拆為獨立 issue(使用者決定,2026-07-31)。理由:本項動的是 workflows/ensemble-workflow.js#25 動的是 bin/codex-call,屬不同檔案與不同抽象層。#25 保持 scope 乾淨只管 codex-call 端;兩者合起來才讓錯誤資訊端到端可讀。


Source: surfaced during /idd-verify #25 --pr 26 follow-up triage(devil's-advocate lens,HIGH finding #4

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions