1. Problems & risks first
Blunt list. Red items block autonomy; amber items are unverified assumptions the design depends on.
- Compliance approval blocks full autopilot. Under NAIC Model 570 every Reel is an "advertisement," and the producer who made it is personally responsible. Recruiting, testimonials, anything naming a carrier or product, annuities and Section 125/Longtable cannot auto-publish. They need Chris's one-tap approval, and carrier-named content also needs a logged carrier pre-approval ID. No AI can grant that.
- Recruiting content is where enforcement already happened. The FTC sent IMO Family First Life a cease-and-desist over agents' income posts and said the IMO is responsible for its participants' claims. No income figures, ever. Typical-earnings data is unanswered.
- TikTok requires GHL (or another audited aggregator). TikTok will not audit a home-built "upload to my own account" tool, so unaudited apps can only post
SELF_ONLYto private accounts. Whether Chris's GHL plan exposes Social Planner API scopes is unverified. Fallback: Zernio. config/facts.mdis empty ("(none yet)"). Model 570 requires every statistic to have a named, recent source. Until Chris approves facts, no script can use a single number.- The marketing bible interview sheet is unanswered. 222-Agent-Marketing-Bible v0.5 has 36 questions, including "pick your top 3 hooks." It stalled Sept 27. Without it the script agent writes generic content, and generic finfluencer content drifts toward phrases regulators target.
- Local Whisper conflicts with the "no fans" rule. Chris asked to "transcribe locally with Whisper." Running Whisper on his Mac is exactly the CPU/fan load he wants to avoid, and the Cowork sandbox also runs on his Mac. Cloud Whisper costs pennies a month, so it is the default here. Local whisper.cpp is an opt-in overnight toggle. Details in Swipe Intake.
- Unverified platform facts: Instagram API publish cap (Meta's page says both 100 and 50 per 24h; design assumes 50 and reads
content_publishing_limit); Business Discovery 2026 field list (competitor view counts may not come back); Trial Reels viatrial_paramsuntested on his account; YouTube "unverified projects are private-locked" claim (2026 docs say no, test once); Submagic B-roll and silence-cut API parameters; the 140 to 160 WPM pace (uncited). - Swipe Intake practical limits. Instagram doesn't let you save most other people's Reels to Photos, so screen recording is the realistic capture. Screen recordings include IG's UI overlay, so the breakdown must ignore UI chrome. Worker request bodies cap around 100 MB, so files larger than that need a two-step presigned R2 upload. iCloud may keep files as cloud-only placeholders, so the watcher must force a download first.
- Copyright. A private transcript kept for analysis is low risk. Republishing it, or a close paraphrase, is not. The system borrows structure and hook type only and rejects any script with a run of 6+ consecutive words matching the reference.
- No AI voice or avatars. Meta, TikTok and YouTube label realistic synthetic voices and faces. An "AI info" tag would make the post "about AI," which breaks Chris's own rule. The Oct 19 "AI voiceover videos" idea conflicts with this.
- Vendor prices are mostly from competitor comparison pages. No vendor virality score has independent validation. Claude 2026 API prices were not retrieved, so they are estimates.
2. What already exists
The file sweep found no roadmap or build for a social media manager. One working piece, and a lot of stalled inputs.
| Asset | State | Use in this build |
|---|---|---|
| #222 Project Folder/linkedin-daily/ | Working (delivered Nov 3). 7:30 AM launchd job, claude-haiku-5-5, one LinkedIn post plus branded card to Discord #social-media-posts; Chris posts by hand. Enforces no $ or %, banned phrases, max 3 hashtags, hook dedupe. | Seed of the Compliance Gate; launchd pattern reused for the iCloud watcher; Discord channel pattern reused for swipe notifications. Stays as is. |
| config/facts.md | "(none yet)" | Becomes the Supabase facts table. Blocker. |
| 222-Agent-Marketing-Bible v0.5 | Stalled Sept 27. Consumer social "none produced yet." Retirement, solar, advanced copy on compliance hold. 36-question sheet unanswered. | Voice and pillar source once answered. |
| Debt-to-Capital bible v1.8 | Locked; has a social section. | Hook library seed. |
| Producer-playbook pipeline | ~2,925 tagged library items, a teleprompter_script.md prompt, 30 Ignite teleprompter scripts flagged "none film-ready." | Hook library seed; script prompt reference. |
| Longtable / tfgap bibles | Include a Quantum 125 (Section 125) version. | Flex-script source, yellow lane only. |
| Longtable Outreach Command Center | Email and LinkedIn DM outreach, not social. Blocked on Cloudflare OAuth and a HeyReach key. | Out of scope. |
| agent-swarm-factory inventory | "Social media agent fed by a marketing bible": mentioned, never started. "Blog autopilot" via GHL Social Planner: not started. | This page is that build. |
| House rules | triumphantfg.com only; bans "guarantee," "six figures," "passive income," "Equis," "GBU," "game-changer," "unlock," #AI, #automation; voice "Clarity. Comfort. Compassion."; max 1 emoji, 0 to 3 hashtags; hook, value, soft CTA; recruiting carries earnings disclaimer, "not an MLM," "team lead, never upline"; keep apostrophes, no em dashes or semicolons, no tax-free framing. | Compliance Gate rule set v1. |
Swipe Intake (primary research lane)
Chris sends Reels he likes. The cloud does the rest. His Mac uploads at most, and only on route (b).
- Capture. Save or screen-record the Reel on iPhone (Control Center → Screen Recording) or Mac (Cmd+Shift+5). Optional: note the source handle and view count shown on screen.
- Send, by one of three routes:
- (a) iOS share-sheet Shortcut "Send to TFG Swipe" (recommended). Share → Send to TFG Swipe → optional note ("@handle, liked the cold open, 1.2M views"). The Shortcut POSTs file + note to
https://swipe.<worker>/swipewith headerAuthorization: Bearer <SWIPE_TOKEN>. The Worker writes to R2tfg-swipeand enqueues a job. The Mac is not involved. Over ~100 MB: the Shortcut first asks the Worker for a presigned R2 URL, then PUTs the file there. - (b) iCloud Drive folder "TFG Swipe Inbox". A tiny launchd agent (same pattern as linkedin-daily) uses
WatchPathson~/Library/Mobile Documents/com~apple~CloudDocs/TFG Swipe Inbox. It wakes only when a file lands, runsbrctl downloadif the file is a placeholder,curl-uploads it to the Worker, and moves it toSent/. Upload only, near-zero CPU, no transcription on the Mac. - (c) Claude via Dispatch or chat. Attach the video (and a note). Claude posts it to the same Worker endpoint, so the pipeline is identical.
- (a) iOS share-sheet Shortcut "Send to TFG Swipe" (recommended). Share → Send to TFG Swipe → optional note ("@handle, liked the cold open, 1.2M views"). The Shortcut POSTs file + note to
- Transcribe. Default: cloud Whisper. Groq
whisper-large-v3-turboor OpenAIgpt-4o-mini-transcribe, about $0.003/min or less, so roughly 60 one-minute refs a month cost under $0.25. Word timestamps are kept for pacing math. - Breakdown. Gemini watches the actual video (not just the transcript), so it sees on-screen text, the visual hook and the cuts. It is told to ignore Instagram UI overlay. Output JSON:
- Hook in the first 3 seconds: verbal, visual and on-screen text hooks, plus hook type (question, contrarian, sourced stat, mistake/warning, story open, POV/skit, list, authority, visual interrupt, direct callout)
- Structure/beats with timestamps
- Pacing: words per minute (from ASR timestamps), cuts per 10 seconds
- Caption and on-screen text style
- CTA
- Format: talking head, green screen, skit, list or story
- Length
- "Why it works"
- Transferability to TFG, scored 1 to 5
- Log. Write to Supabase
swipe_refs(file, route, note, source, private transcript) andswipe_breakdowns(the analysis), tagged by theme, hook_type, format and niche. If Chris supplies view counts (and optionally the account's typical views), store an outlier note: views ÷ typical, flagged at 3× or more. - Generate. Claude writes 3 original TFG scripts per reference in Chris's voice:
- one consumer life-insurance script
- one recruiting script (yellow lane)
- one flex script (Section 125/Longtable, or a TFG value angle)
- Deliver. Scripts that pass land in the teleprompter folder/queue (
S042-H1.txt,S042-H2.txt,S042-BODY.txtin the shared Drive folder) with lane flags. Chris gets a Discord notification in the same channel pattern as linkedin-daily, with the breakdown summary, transferability score and Approve buttons for yellow-lane scripts.
TRANSCRIBE_ENGINE=local queues files for whisper.cpp with the base.en model, run by a launchd job at 2 AM while plugged in. It is slower and less accurate than large-v3-turbo, and it still spins the fans, just while he sleeps. Gemini still has to see the video in the cloud for the breakdown, so going local saves no privacy and almost no money.Illustration: one reference, three original scripts (structure borrowed, wording not)
Reference pattern (abstracted): mistake/warning hook, green screen over a headline, 3-point list, comment-keyword CTA, 32 s.
Samples follow house rules: no numbers needing a fact source, no guarantees or income claims, no em dashes, soft CTA. Recruiting sample still routes to the yellow lane.
3. Framework diagram
Swipe Intake is stage 0 and primary. The scrape lane is dotted because it is optional and later. One human job: recording.
flowchart TD
subgraph S0["0. SWIPE INTAKE (primary)"]
A1["Chris saves or screen-records a Reel"] --> A2{"Send route"}
A2 -->|"a. Share Sheet Shortcut (recommended)"| W["Cloudflare Worker /swipe + secret token"]
A2 -->|"b. iCloud folder + launchd watcher"| W
A2 -->|"c. Claude via Dispatch or chat"| W
W --> R2[("R2 tfg-swipe")]
R2 --> TR["Transcribe: cloud Whisper default, local whisper.cpp opt-in"]
TR --> GB["Gemini breakdown: hook, beats, pacing, CTA, format, why it works, transfer 1-5"]
GB --> LG[("Supabase swipe_refs + swipe_breakdowns")]
end
subgraph S0B["Optional scrape lane (later)"]
SC["Sandcastles, Apify, IG Business Discovery, YouTube Data API"]
end
LG --> RS["1. Research: patterns + weekly outlier brief"]
SC -.-> RS
RS --> IS["2. Idea and Script: 3 scripts per ref, n-gram 6-word check"]
IS --> CG1{"3. Compliance Gate (pre)"}
CG1 -->|"green"| RK["4. Recording Kit: teleprompter queue + Discord ping"]
CG1 -->|"yellow"| AP["Chris one-tap approve in Discord"]
AP --> RK
CG1 -->|"red"| BL["Blocked or rewritten"]
RK --> HU(["Chris records (the human job)"])
HU --> QG["5. Quality Gate: Gemini + ffmpeg on Modal"]
QG -->|"REDO with timestamped fixes"| RK
QG --> CG2{"6. Compliance Gate (post) on actual transcript"}
CG2 -->|"spoken hard-block: REDO"| RK
CG2 --> ED["7. Editing: Submagic API or Modal ffmpeg"]
ED --> PB["8. Publishing: IG + YouTube direct, GHL for TikTok, FB, LinkedIn Page"]
PB --> AN["9. Analytics and Learning"]
AN -.->|"hook weights, what to swipe next"| RS
AN -.->|"rubric recalibration"| QG
Agent cards
0. Swipe Intake primary
- Job
- Receive Chris's reference videos, transcribe, break down, log, trigger scripts.
- Tools
- iOS Shortcut, launchd watcher, Claude Dispatch; Cloudflare Worker + R2 + Queues; Groq/OpenAI Whisper; Gemini 3 Flash; Supabase
- In / Out
- Video + note →
swipe_refs,swipe_breakdowns, job for Idea and Script
1. Research
- Job
- Turn breakdowns into abstracted patterns; weekly "10 outliers and why" brief. Optionally ingests scrape-lane data.
- Tools
- Worker cron (Sun 6 AM), Gemini, optional Sandcastles/Apify/Business Discovery
- In / Out
- Swipe breakdowns, watchlist (optional) →
patterns, Discord brief
2. Idea & Script
- Job
- 3 scripts per swipe ref (consumer, recruiting, flex) plus weekly 7 to 8 scripts × 3 hooks.
- Tools
- Claude API; hook library with Thompson weights; n-gram + pgvector originality checks
- In / Out
- Patterns, breakdowns, approved
facts, bibles →scripts,script_hooks, captions per platform
3 + 6. Compliance Gate (pre and post)
- Job
- Lane every script, caption and final transcript green/yellow/red; rewrite; append disclosures.
- Tools
- Regex rule table + Claude review using the insurance-tax-strategy-compliance framing
- In / Out
- Script or transcript, rules, facts →
compliance_reviews, rewrites, disclosure footer
4. Recording Kit
- Job
- Teleprompter files, shoot sheet, slate codes; Discord ping.
- Tools
- Google Drive API; Teleprompter Pro or PromptSmart on iPhone
- In / Out
- Approved scripts →
S042-H1.txtetc., shoot sheet
5. Quality Gate
- Job
- Score every take; publish/schedule/draft/redo verdict with ranked fixes.
- Tools
- Modal: ffmpeg ebur128, silencedetect, signalstats, 0 to 3 s subclip, ASR word timestamps; Gemini full clip + subclip
- In / Out
- Raw take + script →
qc_reports, Discord verdict
7. Editing
- Job
- 9:16 renders, captions, jump cuts, loudness to −14 LUFS, thumbnails.
- Tools
- Submagic Business + API; Modal ffmpeg fallback (ASS captions, two-pass loudnorm)
- In / Out
- Take, word timestamps, brand kit →
renders
8. Publishing
- Job
- Schedule and post; build IG containers 10 to 30 min ahead; respect rate limits; archive.
- Tools
- Worker cron every 5 min; IG API with Instagram Login; YouTube
videos.insert+publishAt; GHL Social Planner v3 - In / Out
postsqueue → live posts,archive_records
9. Analytics & Learning
- Job
- Pull metrics at 1h/24h/72h/7d; evaluate hook tests; reweight hooks; tell Chris what to swipe more of.
- Tools
- IG insights (skip rate, watch time, shares), YouTube Analytics retention, GHL Statistics and contact sources
- In / Out
- Platform data →
post_metrics,experiments,learnings, Monday 5-line report
Three compliance lanes
| Lane | Covers | Action |
|---|---|---|
| GREEN | Generic life-insurance education with no carrier, product or numbers; behind the scenes and team culture; "our automated CRM helps our agents"; seasonal and community content | Auto-publish after both gate passes |
| YELLOW | Recruiting, any testimonial, any carrier or product, annuities/retirement, Section 125/Longtable, any stat not in facts | One Discord tap; carrier-named also needs a carrier approval ID |
| RED | Medicare, variable products and "market returns," income figures, "tax-free," illustrated rates, "free coverage," government look-alikes, any post about AI or automation itself | Blocked |
4. Quality Gate scorecard
100 points; compliance is pass/fail on top. Thresholds are recommendations to be recalibrated after 25 published posts against IG skip rate and watch ratio.
| Dimension | Pts | Measured by | Pass threshold |
|---|---|---|---|
| Hook, 0 to 3 s | 25 | ASR time-to-first-word; Gemini on 0 to 3 s subclip (verbal hook, visual interrupt, on-screen text by 1.0 s) | First word ≤0.5 s; hook complete ≤3.0 s; Gemini hook sub-score ≥18/25 |
| Retention predictors | 20 | silencedetect, WPM, cut density, script adherence (WER vs script) | No silence >0.6 s after edit; 155 to 185 WPM post-cut; visual change every ≤4 s; adherence ≥85% |
| Delivery | 15 | Gemini (eye line, energy, warmth); ASR filler count | Fillers ≤2/min; eye contact ≥80% of frames |
| Audio | 10 | ebur128 / true peak, noise judgment | Raw integrated −20 to −10 LUFS (normalized to −14 on edit); true peak ≤−1 dBTP; no clipping |
| Lighting/framing | 10 | signalstats YAVG; Gemini framing | Face luma mean 90 to 170; blown highlights ≤2% of frame; eyes in upper third; 9:16 at 1080×1920 |
| Captions/on-screen text | 5 | Render check of safe zones | Nothing in bottom 20% or right 15% UI zones |
| CTA | 5 | Transcript, last 5 s | Exactly one soft, compliant CTA |
| Length | 5 | Duration | Education 20 to 45 s; story 45 to 75 s; nothing >90 s at launch |
| Compliance | Gate | Regex rules + Claude review of transcript, caption, on-screen text | Any hard-block rule = automatic fail |
Decision rules
| Condition | Verdict | Action |
|---|---|---|
| Compliance hard-block spoken in the take | REDO | Discord message quoting the exact second and phrase, plus a compliant rewrite line |
| Compliance issue only in caption/on-screen text | Auto-fix | Rewrite caption, re-run gate, continue |
| Yellow-lane topic (recruiting, testimonial, carrier/product, Section 125, annuity) | DRAFT → approval | One-tap Approve/Reject in Discord; carrier-named waits for a logged carrier approval ID |
| Score ≥80, green lane | SCHEDULE | Next open slot; timely/news content gets PUBLISH NOW |
| Score 70 to 79, green lane | SCHEDULE as Trial Reel only | Non-followers first; graduates on performance |
| Score 60 to 69 | DRAFT | Held for a re-edit with listed fixes, or downgraded to a Story |
| Score <60, hook <15/25, unusable audio, or adherence <70% | REDO | Three ranked fixes with timestamps (e.g. "0:00 to 0:02 you look down at the prompter; raise the phone 4 inches") |
5. Tool comparison
Sort by any column; search filters all columns. Prices are from the report and research notes; most third-party prices are unverified.
6. Data model
Supabase (Postgres + pgvector). Swipe tables are new; the rest is from the report.
| Table | Key columns |
|---|---|
swipe_refs (new) | id, received_at, route (shortcut/icloud/dispatch), r2_key, source_platform, source_handle, source_url, chris_note, views, account_typical_views, outlier_note, duration_s, transcribe_engine (cloud/local), transcript + words jsonb (service-role only), status |
swipe_breakdowns (new) | id, swipe_ref_id, hook_verbal, hook_visual, hook_text, hook_type, beats jsonb [{t, beat}], wpm, cuts_per_10s, caption_style, onscreen_text_style, cta, format (talking_head/green_screen/skit/list/story), length_s, why_it_works, transferability (1 to 5), tags: theme, niche; model_version |
brands | id, name (TFG / Longtable), domain, disclosure_footer, voice_rules jsonb |
platform_accounts | id, brand_id, platform, handle, account_type, auth_ref, ghl_account_id, publish_path (direct/ghl) |
watch_accounts / source_posts / source_transcripts | Optional scrape lane only: handle, niche, outlier_score, private transcript + embedding |
patterns | id, swipe_breakdown_id or source_post_id, hook_type, format, structure_note, cta_type, audio_note |
facts | id, claim, source_name, source_url, source_year, approved_by, approved_at, expires_at |
hooks | id, text, hook_type, pillar, lane, origin, uses, wins, alpha, beta, embedding |
ideas / scripts | scripts: id, idea_id, swipe_ref_id, angle (consumer/recruiting/flex), version, body, word_count, target_secs, cta, caption_by_platform jsonb, ngram_max_overlap, max_cosine, lane, status |
script_hooks | id, script_id, hook_id, variant (H1/H2/H3), text |
compliance_reviews | id, object_type, object_id, stage (script/render/caption), rules_triggered, lane, rewrites, decision, approver, carrier_approval_id, decided_at |
recordings / qc_reports | take r2_key, duration; metrics jsonb (lufs, peak, silences, wpm, fillers, yavg, ttfw, adherence), scores, total, verdict, fixes |
renders / posts | platform renders; posts: kind (reel/trial/story/short), caption, disclosures, scheduled_at, status, platform_post_id, experiment_id |
post_metrics / experiments / learnings | horizon (1h/24h/72h/7d), views, reach, skip_rate, watch_ratio, shares, saves, retention_curve; arms, posterior, winner; weekly finding + rule_change |
archive_records | post_id, final media, transcript, caption, approvals, live_from, live_to, retain_until (≥ live_to + 5 years, Model 570 Sec. 9A) |
Cloudflare layout
| Piece | Detail |
|---|---|
| Worker app | Routes: POST /swipe (Bearer SWIPE_TOKEN, multipart file + note), POST /swipe/presign (large files), Discord interaction endpoint (Approve/Reject/Redo), webhooks (Modal, GHL, Meta). Cron: publish every 5 min, analytics hourly, research Sun 6 AM, scripts Sun 9 AM. |
| Queues | swipe-jobs (transcribe → breakdown → scripts), plus a queue between each studio stage |
| R2 buckets | tfg-swipe (private reference videos, new), tfg-inbox (Chris's raw takes), tfg-renders, tfg-public (unguessable-key media subdomain so Meta can fetch video_url), tfg-archive (private, 5+ years) |
| Pages "Studio" | Dashboard behind Cloudflare Access: swipe file, script queue, scorecards, learning log |
| Secrets | wrangler secret put: SWIPE_TOKEN, GROQ_API_KEY or OPENAI_API_KEY, GEMINI_API_KEY, ANTHROPIC_API_KEY, SUPABASE_SERVICE_KEY, DISCORD_WEBHOOK_URL, DISCORD_BOT_TOKEN, META/YT/GHL tokens |
| Off-Worker compute | Modal for ffmpeg and ASR (Workers can't run ffmpeg; Containers are beta; Supabase Edge Functions cap at 256 MB / 2 s CPU). Nothing heavy on the Mac. |
7. Cadence & costs
Volume targets (weeks 1 to 4)
| Output | Per week |
|---|---|
| Swipe references from Chris | Target 5 to 15 (each yields 3 scripts); answer in Interview Q2 |
| Instagram Reels | 5 (Mon to Fri), repurposed same day to TikTok, YouTube Shorts, Facebook Reels, staggered 1 to 3 hours |
| IG Trial Reels (hook tests) | 2 to 3 |
| Stories | Daily, from cut-downs and hook stills |
| LinkedIn Page videos | 3 |
| LinkedIn personal text post | Daily (existing linkedin-daily, still posted by hand) |
| Longtable / Section 125 | 2 LinkedIn posts, own brand accounts, yellow lane |
| Recording session | One, 60 to 90 min, 7 to 8 scripts × 3 hooks |
Pillar mix: 40% consumer protection education, 25% agent career/recruiting (yellow), 15% retirement/annuity concepts (yellow, no numbers), 20% behind the scenes, team, CRM. Scale to 7 Reels/week only when first-take quality-gate pass rate holds ≥70% for 3 straight weeks.
Monthly cost
| Line item | Lean | Recommended | Notes |
|---|---|---|---|
| Swipe Intake (Worker + R2 storage + cloud Whisper + Gemini breakdown + Claude 3 scripts/ref) | ~$1 to 4 | ~$2 to 6 | At ~60 refs/mo: Whisper <$0.25, Gemini <$1, Claude ~$1 to 4 (estimate). Worker included in the $5 plan |
| Cloudflare Workers Paid (cron, queues, R2, Pages, Access) | $5 | $5 to 10 | R2 at tens of GB is an unverified few-dollar estimate |
| Supabase | $0 | $25 | Pro recommended for backups (5-year archive duty); price unverified |
| Modal (ffmpeg + ASR for takes) | $0 to 2 | $2 to 5 | ~$0.047/core-hour |
| Gemini 3 Flash (quality gate) | <$5 | <$10 | Watch billing anomalies reported on forums |
| Claude API (studio scripts, compliance, captions) | ~$10 | ~$20 to 40 | Estimate only |
| Submagic Business + API | $0 (Modal DIY) | $41 to 69 | Drop by month 2 if Modal captions match |
| Research vendor (Sandcastles/Virlo/Apify) | $0 | $0 (optional) | Secondary lane; add only if swipes don't supply enough ideas |
| GHL Social Planner | $0 incr. | $0 incr. | Assumes API on current plan; unverified |
| Teleprompter app | $0 to 10 | $0 to 30 | Prices conflict |
| Fallback poster (only if GHL API blocked) | n/a | $0 to 24 | Zernio / Upload-Post |
| Local whisper.cpp toggle | $0 | $0 | Costs fan noise and battery, not dollars |
8. Week plan: Wed Nov 4 to Tue Nov 10, 2026
Day 1 to 2 priority: get Swipe Intake working end to end before anything else. Click paths are "look for this menu," since vendor labels move. Checkboxes save in this browser.
Slip risks: Meta token or permission surprises, missing GHL API scopes, the YouTube private-lock claim. Each has a fallback (Zernio, or GHL for YouTube). None should move Sunday's recording session.
9. Interview
The answers that most change the design. They autosave in this browser. Export builds a markdown file to send back.