[codex] acknowledge terminal Gmail OAuth watch failures#930
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 19, 2026, 8:52 AM ET / 12:52 UTC. Summary Reproducibility: yes. for the source-level path: an OAuth refresh error carrying Review metrics: 2 noteworthy metrics.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review detailsBest possible solution: Adopt the durable-marker recovery contract only if maintainers want terminal OAuth failures to stop redelivery storms while preserving the last confirmed cursor, with Do we have a high-confidence way to reproduce the issue? Yes for the source-level path: an OAuth refresh error carrying Is this the best way to solve the issue? Unclear until maintainers choose the delivery policy. The implementation is a narrow and internally consistent way to prevent retry storms while retaining catch-up state, but acknowledging a terminal failure rather than retrying is an operator-experience decision rather than a purely mechanical bug fix. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 4747fb05a429. Label changesLabel justifications:
Evidence reviewedWhat I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (4 earlier review cycles)
|
Summary
watch startandwatch renewRoot cause
The Gmail watch consumers treated every non-rate-limit processing failure as retryable. When the OAuth refresh token returned
invalid_grant, push delivery responded with HTTP 500 and pull delivery nacked the message. Pub/Sub then redelivered a failure that cannot recover without operator re-authentication, producing an unbounded retry and log storm.Recovery contract
Terminal OAuth failures are acknowledged only after
authRecoveryPendingand the failure timestamp/reason are saved without advancinghistoryIdorlastPushMessageId. A state write failure remains a normal processing error, so Pub/Sub keeps the delivery retryable.After re-authenticating, run
gog gmail watch renewor rerungog gmail watch start. Successful registration preserves the old successful cursor while recovery is pending. Gmail sends an immediate notification for a successful watch registration, so the consumer catches up from that cursor without waiting for another mailbox change. Advancing history successfully clears the recovery marker.gog gmail watch statusexposes the pending recovery state.Temporary API failures, rate limits, and hook delivery failures retain their existing retry behavior.
Validation
go test ./internal/gmailwatchinternal/cmdtests covering start, renew, status, push acknowledgement, pull acknowledgement, persistence failure, and catch-upmake fmt-checkmake lintmake deadcodemake buildThe broader
internal/cmdGmail-watch test selection still has pre-existing shared-state failures when run as one package on this machine. The same failures reproduce on unmodifiedupstream/main; the focused regression tests above pass.Redacted live Gmail/Pub/Sub evidence
Run on 2026-07-19 with commit
7b32e33be8a5. The run used:--homeand encrypted file keyringwatch start, pull acknowledgement,watch renew, immediate Gmail notification, history fetch, and hook delivery pathsOnly the isolated refresh token was replaced with an invalid value. The production token was never revoked or modified.
The invalid-token pull logged
Gmail authorization requires re-authentication; acknowledging pull without advancing historyafter Google OAuth returnedinvalid_grant. After restoring the isolated token,watch renewretained the old cursor and pending marker. Gmail's immediate registration notification arrived through the temporary Pub/Sub subscription; the consumer fetched the retained history, delivered three message records to a local 204 hook, advanced the cursor, cleared the marker, and acknowledged the notification.Account addresses, project/topic/subscription names, history IDs, Pub/Sub message IDs, Gmail message IDs, label IDs, endpoints, and all credential material are omitted. Cleanup was verified: no temporary process, directory, subscription, label, or credential copy remains.
Related OpenClaw lifecycle fix: openclaw/openclaw#96202.