Canonical source: docs/claude/growth-marketing-engine.md. This page is generated by docs/scripts/sync-handbook.mjs. Edit the source file in the repo; changes appear here on the next build.
Atlas Growth Marketing Engine — "Ready Practice, everywhere all the time"
2026-07-12. The dissemination arm of Atlas: an autonomous weekly engine that makes Ready Practice omnipresent — social, press, email, client Slack — self-driving toward +10% week-over-week growth on leading metrics, learning from impressions/clicks. Goal (George): everyone in the space — press, clinicians, VCs — knows RP and is impressed by our ship rate, growth, and presentation. Companion:
growth-content-backlog.md(what to announce),gtm-principles.md,growth-signals-playbook.md,atlas-operator-plan.md. Board epic: #39.
Vision & the number
Atlas owns a real KPI — +10% WoW on leading growth metrics (impressions, clicks, followers, email subs, site sessions) — and drives it autonomously: publish everywhere weekly, measure, double down on what works, escalate cadence/mix until the number is hit. Not a content scheduler — a growth operator with a target.
Decisions (George, 2026-07-12)
- Social publishing = Bundle.social API (existing $100/mo account). API-first aggregator → one integration posts to all platforms + returns analytics. No per-platform OAuth/approval.
- Platforms: LinkedIn + X/Twitter + Instagram + Threads/Bluesky (all, via Bundle.social).
- Autonomy = draft → George approves (one Slack click) → publish, ratcheting each channel to fully autonomous once it earns a clean track record (the #224 pattern applied to marketing — the safe way to let AI post publicly about a healthcare co to press/VCs).
The weekly loop
Mon tick (heartbeat: growth_marketing_tick, operator tenant only):
SENSE pull last week's metrics per channel (Bundle.social analytics + Klaviyo opens +
site analytics) → store snapshot → compute WoW vs +10% target
PLAN read growth-content backlog (unannounced ships) + last-week performance →
weight content mix toward what worked; if behind target, add cadence/channels
DRAFT generate the full bundle (per-platform social, email newsletter, press release,
Slack-to-clients) using the growth-content skill's voice rules (HIPAA-safe, no
medical claims, brand = Ready Practice / Atlas)
APPROVE post the bundle to George's Slack with Approve / Edit / Skip buttons
PUBLISH on approve → fan out: Bundle.social (social), Klaviyo/email (newsletter),
newsroom (press), Slack broadcast #166 (clients). Per-channel isolated failures.
MEASURE record what published + baseline → next week's SENSE closes the loop
REPORT weekly growth brief (into COO brief): what posted, WoW %, gap to +10%, next-week plan
Channels & adapters (pluggable — build core once, wire creds as they arrive)
| Channel | Adapter | Status | Needs |
|---|---|---|---|
| Social (LI/X/IG/Threads/BS) | Bundle.social API | build | BUNDLE_SOCIAL_API_KEY + connected accounts (George) |
| Email newsletter | api_klaviyo.py (exists) or functions_email.py | wire | confirm Klaviyo key + newsletter list |
| Press release | v1: publish to newsroom/blog + email press list; v2: wire PR service (EIN/PRWeb) | build | press-list source; newsroom page |
| Client Slack | Slack broadcast (#166) | depends on #166 | — |
Operating model: CAMPAIGNS, not announcements (George, 2026-07-12)
Core principle: shipping a feature ≠ the job is done. Every feature runs a multi-format campaign over time — a drumbeat — never a one-off blast. One announcement decays in 48h; sustained campaigns compound impressions, SEO/GEO citations, and buyer memory.
Per-feature campaign lifecycle (the drumbeat)
| Phase | Timing | Assets |
|---|---|---|
| Launch | T0 | Front Desk issue + LinkedIn/X; flagship → Product Hunt + press release |
| Educate | T0–2wk | deep-dive blog post (durable SEO/GEO asset — the compounding one) + how-to/demo video (#264) + tutorial |
| Prove | T2–8wk | customer case study + testimonial (once a clinic adopts it with a real result) |
| Reinforce | ongoing | rotating showcases — use-case angles, "did you know", vs-competitor, ICYMI/Rewind — re-surfaced on a cadence so it keeps working |
| Webinar | monthly | themed webinar bundling a feature cluster (live demo + Q&A → recording → gated asset) |
Always-on tracks (not tied to one launch)
- SEO/GEO blog engine — cornerstone + buyer-intent posts. Highest-leverage track for George's goal (AI/SEO recommending us) — durable indexed pages are what LLMs cite; social decays. Feeds #266 AI-visibility measurement.
- Monthly webinar engine — the Healthie model (Master Checklist "webinar engine").
- Case-study engine — ~bi-weekly, real customer wins, human-verified proof.
- Reminder/showcase rotation — systematized "Front Desk Rewind."
Blog / SEO "Educate" track — scoped (2026-07-12)
The Ready Practice site already has a real blog: 59 SEO .html posts in /blog/ of repo
Protosome-Inc/readypractice (branch basis-website-updates → Netlify, live at
readypractice.com/blog/<slug>). Each post is self-contained HTML with a proper SEO <head>
(title · meta description · keywords · canonical), Tailwind/serif styling, <article>+<h1>.
Index = blog.html; sitemap.xml lists URLs. Feature-oriented posts already exist
(ai-healthcare-operations, automating-patient-onboarding, ehr-vs-all-in-one-platform, etc.).
Blog-publish adapter (_publish_blog) = highest-leverage next build after the social/email MVP:
- Generate a feature deep-dive as SEO
.htmlmirroring the existing template (+ og/twitter + JSON-LD Article schema for GEO citation). - Add
blog/<slug>.html, link it inblog.html, add the URL tositemap.xml. - Commit via GitHub API to
Protosome-Inc/readypractice@basis-website-updates→ Netlify deploys. - Human-review gate (blog posts are durable brand/authority assets — higher stakes than a social post): engine drafts → George approves → commit. Feeds #266 AI-visibility measurement.
What this means for the engine (build implications)
- Track per-feature campaign STATE across formats, not just announced y/n. The
growth-content-backloggrows columns: blog(done/pending) · webinar(link) · caseStudy(link) · lastShowcasedAt · campaignPhase. The planner ensures each feature completes its lifecycle and re-surfaces under-exposed ones. - New publish adapters beyond social/email: blog/CMS (site blog — the durable SEO asset, next-highest priority after newsletter/social), webinar (schedule+registration), case-study (drafted from real inputs, human-approved). Video/screenshots via #264.
- The weekly planner schedules from ALL tracks (launch + educate + prove + reinforce + webinar), not just "this week's ship."
Content strategy — the Healthie teardown (2026-07-12)
Analyzed 3 pieces of Healthie's newsletter engine ("The Intake"). Their system: one branded masthead wrapping every issue, fixed reusable modules (Practice Pulse = data, Smart Read = blog, Built For You = trust/resource, On the Calendar = events, Case Study, "what shipped"), ~weekly cadence, quarterly "what shipped" roundup. ~2/3 outcome/education/ trust, ~1/3 product; they lead with CUSTOMER OUTCOME everywhere except the pure changelog. Proof discipline: named clinics + hard metrics + verbatim quotes on case studies.
Their weaknesses = our openings:
- "what shipped" is quarterly, text-only, zero proof, no visuals, soft CTA.
- No live velocity metric; no cross-channel repurposing.
Ready Practice doctrine (adopt + beat) — encode in the _draft_bundle prompt:
- Ship-rate IS the brand. Signature format = "This week we shipped" (we ship weekly; they batch quarterly). Number every ship + a running cumulative counter ("Feature #N this quarter"). Publish it on the marquee, not hidden in email. A public auto-updating changelog/ velocity page is a press/VC-facing flex (future).
- Lead with OUTCOME, not spec — match their winning move; pair it with our velocity edge.
- Always attach proof + a visual — every feature = screenshot/GIF (ties to #264 video) + one-line clinic benefit; every issue carries ≥1 metric or named-clinic quote.
- Repurpose once → publish everywhere same-day — one shipped feature fans to newsletter + changelog + LinkedIn carousel + X thread (the growth-content skill already does this; the engine automates it). Healthie shows no cross-channel repurposing — easy win.
- Own a masthead — Ready Practice newsletter needs one branded identity + fixed modules (Shipped / Clinic Spotlight / Pulse data / Trust / Events). Decision needed (George): the masthead name (Healthie's is "The Intake").
Weekly cadence to run: Mon "This week we shipped" (LinkedIn carousel + X thread + email module) → mid-week clinic case-study or Pulse-data post → monthly webinar + AI-trust explainer → continuous public ship counter. Maps 1:1 onto the growth-content skill + unannounced backlog.
Content brain (REUSE — do not rebuild)
growth-contentskill = the copy generator (LinkedIn/email/X/blog bundles, voice-enforced).growth-content-backlog.md= what shipped + announce status. The engine reads unannounced rows, drafts, and flips status to📢 posted (channel)on publish (closes the doc's loop).- Standing CLAUDE.md instruction already nudges George when ≥3 features are unannounced — the engine automates the "produce + post" half.
Metrics & the +10% optimizer
- Store:
growth_marketing_metrics/{isoWeek}— per channel {impressions, clicks, engagement, followers, emailOpens, siteSessions}, plus what was published. - WoW growth = this week's leading-metric total vs last week's; target +10%.
- Optimizer (weekly, in PLAN): if under target → increase cadence / add a platform / shift mix toward the best-performing format & topic from last week; if over → hold and compound. This IS the signal-architecture feedback loop (§5 of the signals playbook) on owned channels.
- Report the number + the lever pulled every week so the loop is legible + George-steerable.
Guardrails (public brand + healthcare = high stakes)
- Approval gate first (draft→approve); autonomy earned per channel via a ratchet (mirror #224 ledger: track approve-clean vs edited-before-send per channel/format).
- Claims linter on every public asset (no medical outcome claims — HIPAA/marketing); reuse the growth-content voice rules as a hard pre-publish check.
- Never expose PHI or a specific clinic's data. Never post a clinic's numbers publicly.
- Kill switch: gated on
autonomy_paused()like every other autonomous loop.
MVP vs full epic
- MVP (this build): the weekly loop + Bundle.social social posting + email newsletter + Slack-to-clients + press-to-newsroom + the +10% metrics loop + Slack approval. TEXT/image only.
- Full epic (deferred, own issues): launch VIDEOS (#264 Remotion), ElevenLabs voice-over, b-roll, AI creator/UGC funnel (#39 tail), PR-wire distribution, paid amplification.
Phased build
- P0 (core, no external keys):
functions_growth_marketing.py— metrics store, WoW optimizer, weekly tick, draft-bundle generator (reuse growth-content), Slack approval flow, weekly growth brief. Heartbeat taskgrowth_marketing_tick(operator tenant, weekly). - P1 (Bundle.social live): social adapter against the real API (pending research); George
adds
BUNDLE_SOCIAL_API_KEY+ connects accounts → first approved bundle posts to all platforms. - P2 (channels + loop closes): wire email newsletter (Klaviyo) + press newsroom + client Slack (#166); first full week measured; WoW number in the COO brief.
- P3 (ratchet + video): graduate clean channels to autonomous; fold in #264 video for launch clips.
Bundle.social API reference (verified 2026-07-12 — for the P1 adapter)
- Base
https://api.bundle.social, paths/api/v1. Auth headerx-api-key: pk_live_...(org-level). - Model: Organization → Team → Social Accounts. Almost every call needs
teamId. List connections:GET /api/v1/team/{id}→socialAccounts[](types: LINKEDIN, TWITTER, INSTAGRAM, THREADS, BLUESKY, FACEBOOK). Reference platforms by ENUM, not account id. - Publish:
POST /api/v1/post/—{teamId, title, postDate(ISO), status:"SCHEDULED", socialAccountTypes:[...], data:{PLATFORM:{text, uploadIds[]}}, referenceKey}. Near-nowpostDate+SCHEDULED= publish now (no PUBLISH_NOW enum). Per-platform text viadata{}. ResponseexternalData:{PLATFORM:{id,permalink}}. UsereferenceKeyfor idempotency. - Media:
POST /api/v1/upload/multipart (teamId+file) →{id}→ put in platformuploadIds[]. - Analytics: per-post
GET /api/v1/analytics/post?postId=&platformType=(impressions, views, likes, comments, shares, saves); per-accountGET /api/v1/analytics/social-account? teamId=&platformType=(impressions, followers, postCount…).force-refreshvariants exist. - Rate: 100 req/s; monthly org post caps by tier; per-account daily quotas.
- Webhooks:
post.publishedfires on success AND failure (checkdata.status=POSTED|ERROR).
Two design consequences (encoded in the optimizer):
- X/Twitter has NO analytics via Bundle.social (absent from the
platformTypeenum) — X POSTS fine but we can't read its metrics here. Verified 2026-07-12: this is an X PLATFORM paywall, not a Bundle quirk — X closed free organic analytics; legacy $200/$5k tiers shut to new signups Feb 2026, now pay-per-use (~$0.005/read); every aggregator (Ayrshare, Postiz…) requires BYO paid X app. Decision: don't switch aggregators. MVP = X is post-only; X impressions excluded from the WoW denominator. Future (only if X earns it): RP's own X Developer app → call X metrics endpoint directly (small native adapter, ~few $/mo at our volume, poll owned posts <30d). Not an aggregator swap. - No
clicksfield on social — social leading metrics = impressions + followers + engagement (likes+comments+shares+saves). CLICKS come from email (Klaviyo) + site analytics. So the +10% WoW metric set = social impressions/followers/engagement (ex-X) + email opens/clicks + site sessions. Follower growth = difffollowersacross weekly snapshots.
Open items for George (P1 blockers)
BUNDLE_SOCIAL_API_KEY(add as Firebase secret) + confirm which social accounts are connected in Bundle.social.- Confirm Klaviyo is the newsletter sender + which list; is there a press-contact list?
- Is there a newsroom/blog page on the Ready Practice site for press releases to land on?