plan-07: 连接器动作结果验证 — 执行→验证后置条件→上报契约 (#769) - #504
Merged
Milhouszhang merged 8 commits intoJul 9, 2026
Merged
Conversation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rify search landed Fixes agentenv/monorepo#582 (puffer side) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…success Fixes agentenv/monorepo#578 (puffer side) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ing success Fixes agentenv/monorepo#588 (puffer side) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…k_read success Fixes agentenv/monorepo#591 (puffer side) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ilure diagnostics Fixes agentenv/monorepo#697, agentenv/monorepo#698 (puffer side) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The mark_read, delete, and send_email actions each hand-rolled the same post-condition loop (sleep -> poll -> auth-check -> predicate -> deadline). Extract a single `poll_gmail_list_until` helper plus `listing_rows` / `listing_contains_thread`, so each action expresses only its predicate and result payload. No behavior change to the verification contract. Also harden two review findings surfaced while consolidating: - gmail_list_emails asserted the live href contained the percent-encoded `#search/<query>` fragment, but Gmail re-normalizes the hash (decoding operators like `newer_than:1d`), which would false-fail the very operator queries #582 enables. Assert the `#search` route instead. - Generalize the shared `verification_failure` prefix from the hardcoded "Gmail/GCal action" to "Browser action" since it also serves GCal. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…gation The `?authuser=<email>` query form triggered an account-resolution redirect that dropped the URL hash fragment, so the `#sent` (send), `#trash` (delete), `#inbox/<thread>` (mark_read / reply), and `#search` (#582) views were never reached -- Gmail silently landed on the default `#inbox`. Switch `gmail_base_url` to the `/u/0/` path form, which preserves the fragment. Search additionally waits for the `#search` route to commit and for the result rows to settle before trusting them, so a transient stale-inbox scrape is never reported as search hits (upholds the plan-07 no-false-success contract). Full search result-timing on cold/warm tabs is tracked separately. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
agentenv/monorepo#769。Gmail/GCal 浏览器连接器的动作没有 post-condition 验证就上报成功,把"发起了动作"当成"动作完成"(虚报成功比失败更危险——上游 Monitor/agent 基于假成功继续推进)。
改动(执行→验证后置条件→上报 三段式)
browser_action_verify(诊断化失败信息 + thread-id 归一化)。#search路由、不再当字面关键词过滤(#582)。poll_gmail_list_untilhelper。gmail_base_url改/u/0/路径形式——?authuser=query 形式会在账户解析重定向中丢弃 URL hash 片段,导致#sent/#trash/#inbox/<thread>/#search视图从未到达。附回归测试。验证
已知 follow-up
🤖 Generated with Claude Code