Skip to content

fix: preserve unknown check verdicts across host evidence flows - #27

Merged
forrestlinfeng merged 2 commits into
EvoMap:mainfrom
imxyanua:codex/fix-unknown-check-verdict
Nov 3, 2026
Merged

forrestlinfeng merged 2 commits into
EvoMap:mainfrom
imxyanua:codex/fix-unknown-check-verdict

Conversation

@imxyanua

@imxyanua imxyanua commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Codex can send a finished command's bare stdout without its exit status. Absence of failure words currently becomes a passing check, L1 reuse evidence and a distillation candidate, even when the native command failed.

native exit / supported explicit summary → passed or failed
missing exit + ordinary output → unknown
unknown last check → no candidate, no L1, no claimed saving

Keep unknown as failed:null through canonical records, prompts and summaries. Never serialize it as exit zero or fall back to an earlier passing check. WorkBuddy and DSH stop inventing verdicts when native exit metadata is absent. Recognized positive Node/TAP summaries require pass>0/fail0; positive cancellation counts fail.

Evidence

  • Before: public Codex profile→driver regression produces a candidate from exit:null and bare boom output, including after an earlier pass.

  • After: final 105 targeted tests passed across evidence, candidate/reporting, summaries, both distill paths and Codex. Host regressions cover eight adapters.

  • Linux Node 22.23.4 and 26.13.0 each passed full 650/650, clean npm ci and all eight packs BEFORE the final two-file cancelled-count guard. The final commit is covered by targeted tests and must pass unchanged CI.

  • Captured actual Codex 0.166.0 silent-failure hook payload replayed through the current packed adapter now yields unknown, no candidate and tier none. This is captured-native replay, not a fresh CLI/model run.

  • Native exit0 and known failures remain recognized. Unsupported text-only summaries conservatively remain unknown.

  • Final head 45ca041 passed GitHub CI run 71 on both Node 22 and 26. The external combined PR19–29 snapshot also passed full 757/757 tests and packing all nine hosts on both Linux runtimes, including Core 2.0.47 from feat: add native MiniMax Code host support #19.

Merge Danger

Door: two-way

Adds a nullable failed value to local check records; consumers now require an explicit boolean. No credentials or host configuration changes.

Blast Radius: evidence

Some hosts without native exit metadata will produce fewer verified candidates/L1 reports. Existing persisted candidates are not migrated. Agent-reported MCP evidence remains a separate tier-none contract.

@evomap-aiqa-bot

evomap-aiqa-bot Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Sentinel 已审核此变更,未发现需要报告的问题。

审核覆盖提示: 2 个 hunk/条目缺少完整输入;它们不作为 bug 报告。

开发 agent 查询详情: 调用 MCP 工具 sentinel_pr_review_context,传入 owner_repo="evomap/evolver-agent-plugin"、pr_number=27、head_sha="45ca041e73264c436dcbad93ba34056257652ae7",并按条目追加 finding_id 或 finding_key。

由 Sentinel 审核 · 目标提交 45ca041e7326

@forrestlinfeng forrestlinfeng left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review — approve after changes

Correct and conservative, and it fixes a real false pass. I found no remaining !! / truthy / === false that turns unknown into pass (lib/agent/defaults/mcp.js:60 check.exit !== 0 is fine since zod requires an integer).

Major

  1. The tri-state is spelled out in 7 production files with three different forms — lib/checks.js:23,28, lib/distill/candidate.js:29-30, lib/distill.js:26,86, lib/distill/prompt.js:38,84, lib/turn-summary.js:28,39, lib/reuse.js:36 use === true, !== false, and typeof === 'boolean'. The next rule change needs edits in all of them. Please introduce one helper in lib/checks.js, e.g. verdictOf(check) → 'passed' | 'failed' | 'unknown' (or store verdict instead of a nullable failed).
  2. Coverage loss on Codex — without an exit code, a pass is only recognised from Node/TAP summaries (lib/verification.js:51-53). jest (Tests: 5 passed, 5 total), pytest (===== 5 passed in 0.12s =====), go (ok github.com/x/y), cargo (test result: ok.) and vitest all come back unknown, so Codex will rarely produce candidates/L1 evidence outside Node projects. Either state this as an accepted trade-off in the description or add the passing-summary patterns.

Minor

  • Names now mislead: verificationFailureOf, checkFailed (lib/turn/record.js:47), shellFailed (hosts/workbuddy/transcript.js:86) return null for unknown. verificationFailed is still exported with no external caller — make it private.
  • Execution-trace filtering is duplicated in lib/distill.js:86-89 and lib/distill/prompt.js:84.

Note: interacts with #20 (both reduce L1 evidence); please run the full suite on the combined branch.

@evomap-aiqa-bot

evomap-aiqa-bot Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Sentinel 已审核此变更,未发现需要报告的问题。

审核覆盖提示: 2 个 hunk/条目缺少完整输入;它们不作为 bug 报告。

开发 agent 查询详情: 调用 MCP 工具 sentinel_pr_review_context,传入 owner_repo="evomap/evolver-agent-plugin"、pr_number=27、head_sha="ea9ad46fb5ed4f9ad00bd56ee6f5dca6cf1e4345",并按条目追加 finding_id 或 finding_key。

由 Sentinel 审核 · 目标提交 ea9ad46fb5ed

@forrestlinfeng
forrestlinfeng merged commit 44246c7 into EvoMap:main Nov 3, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants