AaaS — Email Nurture Plan
← Deliveries
Strategic Architecture

Email Nurture
System Plan

Full architecture for producing, routing, and delivering intelligent email digests across all 15 AaaS surfaces. Covers model selection per digest type, Vertex AI integration, the military execution roadmap, and every email product from daily AI picks to monthly ecosystem updates.

Surfaces: 15
Email Products: 12
Account Types: 12
Interest Topics: 27
Phases: 5
Tier: Free
Authored: 2026-04-09
Digest Types
12
Live Surfaces
7
Cloud Functions
6
Nurture Tracks
5
Weekly Roundup
1
Monthly Update
1
How are emails produced, and with what model?
Three questions answered before the execution plan.
Q1 — How are emails produced?

Emails are not static templates. Each digest is dynamically generated by a Cloud Function that: (1) queries Firestore for new content since last send, (2) fetches structured data from each surface's backend, (3) calls a Claude model on Vertex AI to write the narrative, and (4) renders a React Email template with the AI output. The result is sent via Resend in batch.

Different email types use different generation strategies. The Today daily digest is almost mechanical — GravityClaw already scored and ranked the 5-7 items, the function just formats them. The Weekly Roundup needs Claude to write a cohesive narrative from 6 sources. The nurture sequence needs Claude to personalise tone based on account type and onboarding state.

Q2 — Can we use the Claude Code subscription?
No. Not possible

Claude Code is a coding assistant (this CLI tool). It is not an API endpoint you can call from server code. It has no programmatic interface for backend services. What you want is the Claude API — which is available two ways:

Option A — Anthropic API directly: Separate API key, billed directly to Anthropic. Works fine, but requires managing a separate credential outside your GCP account.

Option B — Claude on Vertex AI: Claude models (Haiku, Sonnet, Opus) available in Google Cloud's Model Garden via the Anthropic ↔ Google partnership. Same GCP billing account, same IAM, same service accounts as Firebase and Cloud Functions. This is the recommended path.

Q3 — Is Vertex AI the correct platform?
Yes. Confirmed

All existing infrastructure runs on GCP: Firebase, Cloud Functions, Cloud Scheduler, Firestore, Cloud Run, GravityClaw (already uses Vertex AI Gemini). Adding Claude on Vertex AI means zero new billing relationships, zero new secrets to rotate, and sub-50ms latency from Cloud Functions to the model. The GravityClaw scanner already uses @google-cloud/vertexai — the same SDK adds Claude access with one additional model identifier.

Additionally, Gemini continues to run scoring/ranking (it excels at structured classification). Claude handles narrative writing (it excels at coherent prose). Both run on the same Vertex AI endpoint.

Right model for every email type
Running Opus on every email would be wasteful and slow. Model selection follows the 60/30/10 principle: deterministic formatting uses no LLM; summaries use Haiku; narrative writing uses Sonnet; strategic content uses Opus (rare).
Email Product Frequency AI Task Model Rationale
Today — Daily AI Picks Daily Format pre-scored items into email HTML Gemini Flash GravityClaw already ranks items. Just templating — no prose generation needed.
Academy — Daily Pack Nudge Daily 1-line personalised nudge + streak status Claude Haiku Short output, high volume, low stakes. Haiku is 3× cheaper than Sonnet.
Blog — Weekly Channel Digest Weekly Summarise top 10 new entities per subscribed channel Claude Haiku Structured summaries of existing content. No original thinking needed.
Platform — Weekly Usage Digest Weekly Write task accomplishment narrative from structured metrics Claude Sonnet Needs coherent "what your agents did this week" narrative — not just data dump.
Quest — Daily Job Alerts Daily Match jobs to user profile, write 1-line relevance note per role Claude Haiku Mechanical matching with short output. Fast, cheap, high volume.
Academy — Weekly Challenge Digest Weekly Write challenge summary + leaderboard narrative Claude Haiku Structured challenge data → short formatted summary.
Forum — Weekly Digest Weekly Summarise top threads, best prompts, tool reviews Claude Sonnet Community content summarisation needs nuance and tone.
Weekly Roundup (cross-surface) Weekly Write cohesive narrative linking content from 6 surfaces Claude Sonnet Multi-source synthesis with consistent voice. Core flagship email — invest here.
Boutique — Monthly Case Study Monthly Narrativise implementation case from structured brief Claude Sonnet Story-driven content, low volume — Sonnet quality warranted.
Monthly Ecosystem Update Monthly Write strategic product narrative + roadmap teaser Claude Sonnet Brand voice, low volume, high visibility. Sonnet delivers with review.
Lifecycle Nurture — Welcome Triggered Personalised welcome by account type + interests Claude Sonnet First impression. Personalisation matters. One-time per user.
Lifecycle Nurture — Day 7–30 Triggered Contextual nudges based on behaviour gaps Claude Haiku Short, targeted messages. Pattern-driven not creative. Haiku sufficient.
Haiku 4.5
Cheapest

Use for: high-volume mechanical tasks, short outputs, structured formatting, daily sends with 1,000+ recipients. ~3× cheaper than Sonnet, ~15× cheaper than Opus.

Sonnet 4.6
Default

Use for: narrative writing, multi-source synthesis, personalisation, brand voice, weekly and monthly digests. Best quality-to-cost ratio for prose generation.

Opus 4.6
Strategic Only

Not used for bulk email. Reserved for one-time tasks: designing new email templates, reviewing nurture strategy, generating onboarding copy. Never in scheduled functions.

One GCP account. Two model families.
Gemini handles ranking, classification, and structured extraction. Claude handles prose, personalisation, and narrative synthesis. Both accessed via the same Vertex AI SDK already in use by GravityClaw.
Already Running — Gemini on Vertex AI
Active

GravityClaw uses @google-cloud/vertexai with Gemini Flash for: scoring news items by novelty × impact × clarity, classifying AI entities into the 16 blog types, ranking content for the Today digest.

Keep Gemini for: classification, scoring, structured JSON extraction, ranking, high-volume low-latency tasks.

Add — Claude on Vertex AI
New

Via Anthropic ↔ Google partnership, Claude Haiku, Sonnet, and Opus are available in Vertex AI Model Garden. Same SDK, same IAM service account, same GCP billing.

Use Claude for: prose generation, narrative synthesis, personalisation, email copy, nuanced summarisation, brand-consistent writing.

Implementation in Cloud Functions
// functions/src/lib/ai-client.ts import { VertexAI } from "@google-cloud/vertexai"; const vertex = new VertexAI({ project: process.env.FIREBASE_PROJECT_ID, location: "us-central1", }); // Gemini — for scoring/classification (already in use) export const geminiFlash = vertex.getGenerativeModel({ model: "gemini-2.0-flash", }); // Claude — for prose/narrative (new, same SDK pattern) export const claudeHaiku = vertex.getGenerativeModel({ model: "claude-haiku-4-5@20251001", }); export const claudeSonnet = vertex.getGenerativeModel({ model: "claude-sonnet-4-6@20250514", });
Why NOT Anthropic API directly?
Decision Rationale

Running Anthropic API separately would mean: a separate API key in Secret Manager, separate billing account, separate rate limit management, and higher latency from us-central1 to api.anthropic.com. Vertex AI keeps everything in the same GCP project with unified observability, IAM, and billing — which is already set up.

12 identity types, multi-type support
Expanded from the current flat 5-type system. Users can hold multiple types simultaneously. Primary type drives personalisation; additional types unlock surface access.
founder — building a startup, AI workforce buyer
builder — developer building AI products
creator — content creator using AI for production
business — SMB/corporate AI automation buyer
consultant — implements AI for clients
enterprise — large org, procurement cycle
investor — VC, angel, AI deal flow
accelerator — program operator, cohort-based
learner — upskilling, early career
researcher — academic, analyst, knowledge-first
Primary surface per account type (★★★ = core)
TypePlatformAcademyBlogDIYToolboxBoutiqueBusinessQuest
founder★★★★★★★★★★★★★★★★★
builder★★★★★★★★★★★★★
creator★★★★★★★★★★★
business★★★★★★★★★★★
consultant★★★★★★★★★★★★★
investor★★★★★★★
learner★★★★★★★★★★★★
researcher★★★★★★★★
27 topic categories across 3 domains
Users select interests during activation Step 3. Persona bundles pre-select sensible defaults. Interests directly map to which sections appear in the Weekly Roundup and which channels are included in the Blog digest.
🤖 ai_models — LLM releases, benchmarks
🔧 ai_tools — New tools, APIs, SDKs
🕹️ ai_agents — Agent frameworks
⚙️ ai_automation — Scripts, workflows
💬 prompt_engineering — Context design
🏗️ ai_infrastructure — MLOps, hardware
🛡️ ai_safety — Ethics, governance
📄 ai_research — Papers, datasets
👁️ computer_vision — Vision models
🎙️ speech_audio — TTS, STT, audio
💻 ai_code — Coding assistants
📊 ai_business — Strategy, ROI
📰 daily_ai_picks — aaas.today digest
🎓 academy_packs — Action packs
📋 toolbox_templates — Business templates
📦 knowledge_packages — DIY packages
vault_skills — New vault skills
🚀 platform_updates — Feature releases
🏗️ builders_updates — Skill slams
🌐 community_forum — Forum digest
📅 weekly_roundup — Cross-surface weekly
💼 job_alerts — Quest job board
📈 career_development — CV tips
📸 ai_photography — Pics tips
🚀 startup_resources — Cloud credits
🤝 consulting_cases — Boutique stories
💰 investor_intel — Deal flow
Founder ai_agents, ai_business, toolbox_templates, startup_resources
Builder ai_tools, ai_code, ai_infrastructure, vault_skills, daily_ai_picks
Business ai_business, toolbox_templates, consulting_cases, weekly_roundup
Researcher ai_research, ai_models, ai_safety, computer_vision
Learner academy_packs, prompt_engineering, community_forum, job_alerts
What every surface provides when fully live
SurfaceURLFree Digest OfferFrequencyStatusModel
Todayaaas.today5-7 curated AI picks, GravityClaw-scored Daily Infra built Gemini Flash
Blogaaas.blogTop 10 new entities per subscribed channel Weekly Live Claude Haiku
Academyaaas.academyDaily pack nudge + weekly challenge Daily + Weekly Live Claude Haiku
Platformagents-as-a-service.comAgent task accomplishments + credits used Weekly Live Claude Sonnet
Toolboxaaas.blog/toolboxNew templates + featured pick Monthly Live Claude Haiku
Questaaas.questAI-adjacent job alerts matching profile Daily or Weekly Coming Q2 Claude Haiku
Forumaaas.forumTop threads, best prompts, tool reviews Weekly Q3 2026 Claude Sonnet
Boutiqueaaas.boutiqueOne implementation case study Monthly Coming Q2 Claude Sonnet
Buildersaaas.buildersNew skill slams + project showcases Weekly Coming Q2 Claude Haiku
Businessaaas.businessInvestor intel + startup funding news Weekly Coming Q2 Claude Haiku
Weekly RoundupAll surfacesBest of everything above in one email Sunday Build First Claude Sonnet
Monthly UpdateAll surfacesEcosystem news, new surfaces, roadmap 1st of month Build First Claude Sonnet
Three layers, one coherent system
The system is layered so users can receive exactly as much as they want — from one weekly email covering everything to individual per-surface digests at their preferred frequency.
Layer 1 — Surface Digests
Each surface sends its own email on its own schedule. Users opt into individual surfaces. Maximum granularity, maximum noise if over-subscribed.
Layer 2 — Weekly Roundup
One Sunday email aggregating the best item from each subscribed surface. The "newspaper" option — recommended for most users. Suppresses Layer 1 for that week if preferred.
Layer 3 — Monthly Ecosystem
Broadcast to all opted-in users on the 1st. New surfaces, major features, top stats, one case study, roadmap teaser. Brand health email — low frequency, high quality.
Nurture Lifecycle Sequences (5 account-type tracks)
DayFounderBuilderBusinessResearcherLearner
D+0Context generatingDev context readyBusiness context readyResearch context readyLearning path starts
D+1First agent task CTADIY intro — GitHub reposSelect email task CTABlog intro — 2,847 entitiesDay 1 Academy pack
D+3Vault highlight — founder skillsVault — top 5 technicalToolbox — top 10 ops templatesChannel setup — personalised feedStreak nudge (Day 3!)
D+7Toolbox — 10 founder templatesContext Engineering crash courseCase study — [company] automated [process]Paper highlight — top 3 this weekWeekly challenge announce
D+14Case study — 3 hires replacedBuilders — first skill slamBoutique CTA — full workforceDIY — research papers to study packsQuest — AI jobs now hiring
D+21Platform new featuresForum waitlistWeekly digest sampleBenchmark updateProgress — X packs in 3 weeks
D+30Strategy call CTASkill review — what are you building?Upgrade to boutique pathAPI intro — build your pipelineForum waitlist — Q3 launch
What each digest looks like
Today — Daily AI Picks
Weekly Roundup — Cross-Surface
OPORDER: Email Nurture System
Five phases. Each phase has a clear objective, specific tasks, and measurable exit criteria. No phase begins before the previous phase's exit criteria are met.
P1
Foundation — Identity & Data Model
Week 1–2 · Prerequisite for everything
Critical Path No External Deps
  • Extend AccountType union (12 types) in auth-core/types.ts
    Replace founder|business|partner|investor|user with the 12-type taxonomy. Add AccountTypeProfile interface for multi-type support. Update all existing guards.
    auth-core/types.ts~2h
  • Add InterestTopic union (27 categories) and DigestPreferences interface
    Add all interest categories, DigestFrequency type, SurfaceDigestPreference, and full DigestPreferences interface to auth-core/types.ts.
    auth-core/types.ts~2h
  • Create EmailSubscription and SurfaceSubscription interfaces
    New Firestore collection interfaces for email_subscriptions and users/{id}/surface_subscriptions subcollection. Add to auth-core/types.ts.
    auth-core/types.ts~1h
  • Clerk publicMetadata write server action
    Create apps/platform/src/app/actions/account.ts with setAccountType(), setInterests(), setDigestPreferences(). Uses clerkClient().users.updateUserMetadata() on server only.
    apps/platform/src/app/actions/account.ts~3h
  • Firestore: create email_subscriptions collection with composite indexes
    Add to firestore.indexes.json: (subscriptionType + status + lastSentAt), (userId + status). Create collection group index for surface_subscriptions subcollection.
    firestore.indexes.json~1h
  • Update activate-client.tsx: add account type + interest selection steps
    Insert Step 1 (account type selection) and Step 3 (surface interest picker with persona bundles) into the existing 5-step onboarding flow. Step 3 shows grouped surfaces with frequency selector.
    apps/platform/src/app/activate/activate-client.tsx~5h
Exit Criteria — Phase 1
New user completes onboarding → accountType written to Clerk publicMetadata → interests written to Firestore → at least one email_subscriptions document created → all TypeScript types compile.
P2
First Emails — Core Digests Live
Week 3–4 · First user value delivery
High Impact Requires Vertex AI Setup
  • Add Claude on Vertex AI to functions/src/lib/ai-client.ts
    Extend existing Vertex AI client to add claudeHaiku and claudeSonnet model handles. Enable Claude API access in GCP project via Model Garden. No new secrets — uses existing service account.
    functions/src/lib/ai-client.ts~2h
  • Build Today daily digest Cloud Function
    Scheduled: 06:30 UTC daily. Queries email_subscriptions for type=today_daily, status=active. Fetches top 5-7 GravityClaw-scored items from Firestore. Renders React Email template. Sends via Resend batch. Updates lastSentAt.
    functions/src/email/today-digest.ts~6h
  • Build Blog weekly channel digest Cloud Function
    Scheduled: Monday 06:00 UTC. Per subscriber: fetches new entities since lastSentAt filtered by their subscribed channels. Claude Haiku summarises each entity in 1-2 sentences. Renders template. Sends via Resend.
    functions/src/email/blog-weekly-digest.ts~8h
  • Build Weekly Roundup Cloud Function
    Scheduled: Sunday 07:00 UTC. For each subscriber: fetches best item from each of their subscribed surfaces. Claude Sonnet writes a cohesive 200-word intro narrative. Renders cross-surface template. This is the flagship email — invest in template quality.
    functions/src/email/weekly-roundup.ts~10h
  • React Email templates (4 templates)
    Build: today-daily.tsx, blog-weekly.tsx, weekly-roundup.tsx, monthly-ecosystem.tsx using React Email. Match AaaS dark brand. Per-subscription unsubscribe link in every footer using subscription-level token.
    emails/templates/~8h
  • Connect Resend: configure from addresses per surface
    Set up: picks@aaas.today, digest@aaas.blog, roundup@aaas.select. Verify DNS for all 3 sending domains in Resend. Store API key in Google Cloud Secret Manager.
    Secret Manager + Resend Dashboard~2hNeeds DNS
Exit Criteria — Phase 2
Today digest fires at 06:30 UTC and 10+ test subscribers receive it. Blog digest fires Monday and renders channel-filtered content. Weekly Roundup fires Sunday with Claude Sonnet narrative. All sent via Resend, all recorded in email_digest_runs.
P3
Nurture Sequences — Lifecycle Automation
Week 5–6 · Activation and retention
Depends on Phase 1
  • Account type-aware welcome email (replaces flat welcome)
    On user creation trigger: read accountType from Firestore, select nurture track, send Claude Sonnet-generated welcome tailored to that type. Template: emails/templates/nurture/welcome.tsx with conditional sections per account type.
    functions/src/email/nurture/welcome.ts~6h
  • Cloud Scheduler: nurture sequence dispatcher
    Daily function that queries users where (now - createdAt) matches a nurture day (D+1, D+3, D+7, D+14, D+21, D+30) AND no email sent for that day yet. Selects correct template by account type. Sends via Resend. Marks nurtureDay as sent in user document.
    functions/src/email/nurture/dispatcher.ts~10h
  • Academy daily nudge + weekly challenge Cloud Functions
    Daily 07:00 UTC: send pack nudge to academy subscribers who haven't opened today's pack yet (Firestore read). Weekly Monday: send challenge announcement. Claude Haiku generates the 1-line personalised nudge.
    functions/src/email/academy-daily.ts~5h
  • Platform weekly usage digest Cloud Function
    Sunday 07:30 UTC: for active platform users, fetch task completions + credit usage for the week. Claude Sonnet writes 3-sentence "what your agents did" narrative. Send via Resend from platform@agents-as-a-service.com.
    functions/src/email/platform-weekly.ts~5h
Exit Criteria — Phase 3
New founder signup triggers founder welcome email within 5 minutes. D+1, D+3, D+7 emails fire on schedule for test users. Academy nudge fires daily without duplicates. Platform usage digest fires Sunday.
P4
Self-Service — User Controls
Week 7–8 · Preference management & unsubscribe
User-Facing Depends on Phase 1+2
  • Overhaul /email-preferences page
    Replace 7 boolean toggles with full DigestPreferences UI: per-surface frequency selector (off/daily/weekly/monthly), Weekly Roundup toggle, Monthly Update toggle, timezone selector, preferred send time picker.
    apps/platform/src/app/email-preferences/page.tsx~8h
  • Account type self-service at /preferences
    Add "I am a..." multi-select and interest picker (grouped by domain) to /preferences or /dashboard/settings. Changes call setAccountType() and setInterests() server actions, sync to Clerk unsafeMetadata + Firestore.
    apps/platform/src/app/preferences/page.tsx~6h
  • Per-subscription unsubscribe tokens and handler
    Each email_subscriptions document gets its own unsubscribeToken. Footer links: "Unsubscribe from [this digest]" uses subscription-level token. Handler at /api/unsubscribe/[token] sets that subscription to status=unsubscribed without touching others.
    apps/platform/src/app/api/unsubscribe/[token]/route.ts~4h
  • Monthly Ecosystem Update Cloud Function
    1st of month 08:00 UTC: compile stats from all surfaces (entities indexed, packs completed, templates used, tasks run), pull latest surface launch news, Claude Sonnet writes the narrative. Sends to all globalOptIn users.
    functions/src/email/monthly-ecosystem.ts~6h
Exit Criteria — Phase 4
User can change account type from preferences UI. Email preferences shows per-surface controls. Unsubscribe from one digest does not cancel others. Monthly update fires 1st of month.
P5
Observability — Analytics & Optimisation
Week 9–10 · Know what's working
Depends on P1–P4
  • Resend webhook → Firestore: open/click tracking
    Webhook endpoint at /api/webhooks/resend receives email.opened and email.clicked events. Writes to email_subscriptions (lastOpenedAt, openCount) and email_digest_runs (openRate, clickRate). Used to suppress inactive subscribers after 60 days.
    apps/platform/src/app/api/webhooks/resend/route.ts~4h
  • Email analytics panel in aaas-design.web.app
    Add /email-analytics route to design deliveries app. Shows: open rates per digest type, unsubscribe rates, top-performing content, subscriber growth per surface, account type distribution.
    apps/design-deliveries/email-analytics.html~6h
  • Inactive subscriber suppression
    Monthly Cloud Function: query subscriptions where (lastOpenedAt is null OR lastOpenedAt < 60 days ago). Set status=paused. Send one reactivation email before pausing. Prevents Resend sending score degradation.
    functions/src/email/suppress-inactive.ts~3h
Exit Criteria — Phase 5
Open rate visible per digest type in analytics panel. Inactive subscribers paused automatically. Resend sending reputation protected. System runs autonomously with zero manual intervention required.
Clerk metadata + Firestore extensions
Clerk publicMetadata (JWT, client-readable)
interface ClerkPublicMetadata { accountType: AccountType; // primary accountTypes: AccountType[]; // multi-type ecosystemTier: "free"|"pro"|"enterprise"; isFounder: boolean; // quick gate isTeam: boolean; onboardingComplete: boolean; onboardingStep: number; // 0–6 activeSurfaces: SurfaceId[]; }
Clerk unsafeMetadata (user-writable)
interface ClerkUnsafeMetadata { persona: BlogPersona; interests: InterestTopic[]; timezone: string; // IANA digestPreferences: { weeklyRoundup: boolean; monthlyUpdate: boolean; preferredSendTime: "morning"| "midday"| "evening"; surfaces: Record<SurfaceId, DigestFrequency>; }; }
Firestore: email_subscriptions/{subscriptionId}
interface EmailSubscription { userId: string; email: string; subscriptionType: "today_daily" | "blog_weekly" | "academy_daily" | "academy_weekly" | "platform_weekly" | "quest_daily_jobs" | "forum_weekly" | "boutique_monthly" | "weekly_roundup" | "monthly_ecosystem"; frequency: DigestFrequency; // "off"|"daily"|"weekly"|"monthly" status: "active" | "paused" | "unsubscribed"; topicFilters: InterestTopic[]; // [] = all createdAt: Timestamp; lastSentAt: Timestamp | null; lastOpenedAt: Timestamp | null; openCount: number; unsubscribeToken: string; // per-subscription, 32-char random }
What good looks like
Open Rate Target
40%
Industry avg is 22%. Niche AI audience should beat this.
Unsub Rate Max
<1%
Per-digest unsubscribe keeps global rate low.
Subscriber Growth
10%
Month-over-month across all digest types combined.
Nurture Activation
30%
Users who send first task within 7 days of sign-up.
Daily Operational Cadence (when all phases live)
06:30 UTC Daily
Today Digest fires
GravityClaw items formatted, sent via Resend to today_daily subscribers.
07:00 UTC Daily
Academy Nudge fires
Claude Haiku generates 1-line nudge for users who haven't opened today's pack.
07:30 UTC Daily
Nurture Dispatcher fires
Sends D+1/3/7/14/21/30 emails to users hitting those day milestones.
06:00 UTC Monday
Blog Weekly Digest fires
New entities since last Monday, filtered by subscribed channels, summarised by Claude Haiku.
07:00 UTC Sunday
Weekly Roundup fires
Claude Sonnet synthesises content from all subscribed surfaces into one cohesive email.
07:30 UTC Sunday
Platform Weekly Digest fires
Claude Sonnet writes "what your agents did this week" for active platform users.
08:00 UTC 1st of month
Monthly Ecosystem Update fires
Claude Sonnet writes ecosystem narrative to all opted-in users. New surfaces, features, roadmap.