Repository navigation
fix: preserve unknown check verdicts across host evidence flows - #27
Conversation
|
Sentinel 已审核此变更,未发现需要报告的问题。 审核覆盖提示: 开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 45ca041e7326 |
forrestlinfeng
left a comment
There was a problem hiding this comment.
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
- 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:36use=== true,!== false, andtypeof === 'boolean'. The next rule change needs edits in all of them. Please introduce one helper inlib/checks.js, e.g.verdictOf(check)→'passed' | 'failed' | 'unknown'(or storeverdictinstead of a nullablefailed). - 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.verificationFailedis still exported with no external caller — make it private. - Execution-trace filtering is duplicated in
lib/distill.js:86-89andlib/distill/prompt.js:84.
Note: interacts with #20 (both reduce L1 evidence); please run the full suite on the combined branch.
|
Sentinel 已审核此变更,未发现需要报告的问题。 审核覆盖提示: 开发 agent 查询详情: 调用 MCP 工具 由 Sentinel 审核 · 目标提交 ea9ad46fb5ed |
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.
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.