| Name | Age | What they do | Submitted | Status | Actions |
|---|
| When | Guest | Calendar | Application | Actions |
|---|
| Name | Plan | Squad | Streak | Rank | Status | Actions |
|---|
| # | Start | End | Status | Winner | Actions |
|---|
System Manual
How It All Works
THUMOS runs on one Cloudflare Worker (thumos-api) + one D1 database (thumos-db). Every page, bot, and admin tool reads from and writes to the same database. There is one source of truth.
The Member Journey (current primary funnel — application-gated)
- Discovery — they land on thumos.academy (price is hidden; all CTAs → /apply)
- Application — they fill out /apply (name, age, occupation, what they want, why now, income range). Saved to D1
applications. PRAGMA pings Thumos CRM with#application. - Book the call — inline slot picker on the same page. Shows Sam's real free times (freeBusy auto-subtracts his calendar). They pick a slot.
- Calendar + Meet — worker creates a Google Calendar event on the "THUMOS Consults" calendar with an auto-generated Meet link. Sam ([email protected]) is invited as attendee. Both get Google invite emails with .ics.
- Confirmation email — Resend email from [email protected] with the Meet link. PRAGMA pings Thumos CRM with
#booking. - The call — Q / Sam runs the call. Decision: enroll, reject, or follow up.
- Enrollment — if yes, Q sends the Stripe checkout link or admin-creates the user. Stripe webhook → D1
usersrow + welcome email. - Onboarding — 3 steps: sign the commitment, set milestones (body/women/money), write first gratitude post.
- Telegram Link — "Join Squad" button opens a bot DM that auto-links Telegram to their account.
- Daily Life — every weekday they post
Action:+Grateful:in their squad. Bot detects, records, responds. - Courses + Cycle — watch videos, mark complete. Every 30 days declare milestones hit/miss. Winning squad gets a debrief with Sam.
Warm/DM traffic that already knows the price can still use /checkout directly — Stripe → same webhook path.
Post Detection
The Telegram bot watches for messages that have Action: AND Grateful: at the start of a line. Both required. One post per weekday — duplicates silently ignored. Weekend posts are recorded but don't count toward score.
Streak = consecutive weekdays posted. Weekends don't break it. Miss a weekday → streak resets to 0.
Scoring System
Personal score per cycle = (posts ÷ weekdays × 50) + (milestones hit ÷ 3 × 50) = max 100 per cycle
Squad score = same formula but aggregated across all squad members, percentage-based
Cumulative score persists across cycles and determines rank.
| Rank | Points | Typical Timeline |
|---|---|---|
| Initiate | 0-199 | 0-3 months |
| Journeyman | 200-499 | 3-6 months |
| Adept | 500+ | 8-12 months |
Cycles
~30 days per cycle. Leaderboard resets each cycle. Rank persists forever.
Start a cycle → resets all squad scores, creates new cycle record. Old cycle marked "ended".
End a cycle → pick winning squad. They get a private debrief with Sam.
New members mid-cycle: excluded from squad score that cycle.
Milestones
3 per user per cycle: Body, Women, Money. Set during onboarding or cycle start.
Visible to squad immediately. Cannot be changed once submitted.
At cycle end: declare hit or miss. Early completion allows optional new milestone (no extra points).
Automated Systems
| System | When | What |
|---|---|---|
| Stripe webhook | On payment | Creates user + sends welcome email |
| Post detection | Every message in squad | Checks format → records post → responds with 🔥 |
| 8pm reminder | Every hour (checks user timezone) | If it's 8pm for a user and they haven't posted → bot messages squad |
| Score recalc | 5:00 UTC daily | Recalculates all squad scores |
| Bot auto-link | User taps deep link | Links Telegram ID to THUMOS account |
| Group welcome | User joins squad | Bot sends welcome message with post format |
Invite Codes
Free members use invite links: thumos.academy/invite?code=FORGEDAY1
| Code | Squad | For |
|---|---|---|
| FORGEDAY1 | Squadron Lambda | OG fight camp / BDE members |
| FORGETHETA | Squadron Theta | Second group |
To add new codes: edit INVITE_CODES in worker.js and redeploy.
Telegram Groups
| Group | Purpose | Invite |
|---|---|---|
| THUMOS | All members + Sam. Topics enabled. | Link |
| Squadron Lambda (Λ) | First squad | Link |
| Squadron Theta (Θ) | Second squad | Link |
Bot: @ThumosAI
Infrastructure
| Component | Service | URL |
|---|---|---|
| API | Cloudflare Worker | thumos-api.q-2f4.workers.dev |
| Database | Cloudflare D1 | thumos-db |
| Main site | Cloudflare Pages | thumos.academy |
| Editor | Cloudflare Pages | editor.thumos.academy |
| Admin | Cloudflare Pages | admin.thumos.academy |
| Videos | Cloudflare Stream | Stream IDs in D1 |
| Payments | Stripe | Product: prod_UILptFYD8wxzKO |
| Resend | [email protected] | |
| Bot | Telegram | @ThumosAI |
7-Day Guarantee
Not a trial. Full access from day 1. If they do the work (daily posts, course engagement) and it's not for them after 7 days, full refund. Manual process — review and process through Stripe dashboard.
Deploy Commands
# Deploy API (Worker) cd selene/markets/thumos/deploy_api && npx wrangler deploy # Deploy main site npx wrangler pages deploy "selene/markets/thumos/deploy_main" --project-name=thumos-academy --commit-dirty=true # Deploy editor npx wrangler pages deploy "selene/markets/thumos/deploy_editor" --project-name=thumos-editor --commit-dirty=true # Deploy admin npx wrangler pages deploy "selene/markets/thumos/deploy_admin" --project-name=thumos-admin --commit-dirty=true # Or: git push (auto-deploys main site)
Applications
What this is
The primary funnel as of April 2026. Price is hidden on the main site — every CTA drives to thumos.academy/apply. Lead has to apply before they can even see the Forge offer.
Purpose: qualify. We don't want people who need a credit-card button; we want people who'll do the work. The application forces them to articulate what they actually want, and the call lets us tell them the exact thing they need to do — whether the Forge is that move or not.
The form fields
| Field | Required | Why |
|---|---|---|
| name | yes | obvious |
| yes | for follow-up + confirmation | |
| age | no | qualification signal (18–28 is sweet spot) |
| occupation | no | context for the call |
| goal | yes | "What do you want?" — most important answer |
| why_now | no | urgency / stakes — reveals readiness |
| income_range | no | informs payment-plan offer |
| no | vibe check before the call | |
| source | auto | UTM params + referrer, captured silently |
Status flow
- pending — default on submit. Needs review.
- invited — reviewed, good fit, moved forward (booking exists or invite sent).
- rejected — reviewed, not a fit right now.
- enrolled — they paid and became a member.
Status is set from the Applications tab. Click any application row → detail modal → status buttons + notes field. Pending rows also have inline Invite/Reject buttons.
PRAGMA ping
Every submitted application posts a #application message via PRAGMA bot into the Thumos CRM topic of the main PRAGMA supergroup. The ping includes everything they wrote so you can react from Telegram without opening the admin.
D1 schema
applications ( id, name, email, age, occupation, goal, why_now, income_range, instagram, status, source, notes, submitted_at, reviewed_at )
Migration: deploy_api/migrate_applications.sql
Bookings & Calendar
What this is
Sovereign booking system — ported from Meridian's booking-worker, now running inside the main thumos-api worker. No Cal.com, no Calendly. Multi-tenant by calendar slug, D1-backed, Google Calendar + Meet integrated, Resend-wired.
How a booking happens
- Applicant fills out /apply → application row saved → PRAGMA pinged
- Apply page flips to the inline slot picker (same page, no redirect)
- JS fetches
/api/book/thumos-apply/dates?month=YYYY-MM— worker generates slots fromavailability_rules, subtracts existing bookings, subtracts Sam's real calendar events via Google freeBusy API, returns dates where anything is free - Applicant picks a date →
/api/book/thumos-apply/slots?date=…returns open times for that day (same filter logic) - Applicant picks a slot →
POST /api/book/thumos-apply/bookwith the chosen UTC time, name, email, application_id - Worker: inserts booking row → creates Google Calendar event on THUMOS Consults with a unique Meet link, invites Sam + guest → fires Resend branded confirmation with the Meet link → PRAGMA pings CRM with
#booking
Sam's availability (currently)
Mon–Sat, 09:00–22:00 Asia/Bangkok. Sundays off. 30-min slots, 12-hour minimum lead, 14-day booking horizon.
The outer window (when Sam is willing to take calls) lives in D1 availability_rules. Inside that window, the worker auto-checks Sam's real calendar ([email protected]) via freeBusy and removes any slots that conflict with his existing events. So applicants only ever see slots Sam is both willing and free to take.
To change the outer window, edit the availability_rules rows directly in D1. To block specific dates (e.g. Sam is traveling April 28–30), insert into date_overrides with type='block'. There's no admin UI for this yet — SQL only.
Bookings tab
The Bookings admin tab lists confirmed calls. Filters: Upcoming / Past / All. Each row links to the underlying application if one exists. Cancel button:
- Marks
status='cancelled'in D1 - Deletes the Google Calendar event with
sendUpdates=all— both parties get a Google cancellation notice - PRAGMA pings CRM with
#booking #cancelled
Google Calendar integration
Uses a service account ([email protected]) with domain-wide delegation impersonating [email protected]. The worker signs an RS256 JWT, exchanges it for an access token at oauth2.googleapis.com/token, then hits the Calendar API.
Events land on the secondary THUMOS Consults calendar (owned by Q, shared with Sam with edit permission). This keeps them separate from Q's personal calendar.
Required OAuth scope on the domain-wide delegation: https://www.googleapis.com/auth/calendar
To rotate the service account key: IAM → Service Accounts → thumos-booking → Keys → create new, delete old, re-run wrangler secret put GOOGLE_SA_PRIVATE_KEY.
Multi-tenant by slug
The calendars table is keyed by slug. Right now there's one: thumos-apply (30-min intro calls). To add another — e.g. existing-member 1:1s at a different price or different availability — insert a new calendars row + availability_rules, and the same /api/book/:slug/... endpoints work without any code change.
D1 tables
calendars (slug, name, timezone, slot_duration, slot_gap, owner_email, from_email, meet_url, booking_lead, booking_horizon, ...) availability_rules (calendar_id, day_of_week, start_time, end_time, active) bookings (calendar_id, application_id, slot_start, slot_end, guest_name, guest_email, meet_url, google_event_id, status, notes) date_overrides (calendar_id, date, type, start_time, end_time)
Migrations: migrate_bookings.sql, migrate_bookings_meet.sql, migrate_sam_availability.sql
Common SQL ops
Change Sam's window to Mon–Fri only:
DELETE FROM availability_rules WHERE calendar_id = (SELECT id FROM calendars WHERE slug='thumos-apply') AND day_of_week = 6;
Block April 28 (Sam traveling):
INSERT INTO date_overrides (calendar_id, date, type)
VALUES ((SELECT id FROM calendars WHERE slug='thumos-apply'),
'2026-04-28', 'block');
Change slot length to 45 min:
UPDATE calendars SET slot_duration = 45 WHERE slug = 'thumos-apply';
Run via: npx wrangler d1 execute thumos-db --remote --command "..."
New Member Onboarding
How They Get Here
Two paths into onboarding:
| Path | URL | What happens before |
|---|---|---|
| Paid | thumos.academy/checkout | Pay $1,997 or 3x$699 on Stripe → webhook creates account → welcome email with login → they log in → redirected to onboarding |
| Invited | thumos.academy/invite?code=X | Enter name, email, password + invite code → account created instantly → auto-logged in → redirected to onboarding |
Both paths end at thumos.academy/onboarding. The page checks auth and onboarded status — if already onboarded, redirects to portal.
Step 1: The Commitment
What they see: A commitment statement (not terms and conditions). Sam's video will play here explaining what they're stepping into — currently a placeholder until Sam records it.
The commitment text:
- "I am here to become the man I am capable of being. Not to observe. Not to consume. To become."
- "I will post my daily action and gratitude every weekday without exception."
- "I will set three honest milestones — one for each realm."
- "I will show up to the calls."
- "I will hold my brothers to the same standard I hold myself."
- "I understand that my failure belongs to the men beside me."
What they do: Type their full name and today's date. This replaces a checkbox — writing it makes it real.
What's saved: Nothing yet — the commitment is a ritual, not data. Future: store the signed commitment in D1.
Design intent: Abundance energy, not compliance. Alan's feedback: "put them in a state of abundance, not obligation." Sam's video will set the tone. The dark aesthetic may change to something more expansive.
Step 2: Your Milestones
What they see: An AI prompt they copy-paste into Claude or ChatGPT. The AI walks them through a guided conversation to discover what they actually want to work on.
How the prompt works:
- Asks which domain feels most alive — Women, Money, or Body
- Goes deep on ONE domain at a time (one question at a time, never a list)
- If they're stuck, flips to anti-vision: "What do you NOT want?"
- Sharpens into a concrete 30-day milestone (binary, specific, uncomfortable)
- Repeats for each domain
- Outputs 3 clean lines: WOMEN: / MONEY: / BODY:
Key principles in the prompt:
- Never hand them a milestone — guide them to their own conclusion
- If they list 6 goals, stop them: "Pick one."
- If they're already strong in a domain (like Body), respect it — don't manufacture struggle
- Match their energy. Call out deflection gently.
- 10-20 minutes if done right
What they do: Paste their 3 milestones into the input fields (Women, Money, Body).
What's saved: 3 milestones saved to D1 milestones table with current cycle ID.
Prompt location: Embedded in onboarding.html inside a copy-paste box.
Step 3: First Post
What they see: A mock post card showing the daily format. The "Action" is pre-filled: "I joined the Forge. My milestones are set. I am beginning." They type one thing they're grateful for.
What they do: Write their gratitude → click "Post it — Enter the Forge"
What happens:
- Milestones saved to D1 (POST /onboarding/milestones)
- User marked as
onboarded = 1in D1 - "You're in" screen appears with 4 links
"You're In" Screen
After completing step 3, they see 4 action items:
| Item | Link | What it does |
|---|---|---|
| Join Squad | Bot deep link: t.me/ThumosAI?start=LINK_{userId} | Opens bot DM → auto-links their Telegram account → bot sends squad invite + THUMOS group link |
| Join THUMOS | t.me/+4deDUZpuZ7k1ZWMx | Opens THUMOS main Telegram group |
| Enter Portal | /portal | Goes to member dashboard |
| Start: Breathe Like A Dragon | /courses/c01 | First course, lesson 1 |
Below these: "Don't have Telegram? Download it here" link + "Need help? Message Q directly" link to Q's Telegram DM.
After Onboarding
Once onboarded, visiting /onboarding redirects to /portal. They're in the system:
- Portal shows their real data (streak, squad, milestones, leaderboard)
- Telegram bot tracks their daily posts
- Courses are accessible with progress tracking
- 8pm reminder kicks in if they don't post
What's Not Built Yet
- Sam's commitment video — placeholder in step 1
- Photo signature — currently text name+date, future: upload photo of handwritten signature
- Anti-vision pairing — each milestone paired with "what happens if I don't" (fuel)
- Sovereign Declaration — deeper values exercise for month 2-3 members who plateau
- Auto-squad assignment — paid members currently get no squad, need manual assignment
- Portal aesthetic — currently dark, planned redesign to clean white
Telegram Bot
What It Is
@ThumosAI is a Cloudflare Worker-powered bot. It has no separate server — it runs on the same thumos-api Worker as everything else. Telegram sends messages to /telegram endpoint via webhook.
How Post Detection Works
- Member posts a message in their squad Telegram group
- Telegram sends the message to our Worker webhook
- Worker checks: does the message have
Action:ANDGrateful:at the start of a line? - If yes → look up the user by their Telegram ID in D1
- Check if they already posted today (UTC date) → if yes, silently ignore
- Record the post in
daily_poststable (who, when, which squad, weekday/weekend) - Calculate their new streak (consecutive weekdays with posts)
- Bot responds in the group: 🔥 username — Day X
Important: The bot NEVER stores message content. Only records that a post happened and when.
Post Format Rules
| Requirement | Detail |
|---|---|
| Both fields required | Action: AND Grateful: — both must be present |
| Start of line | Must be at the beginning of a line, not mid-sentence |
| Colon required | Action: works. Action test does not. |
| Case insensitive | action: and ACTION: both work |
| One per day | First valid post counts. Duplicates silently ignored. |
| Weekends | Recorded but not counted toward score. Don't break streaks. |
Streak Rules
Streak = consecutive weekdays with a recorded post. Counted backwards from today.
- Post Mon-Fri → streak goes up
- Miss a weekday → streak resets to 0
- Saturday/Sunday → ignored (don't help, don't hurt)
- Post on weekend → recorded but streak doesn't increase
8pm Reminder
A cron job runs every hour. For each active member, it checks: "Is it 8pm in their timezone?" If yes and they haven't posted today, the bot messages their squad group: [name] hasn't posted today.
Timezone is stored per user in D1 (detected from browser on signup). Default: America/New_York.
Known issue: If the Worker is redeployed while messages are in-flight, Telegram may mark them as delivered but the Worker didn't process them. Posts are lost — Telegram won't retry.
Account Linking
Members need their Telegram account linked to their THUMOS account for posts to be tracked.
Automatic (onboarding): "Join Squad" button on the onboarding completion screen is a deep link: https://t.me/ThumosAI?start=LINK_{userId}. When they tap it, the bot auto-links their Telegram ID.
Manual: In a DM or group, send /link [email protected]. Bot looks up the email in D1 and links the Telegram ID.
Admin: Directly update D1: UPDATE users SET telegram_user_id='...' WHERE email='...'
Bot Commands
| Command | Where | What |
|---|---|---|
/start | DM | Welcome message with post format |
/start LINK_X | DM | Auto-link Telegram to THUMOS account (X = user ID) |
/link email | DM or group | Manual link by email |
/streak | Group | Show your streak |
/leaderboard | Group | Show squad rankings |
/chatid | Anywhere | Show chat ID (debug) |
Group Welcome
When a new member joins a registered squad group, the bot automatically sends a welcome message with their name and the daily post format.
Groups
| Group | Chat ID | Purpose |
|---|---|---|
| THUMOS | -1003912158998 | Main group — all members + Sam. Topics enabled. |
| Squadron Lambda (Λ) | -1003992128318 | First squad |
| Squadron Theta (Θ) | -1003673790148 | Second squad |
To add a new squad: create Telegram group → add @ThumosAI as admin → use /chatid to get the ID → add squad in Admin panel or D1.
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
| Bot doesn't respond to posts | Worker was redeployed while messages in-flight | Post again — next message will work |
| Member posts but no 🔥 | Telegram ID not linked | DM bot: /link email |
| Already posted but shows 0d | Duplicate check blocked (curl test or timezone mismatch) | Check D1 for existing today post |
| Wrong timezone reminder | User timezone not set | Update in D1: UPDATE users SET timezone='...' |
| Bot not receiving messages at all | Webhook deregistered | Visit thumos-api.q-2f4.workers.dev/telegram/setup |
Scoring & Ranks
Personal Score (per cycle)
(posts ÷ weekdays × 50) + (milestones_hit ÷ 3 × 50) = max 100
Example: 18 posts out of 22 weekdays = 40.9 pts. Hit 2 of 3 milestones = 33.3 pts. Total = 74.2 pts.
Squad Score (per cycle)
Same formula but aggregated across all squad members. Percentage-based so squad size doesn't matter.
Stored in squads.cycle_total_score. Recalculated nightly at midnight UTC.
Cumulative Score
Personal score carries over between cycles. Stored in users.cumulative_score. Determines rank.
Ranks
| Rank | Points | Timeline |
|---|---|---|
| Initiate | 0-199 | 0-3 months |
| Journeyman | 200-499 | 3-6 months |
| Adept | 500+ | 8-12 months |
Rank persists forever. Leaderboard resets each cycle.
Cycles
- ~30 days per cycle
- Start: squad scores reset, new cycle record created
- End: pick winning squad → private debrief with Sam
- New members mid-cycle: excluded from squad score
Milestones
- 3 per user per cycle: Body, Women, Money
- Set during onboarding or cycle start
- Visible to squad. Cannot be changed.
- Declare hit/miss at cycle end
Infrastructure
Architecture
Everything runs on Cloudflare. One Worker (thumos-api) handles all API requests. One D1 database (thumos-db) stores all data. Three Pages projects serve the websites.
Services
| Component | Service | URL/ID |
|---|---|---|
| API | Cloudflare Worker | thumos-api.q-2f4.workers.dev |
| Database | Cloudflare D1 | thumos-db (c90051c3...) |
| Main site | Cloudflare Pages | thumos.academy |
| Editor | Cloudflare Pages | editor.thumos.academy |
| Admin | Cloudflare Pages | admin.thumos.academy |
| Videos | Cloudflare Stream | Stream IDs in D1 lessons table |
| Payments | Stripe | prod_UILptFYD8wxzKO |
| Transactional email | Resend | [email protected] (booking confirmations) · [email protected] (onboarding) |
| Member bot | Telegram | @ThumosAI (squad groups, daily posts) |
| CRM bot | Telegram | PRAGMA → Thumos CRM topic #768 (applications + bookings pings) |
| Calendar + Meet | Google Workspace | THUMOS Consults calendar (on [email protected]) + service account thumos-booking@theotherside-490901 |
Worker Secrets
All set via npx wrangler secret put <NAME> inside deploy_api/.
| Secret | What |
|---|---|
STRIPE_SECRET_KEY | Stripe payments |
STRIPE_WEBHOOK_SECRET | Stripe webhook signature verification |
RESEND_API_KEY | Transactional email (booking + welcome) |
TELEGRAM_BOT_TOKEN | THUMOS member bot (@ThumosAI) |
PRAGMA_BOT_TOKEN | PRAGMA bot — CRM pings |
PRAGMA_GROUP_ID | PRAGMA supergroup ID (-1002616802728) |
THUMOS_CRM_THREAD_ID | Thumos CRM topic inside that group (768) |
GOOGLE_SA_EMAIL | Service account email for Calendar API |
GOOGLE_SA_PRIVATE_KEY | Service account PEM private key |
GOOGLE_IMPERSONATE_USER | User the SA impersonates ([email protected]) |
GOOGLE_CALENDAR_ID | THUMOS Consults calendar ID (where events land) |
SAM_EMAIL | Sam's email — attendee on every booking ([email protected]) |
SAM_CALENDAR_ID | Sam's calendar ID — queried via freeBusy to subtract his real events ([email protected]) |
D1 Tables
Core
| Table | What | Key Fields |
|---|---|---|
| users | Members | email, plan, squad_id, rank, telegram_user_id, timezone |
| sessions | Auth tokens | user_id, token, expires_at |
| squads | Squadrons | name, telegram_group_id, cycle scores |
| daily_posts | Post tracking | user_id, squad_id, posted_at, counted |
| milestones | User goals | user_id, cycle_id, realm, text, declared_hit |
| cycles | 30-day rounds | start_date, end_date, status, winning_squad_id |
| progress | Course completion | user_id, course_slug, lesson_id |
| courses / lessons / lesson_flags | Course content + audit flags | — |
Applications + Booking (added 2026-04-19)
| Table | What | Key Fields |
|---|---|---|
| applications | /apply submissions | name, email, goal, why_now, income_range, status, notes |
| calendars | Multi-tenant calendars | slug, timezone, slot_duration, booking_lead, booking_horizon |
| availability_rules | Working windows per calendar | day_of_week, start_time, end_time |
| bookings | Scheduled calls | slot_start, guest_email, application_id, meet_url, google_event_id, status |
| date_overrides | Blocked dates | date, type |
Deploy Commands
# API (Worker) cd selene/markets/thumos/deploy_api && npx wrangler deploy # Main site npx wrangler pages deploy "selene/markets/thumos/deploy_main" --project-name=thumos-academy --commit-dirty=true # Editor npx wrangler pages deploy "selene/markets/thumos/deploy_editor" --project-name=thumos-editor --commit-dirty=true # Admin npx wrangler pages deploy "selene/markets/thumos/deploy_admin" --project-name=thumos-admin --commit-dirty=true # Or: git push (auto-deploys main site)
Worker Secrets
Set via npx wrangler secret put NAME from deploy_api/:
STRIPE_SECRET_KEYSTRIPE_WEBHOOK_SECRETRESEND_API_KEYTELEGRAM_BOT_TOKEN
| Course | Lessons | Red Flags | Orange | Resolved |
|---|