mirror of
https://github.com/karatektus/pl_mail.git
synced 2026-10-25 01:54:10 +00:00
A Gmail account that stops every few days is almost always one thing: Google expires refresh tokens issued by an OAuth app whose consent screen is still in "Testing" publishing status, after about a week. That is the state nearly every self-hosted install is in, because leaving it there is the documented way to avoid Google's verification review for scopes of Gmail's reach. So the account works, stops seven days later, gets reconnected, and stops again. Forever. Google gives no clue which case you are in. What arrives is `invalid_grant` — the same code it returns for a revoked consent, a changed password, and a token that aged out. Four causes, one error, and only one of them is fixed by changing a setting rather than by signing in again every week. THE ONLY THING THAT SEPARATES THEM IS THE INTERVAL, and nothing was recording it. Two columns now do: when the current grant was issued, and how many hours the previous one survived. The second is kept ACROSS the reconnect on purpose — it is the only evidence that survives one, and the moment somebody has just fixed it is the one moment they are looking at the account and could act on the cause. Two cards come out of it. A sign-in that died after about a week gets one naming that cause and the real fix instead of the generic "sign in again" for the fifth time. And once the pattern has been seen once, a warning appears a day or two BEFORE the next one runs out, while nothing is broken yet. The inference needs both halves and says so. Without the history it would nag every healthy Google account weekly; without the age it would fire the moment somebody reconnected, and a warning visible five days out of seven is furniture. The window is 4 to 9½ days: wide enough for a death noticed a day late on the next sync, narrow enough to exclude a grant that ran for three months and was then revoked — which is the claim that must never be made, and is pinned in WeeklyGrantExpiryTest in both directions. An account connected before this was recorded is told nothing at all. Verified on a running stack in all three states: the warning on a live six-day grant with a weekly history, the diagnostic card on a dead one, and the plain card with no mention of Testing on a grant that lasted ninety days. The last found a real bug — the check was wired into inspectAccount(), which the settings page never calls, so the card rendered nowhere. It also must not register as a CAUSE, or every calendar on the account would grey out and blame a card whose first sentence says mail is still arriving. The handbook said "publishing and going through verification is what removes that", which conflates two separate settings and is what makes people accept the weekly reconnect as the price of not being verified. Publishing status and verification status are different fields; an app published without verification works, with a warning screen the first time. Corrected in English and German, with a new section in features/health.md describing both cards. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>