Commit Graph

152 Commits

Author SHA1 Message Date
martbost 3f8d23d66c Circle Suite: complete the ladder — every paid level now unlocks live software
Four new tools, so no tier is a placeholder any more:

L4 Voice Profile (/suite/voice) — five short answers that ride along with
every Copy Engine and Email Engine generation. It sits BEFORE the compliance
block in the prompt on purpose: a personal voice must never be able to talk
the model out of the honesty rules. suite-email builds its own prompt, so the
profile is threaded in there separately or email would keep sounding generic
while the Copy Engine sounded like the member.

L5 Split Tester (/suite/split) — 2-3 variants launched as one test with the
impressions split evenly, then click counters compared. Deliberately
conservative: it will not declare a winner until both arms have real volume
AND the leader is clearly ahead, because a 3-click gap on 400 impressions is
noise. A genuine tie is reported as a tie, which is useful information too.
A failed arm rolls back the whole test rather than leaving half of it running.
Apex is the right home for it — that is where impressions jump to 50,000.

L6 Funnel Factory (/suite/funnel) — extra named pages at /p/<id>/<slug>, so a
leader can run one page per audience and point different ads at each. Missing
slugs fall back to the member's main page, same no-dead-ends rule as /p/<id>.

L7 Leader Ops (/suite/leader) — the coaching radar already existed in chain.js
and only admin could see it, which was backwards: the leaders running those
legs need it more than anyone. Now scoped to the member's own organisation,
with a written plan built on contract-read facts only. Follows the
teach-forward rule — the digest gives the leader words to hand down, not just
numbers to act on.

Tile copy across the wall and the payout alerts now describes what actually
exists rather than what was sketched. suite-tools.js was stale in both
directions (it still had the Traffic Desk at L5 and L3 not live).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 10:49:36 -05:00
martbost d5c9e33e0e Traffic Desk: AI-written text ads alongside banners
Text placements out-perform banners on this network — 357 text ads average
~171 clicks each against ~150 for banners, on far less inventory — so
members can now run them too.

The format is measured, not guessed. Across 60 live text ads: Subject caps
at 20 characters and Body is ALWAYS exactly three <br>-joined lines of at
most 24 characters. Every ad in the sample obeyed it.

Emoji: the NAS columns are latin1, but so is the connection, so UTF-8 bytes
pass through and render — which is how the existing emoji ads got there. The
bridge's clean() would have deleted every emoji via iconv //TRANSLIT//IGNORE,
so text copy now uses clean_ad_text(), which preserves them and strips angle
brackets instead. The bridge builds the <br> separators itself from a lines[]
array, so a member can never inject markup.

The engine writes plain text to a tight budget and we apply emoji ourselves:
models cannot count characters, least of all with emoji, so decoration is
arithmetic we control. It also lets the emoji rotate independently of the
copy. The palette carries no money emoji — the network is full of them, but
implying earnings outranks matching the neighbours.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 10:19:36 -05:00
martbost 931eb4336b Traffic Desk: stop-and-refund, plus never let a banner dead-end
Three fixes from live testing of the Traffic Desk:

- /p/<id> with no page built now 302s to /join/<id> instead of returning
  raw JSON 404. Any /p/ link already on a banner, flyer, or in a DM must
  always land somewhere useful.
- The personal-page ad destination is only offered (client) and only
  accepted (server) once a page actually exists; otherwise the member is
  pointed at the Page Builder.
- Members can stop a running banner and get the unserved impressions back
  in their monthly balance. Counters are read before deactivation, since
  deactivating zeroes `remaining` and would look fully served.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 10:03:38 -05:00
martbost f7276589e9 Traffic Desk ships: signed NAS bridge client, monthly impression allowance by level (2.5k Scintilla -> 150k Corona), team-kit creative only (no member uploads = no moderation risk), local grant ledger, live serve stats; tile moved to L1 since credits are included at every paid level
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 09:50:03 -05:00
martbost 6c73b5d9c5 Page Builder fixes from Marty's test: our own CSP frame-src blocked framing our member pages (preview showed broken) — add 'self'; /p/<id> now sends explicit permissive framing headers so member pages always render embedded; button label tracks whether a page exists; live progress line with step narration + elapsed seconds; stale preview hidden during rebuild and cache-busted after
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 08:56:32 -05:00
martbost 44816571b6 Video Maker ships (L3): ffmpeg end-card composite over the team master videos (member name + link + server-generated QR as PPM), audio preserved, metered; ffmpeg+ttf-dejavu added to the image; tile live
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 08:37:59 -05:00
martbost 7c3e98eaa9 Email Engine ships (L3): sequence generation (welcome/follow-up/re-engagement/broadcast) on the Suite engine with tolerant EMAIL/SUBJECT/BODY parsing, per-email copy buttons, metered; tile live
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 08:17:24 -05:00
martbost 3c21f9f615 Payout alerts highlight unlocked tools: shared suite-tools level map drives the Telegram team feed, recruiting feed, member DM on upgrade, and X posts; only announces LIVE tiers and gated behind config.suiteToolsInAlerts (off until Suite launch)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 07:59:40 -05:00
martbost f7d5c3f358 Syndicated network display advertising language: homepage toolkit card, how-pay-works toolkit section, Suite Traffic Desk tile, AI prompt
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 07:36:30 -05:00
martbost 7f289bb495 Policies + tools angle: /privacy and /refunds pages (crypto payments are final, we never hold funds), footer links sitewide, toolkit section on How You Get Paid, toolkit line on Getting Started
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 07:32:51 -05:00
martbost 8fb585246c Route /p/<id> into the API handler — member pages are dynamic HTML and were falling through to the static 404
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 07:26:57 -05:00
martbost 6a7867588d Page Builder ships: labelled-section AI output parsed deterministically, escaped renderer, one page per position at public /p/<id> with angle video + QR, rebuild keeps the same URL; L2 tile live
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 07:15:11 -05:00
martbost 2a8b311a83 Copy Engine ships: Suite AI layer (own engine, RM facts + compliance in our system prompt, deterministic link injection), metered generate/meters APIs, /suite/copy tool page; L2 tile now live
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 06:51:16 -05:00
martbost 323c86b750 L6 tile: 'webinar rooms' -> Replay Funnels (evergreen registration page around a recorded team webinar, timed CTA); AI prompt clarifies it is NOT live conferencing
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 06:44:16 -05:00
martbost 35b3c07e74 Fix Suite org check: teamRootId is a comma-separated list, Number() made it NaN so every member read as outside the org (Marty hit this as #21); parse all roots + orgRootId fallback. Nav dedupe on /suite. Adds suite-meter module (per-position monthly quotas by level)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 06:33:08 -05:00
martbost 6f28e94abd Suite team-beta gate: config.suiteAllowlist restricts entitlements to listed IDs (others get an honest 'you're early' notice); homepage CTA + chatbot answer held until launch; AI prompt marked private-beta
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 05:22:50 -05:00
martbost 0258b82a16 Circle Suite P0: /suite tool wall — wallet sign-in (existing challenge/verify flow), live level entitlements via /api/public/suite-me (org-gated to teamRootId), all tiles always visible (yours / unlocks-at / in-development), L1 = today's real tools; homepage CTA + chatbot + AI prompt synced
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 05:19:09 -05:00
martbost 21e105b953 /generation-pay: printable generation-pay chart personalized from the live chain (level/tier/qualification -> catching vs needs-Level-N per generation); dashboard + how-pay-works links, chatbot + AI prompt synced; exact-costs card now states the exact one-catch identity
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 14:34:20 -05:00
martbost 30a5c7237e Training Video 7 'Your level is your reach' (97s, script Marty-approved): catch eligibility + reach rule + pass-over + one-catch funding identity; how-pay-works first-catch line tightened to exact; chatbot + AI prompt synced
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 13:23:08 -05:00
martbost 1029bdb3e2 Two hard-question objection cards from live member Q&A (catch-eligibility: level = reach; fixed counts vs quadrupling value) + chatbot + AI prompt synced
Both verified against contract source today (payout loop: level > levelIndex && 2 directs; one structural skip per depth).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 12:59:09 -05:00
martbost b76a590714 Correct #exact-costs: entry exists ONLY at Scintilla (register() has no level param; upgrade() one rung per call) — levels cannot be skipped; table now shows upgrade path + cumulative totals; AI prompt synced
Verified against the exact-match ABI on Sourcify: per-level entry rows on company charts are vestigial contract data with no callable path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 11:32:43 -05:00
martbost bdfb40667e Contract-exact price table (#exact-costs on how-pay-works) + entry-vs-upgrade objection card; chatbot + AI prompt synced
Live getAllCosts() numbers: entry 360.58 incl 5% (sponsor 326.24), upgrades double exactly per level, 100% member-to-member. Answers the 'why is entry different from upgrade / is the chart inflated' question with verifiable numbers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 11:08:07 -05:00
martbost 8858470244 stopwaiting angle: squeeze page on the lander (combined overview video) + handout QR now carries ?v=stopwaiting
The stop-waiting handout QR previously hit the plain join page with no angle continuation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 10:11:41 -05:00
martbost 7fb7a6c0d1 Remove tear-off full-page flyers; /flyers is now the five artwork handouts only
Marty: the tear-off designs did not look good next to the artwork handouts. Page renamed Printable Handouts; dashboard link, tools card/nav, chatbot answer, and AI prompt synced.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 09:25:17 -05:00
martbost 3761fab3c6 Half-sheet handouts on /flyers: 5 vibrant angle designs (pocket, two, phone, graveyard, stop-waiting), 2 per letter page with cut line, personalized QR + angle-matched links; chatbot + AI prompt + tools card synced
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 07:31:40 -05:00
martbost df5f94573e Printable flyers feature: 4 colorful personalized flyer designs with member QR + tear-off tabs for offline promotion; /flyers route, tools + dashboard links, chatbot + AI prompt synced 2026-08-26 16:55:50 -05:00
martbost 4b53dd5326 Direct link option: opt out of moving-link rotation to build personal spillover (Team link default, Direct link alternate) 2026-08-26 14:24:32 -05:00
martbost 6282e8c768 Triple Play: add the upgrade strategy (concentrate on the top position; pass-ups bubble up to it) 2026-08-26 08:13:33 -05:00
martbost 04a0ae1c6a Triple Play: correct the wallet guidance (separate addresses; MetaMask add-account switch gotcha -> already-registered) 2026-08-26 08:02:21 -05:00
martbost c3d28f17a8 The Triple Play: optional 3-position fast-start (how-pay-works section + objection card + chatbot + AI prompt) 2026-08-26 07:50:58 -05:00
martbost cffaf4ffc0 how-pay-works: Does it cap at 8 levels explainer (pass-ups bubble up; Corona catches all) + chatbot + AI prompt 2026-08-26 06:17:07 -05:00
martbost 1f5bcd688f how-pay-works: What each level opens up scaling table (illustration, not a promise) + dashboard link 2026-08-26 06:00:31 -05:00
martbost a413062c5c Config-driven wallet-connect notice (for the Blockaid false-positive window)
New shared wallet-notice.js on join-now, my, training: if config.walletNotice
is set, shows an admin-authored heads-up right above every connect/unlock
button; empty string hides it everywhere (one PATCH, no deploy). Placed at the
friction point only, not a sitewide banner, so unaffected wallets/Mini App
users are not told about a warning they will never see.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 18:40:32 -05:00
martbost aba3db2938 Doctrine sweep: your link never retires — the moving link auto-routes
Replaced every retire-your-link instruction (8 spots across index, join,
start, my, training FAQ, chat.js core-strategy + qualified + moving-link
answers, and the AI prompt) with the automated doctrine: after 2/2 the same
invite link self-routes each signup to the next position in the leg that
needs a direct; personal effort shifts to coaching your two. Raw-ID dApp
signups on a qualified position stay documented as the bonus path. Video
content already correct (Video 1 rebuild script fixed this framing before
recording; Method lesson scripts never said retire).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 06:48:32 -05:00
martbost afe7173680 Objections bank: the what-is-the-product + members-area answer
New card in the tools objection section: truth (name the product first;
business-in-a-box inventory; wallet-is-the-login members area) + the
ready-to-send casual reply (Lesson 1 free preview, verify-before-you-join
close). AI prompt tools inventory notes the objection bank.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 06:07:49 -05:00
martbost ca4b5bf34f Members area: Circle Method lessons 2-10 + Video 8 gated behind position ownership
The product now has a lid. Server refuses the gated video FILES without a
wallet-verified member session (the Mini App bridge session counts, so
Telegram members see no locks). Lesson 1, every poster, and all join-funnel
and transparency videos stay public: free preview + trust engine. Training
page renders locked cards with a one-signature unlock (same SIWE flow as
Messages) and a members-unlocked badge. Chatbot: new members-area canned
answer, Method answer notes the preview, AI prompt routing rule now answers
prospects directly instead of sending locked links; bot lesson command notes
the unlock path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 04:10:57 -05:00
martbost 76a9b449c9 Unlisted Friend Circle demo video + config-driven recruiting-feed CTA
friend-circle-290a3815db.mp4: Marty-only share URL, referenced from no page.
recruitMsg + its Get Started button now read config.recruitCtaUrl (new PATCH
key, default home page) so notification CTAs can point at a proof-first
landing like /my/21. Tweet CTA was already config-driven (value PATCHed).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 08:38:10 -05:00
martbost 86ed87510b Coach panel: one-tap Send-this-nudge buttons on every recommendation
Each coach card now carries a pre-written, situation-specific teach-forward
message (all four recommendation kinds) sent over the existing wallet-verified
Messages rails: msg-send plus the Telegram bridge. When not signed in, an
inline prompt appears and the page smooth-scrolls to the Messages card.
Chatbot canned answer and AI prompt synced.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 07:20:23 -05:00
martbost a0642516e1 My Dashboard nav shortcut + analytics whitelist fix for engaged/ctb-offer
nav-dash.js on all header pages: a top-right My Dashboard button when the
visitor is known (msg session from wallet sign-in or the Mini App bridge is
authoritative; else the last dashboard opened on the device). Prospects with
no identity never see it.
recordEvent was silently dropping the new engaged + ctb-offer-* events
(whitelist); now recorded per source, with admin funnel tiles for both.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 07:10:52 -05:00
martbost c5e2c30ff3 CTB featured-offer relay: 30s visible-dwell engaged event -> signed postback
track.js: on join pages with a ctb1_ clickid, count 30s of VISIBLE time (1s
ticks, pauses when tab hidden), then report engaged once per session.
server.js: relay engaged ctb1_ clickids to the CTB backend per the spec
contract (X-Offer-Secret header, any-200-is-done); light in-process dedupe.
New volume config keys ctbOfferPostbackUrl + ctbOfferSecret (PATCH allowlist).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-23 08:10:29 -05:00
martbost 7182746883 Tools: Text-a-friend section (SMS + WhatsApp + messenger share, per angle)
5 SMS-sized low-pressure messages (general moving link + one per angle video,
each carrying the matching ?v= landing link) with one-tap launchers: sms: body
pre-fill, wa.me text pre-fill, t.me/share with the member''s Mini App invite
(angle-matched), Copy for Messenger/IG. Hrefs rebuilt on personalization.
Chatbot canned answer + AI prompt synced.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-23 07:46:36 -05:00
martbost b8fd3a8bbf Telegram group-ad banner (1280x720) added to the banner kit
Brand-matched (navy gradient, gold RM ring, paper-plane watermark), reusable
by any member: no baked-in link, CTA points to the link below the image.
First cell in the tools-page banner grid; AI prompt synced. Generator HTML
kept at D:\tmp\banner-telegram-generator.html.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-23 07:35:39 -05:00
martbost 131fa8ae2a Tools: Promote-on-Telegram section (Mini App links, posts, team setup swipe)
/tools#telegram: the member's t.me/RMCircleBot/join?startapp=YOURID links
(moving + 4 angles, self-preview tip), a paste-ready group post and warm DM,
and the connect-your-team setup message to forward (teach-forward). tools.js
personalize() now also fills YOURID tokens. Chatbot canned answer + AI prompt
synced.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-23 07:22:00 -05:00
martbost 826f779bc0 Training Video 8: real e-gift-card cash-out walkthrough (8 min)
Marty's screen recording: POL -> CWallet -> dollar swap -> gift card, with the
Google Wallet tap-to-pay screenshot as the end-result proof under the player.
Encoded CRF23 + loudnorm (235MB -> 24MB). Cross-linked from the #spending
guide; chat.js cash-out answer + AI prompt synced (7 -> 8 how-to videos).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-23 07:03:10 -05:00
martbost f876351391 Mini App join funnel: startapp sponsor attribution + wallet-app handoff
- /app decodes startapp=<sponsorId>[_<angle>] -> unlinked visitors land on the
  sponsor squeeze page /join/<ref>?src=miniapp (linked members still go to
  their dashboard); no-invite prospects get a gold Join button -> /join-now
- tg-app.js: sync __rmcInTg flag; external links route out of the webview via
  openLink/openTelegramLink (wallet deep links reach the wallet app reliably)
- join-now.js in the webview leads with the MetaMask/Trust deep links (no
  injected wallet can exist there); ref + src survive into the wallet browser
- tgbot: links command + weekly digest include the t.me/<bot>/<short>?startapp
  Telegram-native invite once config.miniAppShortName is set (new PATCH key)
- Synced chat.js canned answer + AI prompt (prospects can join from the app)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-23 06:32:51 -05:00
martbost cd361a1eaa Telegram Mini App v1: initData auth bridge into the existing site
- POST /api/public/tg-webapp-auth: HMAC-verifies WebApp initData against the
  companion bot token (12h freshness, timing-safe), maps chat -> member via
  tg-links.json, mints a message session -> linked members land on /my/<id>
  with zero login
- /app entry page (vendored telegram-web-app.js keeps CSP script-src 'self');
  unlinked users get the one-time wallet-link instructions
- tg-app.js on all pages: no-op in browsers; inside the webview lazy-loads the
  SDK, expands, themes header/background #071421, wires native BackButton
- Bot menu button set programmatically to open /app; /start + help mention it
- Synced chat.js canned answer + AI system prompt (Mini App facts)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-23 05:56:51 -05:00
martbost 1f95025587 Companion bot requires its own dedicated token (companionBotToken) - never the shared CTBRewards_Bot token; allowlist the new config key 2026-08-22 19:42:58 -05:00
martbost 6ac1bcab55 Telegram companion bot, phase 1
New tgbot.js (raw Bot API, zero deps, private-chats only so the
group feeds are untouched): wallet-verified linking via dashboard
deep-link codes, personal payout + joined-on-your-link DMs, a
message bridge that delivers site messages natively in Telegram
with reply-to-answer routing (matrix-line permissions enforced by
the existing messages.js rules), and links/msg/help commands.
Webhook self-registers; secret derived from the token. Config key
companionBotToken overrides the feed bot token when Marty creates
a dedicated bot. Dashboard Messages panel gains Connect Telegram;
chatbot + AI prompt synced.
2026-08-22 19:39:55 -05:00
martbost 0562579a56 og:url keeps the ?v= angle - Facebook was canonicalizing every variant back to the cached plain URL 2026-08-22 12:09:25 -05:00
martbost 1dc60e8c4c Angle OG override in serveMemberPage (the real join-page server); remove dead first attempt 2026-08-22 12:01:00 -05:00