Skip to content

fix(gmail-browser): search result integrity — settled-view primitive (#777) - #506

Merged
Milhouszhang merged 6 commits into
berabuddies:masterfrom
Milhouszhang:fix/777-gmail-search-result-integrity
Jul 9, 2026
Merged

fix(gmail-browser): search result integrity — settled-view primitive (#777)#506
Milhouszhang merged 6 commits into
berabuddies:masterfrom
Milhouszhang:fix/777-gmail-search-result-integrity

Conversation

@Milhouszhang

Copy link
Copy Markdown
Collaborator

Summary

Fixes Gmail-browser search returning pre-filter inbox rows masquerading as search results (plan issue #777). Gmail's SPA commits location.hash before it replaces the row grid, so a scrape run mid-transition could return the old #inbox rows under a new #search/... URL — a silent false success.

Root cause

  • List reads trusted "any visible rows = ready", unable to distinguish a stale inbox grid from real search results.
  • The ?authuser=<email> base URL triggered a full-page redirect that dropped the #search fragment, landing back on #inbox.
  • Zero-result searches ("No messages matched your search") were never detected as empty, so they hung in perpetual loading.

Fix

  • open_gmail_view_settled — one primitive all action-path list reads (search + post-condition) now go through: navigate → wait network-idle (best-effort) → assert the href route matches the URL's fragment route (href_on_route) → require the row signature to hold across two consecutive scrapes. Replaces three ad-hoc polling sites.
  • gmail_base_url fixed to the /u/0/ path form so the hash fragment survives navigation.
  • Zero-result detection extended to match "no messages matched", so an empty search resolves as ok/empty instead of loading.
  • Route-assertion helpers (expected_route_of, href_on_route) reject thread-detail URLs so post-conditions force the real list view.

Verification

  • 919 unit tests pass (cargo test -p puffer-cli), incl. route-assertion, pre-navigation-signature, and zero-result cases.
  • Live E2E against real Gmail (managed profile, milhouszhang@fuzz.land), three read-only scenarios:
    • list_inbox#inbox, 5 real rows (baseline).
    • search newer_than:1d#search/newer_than%3A1d, 6 rows; result set differs from inbox (includes newer mail absent from the inbox top-5, excludes an older Jul-7 notification) — proves real search results, not a stale grid.
    • search from:<nonexistent>#search/..., 0 rows + complete (not a loading hang) — proves the zero-result fix.
  • All CI gates green locally (scripts/ci-gates.sh).

Plan issue: agentenv/monorepo#777

Milhouszhang and others added 6 commits July 9, 2026 14:34
…ettled-view path

- Remove the stale pre-refactor doc block stacked on poll_gmail_list_until
  (it described the old re-navigate loop, contradicting the settled-view impl).
- Inline the identity wrapper should_wait_network_idle_after_previous_attempt
  (fn returning its argument) to a plain `if network_idle_reliable`, and move
  the misattached network-idle doc onto the real waiter wait_gmail_network_idle.

Behavior-preserving cleanup; 919 unit tests plus live search E2E pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Milhouszhang
Milhouszhang merged commit 95dd4dd into berabuddies:master Jul 9, 2026
9 of 10 checks passed
@Milhouszhang
Milhouszhang deleted the fix/777-gmail-search-result-integrity branch July 9, 2026 13:11
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.

1 participant