You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
a marker: id, labelIds, timestamps, url — bodies fetched separately
flattened with subject / from / to / date + decoded text/plain (see cloud/packages/core/tests/provider-write-planner-google-mail-parity.test.ts)
Consumers
none until AgentWorkforce/relayfile-cloud#136
the live system
google-mail-emails — this adapter's declared sync — exists nowhere outside this package's own source. The real integration was built separately in cloud with a richer sync set, and cloud's GOOGLE_MAIL_RESOURCES (packages/core/src/relayfile/provider-contracts.ts, mirrored in sync/record-writer.ts) is hand-maintained rather than imported from here — unlike github/linear/notion/slack/jira/confluence, which all import resources from their adapter package.
identity.ts already declares the intended end state: /gmail canonical, /google-mail a "read/digest compatibility identity while existing Cloud mounts are resynced", with resync: required and retireLegacyAfter: zero-references-and-explicit-cutover. That cutover has not been executed.
Why this can't be a one-line import today
Swapping cloud's hardcoded list for import { resources } from "@relayfile/gmail" regresses three ways at once:
Coverage — drops labels, filters, send-as, and watch-renewals (4 of cloud's 6 resources).
Paths — emits /gmail/* where cloud materializes /google-mail/*; every read misses and returns an empty tree.
Record shape — the thread marker is not the flattened record cloud's readers expect.
Steps
1. Port the missing resources into the adapter. Add labels, filters, send-as, messages (first-class, not just threads), and watch-renewals, matching google-mail-relay's sync outputs. The adapter adopts cloud's richer set — not the reverse.
2. Adopt the flattened record shape. Thread and message records carry subject/from/to/date and decoded text/plain, so a header-level search is a grep with no hydration. Pin it against the existing cloud parity test.
3. Unify the Nango integration. Reconcile google-mail + google-mail-emails against google-mail-relay's 6 syncs and 3 actions, and decide which config key survives.
4. Execute the root cutover. Resync /google-mail → /gmail per the GMAIL_IDENTITY.migration policy, then retire the legacy root once references hit zero. Riskiest step — it moves live mounts, and persona scopes naming /google-mail break the moment it lands.
5. Delete the duplicates.cloud's GOOGLE_MAIL_RESOURCES and relayfile-cloud's providers/google-mail.ts import from @relayfile/gmail, the way github.ts does.
Steps 1–2 are the substantial work. Step 4 is the one that needs a plan rather than a PR.
Related duplication worth killing in step 5
relayfile-cloud/packages/relayfile/src/writeback/providers/google-mail.ts carries its own
— a second copy of the reserved-prefix heuristic whose adapter-side twin was the Major finding in #257: a neutral filename like ask-storebrand.json matched neither the prefix list nor a real provider id, so it resolved as canonical and issued an update for a record that does not exist. Drafts now delegate to the adapter (relayfile-cloud#136), but that copy still governs filters and send-as there, so the same class of misclassification is live for those two resources.
AgentWorkforce/relayfile-cloud#136 — routes /google-mail/drafts/* through that adapter. First production code to consume this package for google-mail, and the bridgehead for step 5.
AgentWorkforce/cloud#2892 — adds /google-mail/drafts to the persona mount scope.
Found while benchmarking mail surfaces for a set of personal-assistant personas: the adapter looked far weaker on paper (threads-only markers) than what production actually materializes, because the two implementations had diverged.
Gmail has two parallel implementations. Neither is a copy of the other, and the one shipped in this repo is the thinner of the two.
relayfile-adapters/packages/gmailgoogle-mail, syncgoogle-mail-emailsgoogle-mail-relay— 6 syncs (labels, filters, messages, send-as, threads, renew-watch) + 3 actions (watch-mailbox, stop-watch, provision-pubsub-infrastructure), incloud/nango-integrations//gmail/google-mailid,labelIds, timestamps,url— bodies fetched separatelysubject/from/to/date+ decodedtext/plain(seecloud/packages/core/tests/provider-write-planner-google-mail-parity.test.ts)google-mail-emails— this adapter's declared sync — exists nowhere outside this package's own source. The real integration was built separately in cloud with a richer sync set, and cloud'sGOOGLE_MAIL_RESOURCES(packages/core/src/relayfile/provider-contracts.ts, mirrored insync/record-writer.ts) is hand-maintained rather than imported from here — unlike github/linear/notion/slack/jira/confluence, which all importresourcesfrom their adapter package.identity.tsalready declares the intended end state:/gmailcanonical,/google-maila "read/digest compatibility identity while existing Cloud mounts are resynced", withresync: requiredandretireLegacyAfter: zero-references-and-explicit-cutover. That cutover has not been executed.Why this can't be a one-line import today
Swapping cloud's hardcoded list for
import { resources } from "@relayfile/gmail"regresses three ways at once:/gmail/*where cloud materializes/google-mail/*; every read misses and returns an empty tree.Steps
labels,filters,send-as,messages(first-class, not just threads), andwatch-renewals, matchinggoogle-mail-relay's sync outputs. The adapter adopts cloud's richer set — not the reverse.subject/from/to/dateand decodedtext/plain, so a header-level search is a grep with no hydration. Pin it against the existing cloud parity test.google-mail+google-mail-emailsagainstgoogle-mail-relay's 6 syncs and 3 actions, and decide which config key survives./google-mail→/gmailper theGMAIL_IDENTITY.migrationpolicy, then retire the legacy root once references hit zero. Riskiest step — it moves live mounts, and persona scopes naming/google-mailbreak the moment it lands.cloud'sGOOGLE_MAIL_RESOURCESandrelayfile-cloud'sproviders/google-mail.tsimport from@relayfile/gmail, the waygithub.tsdoes.Steps 1–2 are the substantial work. Step 4 is the one that needs a plan rather than a PR.
Related duplication worth killing in step 5
relayfile-cloud/packages/relayfile/src/writeback/providers/google-mail.tscarries its own— a second copy of the reserved-prefix heuristic whose adapter-side twin was the Major finding in #257: a neutral filename like
ask-storebrand.jsonmatched neither the prefix list nor a real provider id, so it resolved as canonical and issued an update for a record that does not exist. Drafts now delegate to the adapter (relayfile-cloud#136), but that copy still governsfiltersandsend-asthere, so the same class of misclassification is live for those two resources.Context
@relayfile/gmail@0.3.3./google-mail/drafts/*through that adapter. First production code to consume this package for google-mail, and the bridgehead for step 5./google-mail/draftsto the persona mount scope.Found while benchmarking mail surfaces for a set of personal-assistant personas: the adapter looked far weaker on paper (threads-only markers) than what production actually materializes, because the two implementations had diverged.