fix: retry Google's transient domain-wide-delegation propagation-delay error
Release to Docker Hub / Build & Push Docker Image (push) Canceled after 0s
Release to Docker Hub / Create GitHub Release (push) Canceled after 0s

Live Google Workspace delivery validation surfaced a real, self-resolving
Google-side condition: freshly-authorized domain-wide delegation can take
up to about a minute to propagate across Google's auth infrastructure,
producing intermittent unauthorized_client on the OAuth token exchange
even with correct configuration. gws-provider.js now classifies
unauthorized_client as a temporary (retryable) error instead of permanent,
so the existing bounded-backoff worker absorbs it automatically.

Also documents the alias-vs-delegated-user env passthrough in
docker-compose.dev.yml, and records both real findings (this one and the
GOOGLE_DELEGATED_USER alias distinction) plus the full live-delivery
validation outcome in the runbook and Phase 5C doc.

Validated live: isolated gws-email-test.js send (DKIM/SPF passing,
delivered) and a full real lifecycle test (create student, enrollment,
real activation email, activate, login, see program, real password-reset
email, reset, login with new password) via [email protected].
This commit is contained in:
2026-08-25 21:36:12 -05:00
parent 7baf7074e5
commit 4c0a950afb
4 changed files with 43 additions and 8 deletions
+26 -6
View File
@@ -1,7 +1,9 @@
# Phase 5C — Enrollment Operations & Communications
**Status: PHASE 5C COMPLETE. ENROLLMENT COMMUNICATIONS COMPLETE. STUDENT ACTIVATION PIPELINE READY.**
**LIVE GOOGLE WORKSPACE DELIVERY VALIDATION PENDING** — see §14.
**LIVE GOOGLE WORKSPACE DELIVERY VALIDATED** — real activation and password-reset emails
delivered end to end via `[email protected]` (a Workspace alias), DKIM/SPF passing,
inbox delivery confirmed. See §14.
Phase 5B built the enrollment/entitlement model and the website integration boundary. What was
still missing for a real student: nobody ever told them. This phase closes that gap — real
@@ -221,8 +223,26 @@ is exhausted, then `failed` too. Never an infinite loop; every attempt is persis
then this phase's migration applied — every prior record intact; a new notification correctly
links to the pre-existing student/enrollment; re-running the migration set is a no-op.
**Live Google Workspace delivery has not been validated** — no service account/domain-wide
delegation exists yet for this RootNode Workspace domain. The adapter (`gws-provider.js`) is
fully implemented and unit-testable at the code level; `infra/scripts/gws-email-test.js` is
ready to run the moment credentials exist (opt-in, `RUN_GWS_EMAIL_TEST=true`, sends exactly one
message to one operator-configured test address — see the runbook).
**Live Google Workspace delivery has been validated for real**, both in isolation
(`infra/scripts/gws-email-test.js`, one message, DKIM/SPF passing, delivered) and through the
full genuine flow: a real student created, enrolled, receiving a real activation email, setting
their password from the real link, logging in, seeing their enrolled program, requesting and
receiving a real password-reset email, and completing the reset — every step against the live
Platform API, `EMAIL_PROVIDER=gws`, nothing simulated.
**One real Google Workspace limitation found and handled:** newly-authorized domain-wide
delegation does not take effect instantly across all of Google's auth infrastructure — the
identical token request succeeded, then failed with `unauthorized_client`, then succeeded again,
over the span of about a minute, before settling. This is Google-side propagation delay, not a
configuration error, and it self-resolved. `gws-provider.js` now classifies `unauthorized_client`
as a *temporary* failure (retried with the existing bounded backoff) rather than permanent —
this is exactly the failure mode that backoff exists for, and it means a real deployment doesn't
need a human to notice and manually retry during that propagation window. See
`docs/RUNBOOK_GOOGLE_WORKSPACE_EMAIL.md`'s troubleshooting section.
**A second real-world detail found during setup, not a bug:** the sending address
(`[email protected]`) is a Workspace *alias* of an existing account rather than its
own paid seat — a deliberate cost-saving choice. Domain-wide delegation authorizes a real
account, not an arbitrary alias string, so `GOOGLE_DELEGATED_USER` (the alias's real owner) was
added as a setting distinct from `EMAIL_FROM_ADDRESS` (the visible sending address) — see §2 and
the runbook §5.