# Profectus — Public Launch Roadmap

Companion to the Magnus Profectus app (repo `/home/rpi/projects/rp-tracker`). Target: worldwide launch, privacy-first, anonymous registration possible, conventional + crypto payments (Mullvad-style). Nothing here is executed automatically; every step waits for explicit go.

## Name conflict finding (verified 2026-10-05)

Strike First Nutrition (Natural Life Foods Corp., Pleasant Hill CA, founded 2001) sells "Magnus Profectus(TM)" as an UNREGISTERED nitric-oxide supplement since at least 2016-01-19 (archive.org), currently out of stock, near-zero brand footprint. No registration for the exact name anywhere: USPTO 0 hits, WIPO BrandDB exact 0, Swissreg 0. Their house mark STRIKE FIRST NUTRITION (US reg 85865745, class 5) does not cover it. Risk: LOW legal (dissimilar goods: supplement vs software; unregistered opponent must prove secondary meaning), MODERATE practical (identical name + shared gym audience in the US; possible C&D / app-store dispute / SEO collision with their 2016 product page). The stronger known conflict remains PROFECTUS GmbH (DE) EUTM classes 9/42.
Actions chosen: proceed with the name; file defensive registrations for MAGNUS PROFECTUS in classes 9+42 (consider 35/41) in CH, EU, US (+Madrid) BEFORE launch; keep dated evidence of our first use; secure magnusprofectus domains/handles; optional courtesy coexistence letter to Natural Life Foods Corp. (2638 Pleasant Hill Rd, Pleasant Hill CA 94523) — weigh alerting them vs paper-trail value. Renaming not warranted on current evidence. EUIPO-native TMview check was not programmatically drivable; EU coverage verified via WIPO BrandDB (indexes TMview).

## 0. Decisions to lock (you)

| Decision | Recommendation | Why |
|---|---|---|
| Hosting path | Hetzner VPS (CX22), lift-and-shift | Cheapest capable option, zero code changes, scales far beyond launch needs; Supabase migration stays open for later |
| Primary domain | profectus.fit | Short, thematic, international; magnusprofectus.ch as defensive alias |
| Registration legal form at launch | Start private (sole proprietorship once commercial register / VAT relevant); formalize entity when revenue justifies | Product can launch before entity; keep invoices/taxes clean from first sale |
| Payments: conventional | Merchant-of-record (Paddle or Lemon Squeezy) over raw Stripe | MoR handles worldwide VAT/sales tax for you, which a solo worldwide launch otherwise makes painful |
| Payments: crypto | BTCPay Server, self-hosted on the same VPS | No third party, no fees, funds go straight to your wallet, best privacy story (Mullvad model) |
| Data location | Germany (Hetzner FSN/NBY) initially | EU adequacy covers Swiss requirements; "Swiss" is a marketing option, not a legal need |

## 1. Phase 1 — Identity & infrastructure

**Your side**
1. Create a dedicated account set for the product (email like `contact@...` via a provider you control; not tied to firm infrastructure).
2. Register `profectus.fit` (and `magnusprofectus.ch` if free) at a registrar such as Infomaniak or Namecheap. Enable registrar lock + auto-renew. ~20 + 13 CHF/yr.
3. Open a Hetzner account, create the VPS (CX22, Ubuntu LTS), add your SSH key. ~4.50 CHF/mo.
4. Create an object-storage bucket (Hetzner Storage Box or S3-compatible) for backups. ~1 CHF/mo.

**My side**
5. Harden the VPS (user login only, SSH key-only, firewall, fail2ban, unattended-upgrades), install Caddy for automatic TLS, migrate the current stack (Node service + SQLite) from the Pi, DNS: A record `profectus.fit` + www + apex redirect.
6. Set up automated nightly encrypted SQLite backups to the bucket + a restore drill, and a Pi-side cron uptime ping with alerting.

## 2. Phase 2 — Privacy & GDPR/revDSG compliance (build for worldwide from day one)

Because you offer the service to EU users at launch, GDPR applies extraterritorially (Art. 3(2)) alongside the Swiss revDSG. The good news: the app's architecture is already privacy-friendly (no ads, no analytics, no third-party trackers, offline-first). Compliance is mostly documentation + discipline, not re-engineering.

**My side**
7. Data inventory ("Record of Processing Activities"): what we store (username, bcrypt-hashed password, workout logs, settings), where, retention, no email required for signup, no IP logging beyond Caddy defaults, no cookies beyond the session cookie.
8. Draft privacy policy + terms of service (plain language, EN + DE), covering: controller identity, purposes, legal bases, data location, third parties (host, payment MoR), retention, user rights, contact.
9. Technical erasure: "delete my account" button that hard-deletes all rows server-side (extension of the existing deletion path); export feature (JSON download of all user rows) for data portability.
10. Sign Hetzner's order-data-processing agreement (DPA, free, in their console); list the MoR as processor for payment data.
11. Security memo: TLS everywhere, hashed passwords (scrypt), no sensitive data beyond workout logs, backup encryption, breach-response checklist (72h notification duty).
12. Cookieless by design: no consent banner needed since no tracking cookies exist. Keep it that way; any future analytics must be self-hosted and cookieless.

**Your side**
13. Review and approve policy drafts; you are the controller, so the named contact must be you (or later the company).
14. Optional but recommended before charging money: one-time lawyer pass over T&Cs/privacy (Swiss digital-law-savvy, ~1–2k CHF). Not a blocker for a friends-and-family launch; required in spirit once money changes hands at scale.

## 3. Phase 3 — Accounts & payments (after Phase 1–2)

**My side**
15. Anonymous-first registration: keep current username-only signup as the default path; email becomes optional (for receipts/password reset only). No email = less data = stronger privacy story; document the trade-off (no account recovery without email).
16. Wire the MoR checkout (subscription or one-time, MoR provides hosted payment page, handles VAT, invoices, refunds). You never touch card data.
17. BTCPay Server on the VPS, on-chain BTC + Lightning; invoices auto-confirmed → entitlement granted. No customer KYC, no chargebacks, no processor fees. Delete invoice metadata after settlement (Mullvad-style: don't retain payment identifiers; and if you later want "no logs at all", consider deleting accounts after N years of inactivity, like Mullvad does).
18. Entitlement logic in the app: free tier (current full app for friends) vs paid tier (whatever you decide: everything free today is fine — payments can be switched on later without schema change if we keep a `plan` field from the start).

**Your side**
19. Decide pricing (one-time, yearly, monthly) — recommendation: single yearly price, simple.
20. Create MoR + BTCPay wallet setup; secure the wallet seed offline.
21. Confirm you accept the risk trade-offs of crypto: irreversible payments (no chargeback fraud, but no chargeback protection either), refund policy must state crypto refunds only in exceptional cases.

## 4. Crypto payments — regulatory read (Switzerland)

Short version: accepting crypto as payment for your own product does **not** by itself make you a regulated financial intermediary under FINMA's AMLA. The triggers would be: exchanging crypto for customers as a service, holding customer funds in custody, or accepting deposits (i.e., acting like a money transmitter/exchange). Selling your own subscriptions and receiving BTC/Lightning payments to your own wallet is a plain sale of goods/services — the same as Mullvad operates. Three cautions:

- Use BTCPay self-custody (funds go straight to your wallet, nothing custodial) rather than a custodial processor that might push you toward intermediary classification.
- Convert to CHF at your bank/broker as you wish; your bank may ask about incoming crypto-origin funds — keep the BTCPay invoice records as the audit trail.
- When the company exists, check whether your bank's onboarding questionnaire requires declaring crypto acceptance. This is paperwork, not a license issue.

None of this adds FINMA licensing complexity for the fitness product. Keep it strictly separate from the asset-management track (no cross-marketing, no shared branding if a regulator could ever see it as one venture).

## 5. Phase 4 — Launch checklist

22. Content pass: guide + articles worldwide-ready (no Swiss-specific claims in the product).
23. Soft launch to friends on the public URL; watch Caddy logs + error surface.
24. Public launch: post where your audience is; keep the Pi as staging.

## 6. "Swiss" in marketing — where it helps

Worldwide launch means no Swiss claims in the product itself. Legitimate, honest use of the Swiss angle: founder bio ("built in Switzerland"), imprint/contact page (Swiss controller), and if you ever move hosting to a Swiss DC (Hosttech/Nine, ~2–4x cost), "data hosted in Switzerland" becomes a real claim. Avoid "Swiss privacy" marketing until hosting matches it.

## 7. Expected costs

**Initial (one-time)**

| Item | Cost |
|---|---|
| profectus.fit, 1 yr | ~20 CHF |
| magnusprofectus.ch, 1 yr (optional) | ~13 CHF |
| Optional lawyer pass on policies | 0–2,000 CHF |
| **Total (without lawyer)** | **~33 CHF** |

**Running (monthly)**

| Item | Cost |
|---|---|
| Hetzner VPS CX22 | ~4.50 CHF |
| Backups storage | ~1 CHF |
| Domain amortized | ~3 CHF |
| Email (transactional, free tier until volume) | 0 CHF |
| BTCPay | 0 CHF (self-hosted, no fees) |
| MoR fees (only when selling) | ~5% + fixed fee per sale |
| **Total before any revenue** | **~8–9 CHF/mo** |

Compare: Supabase paid tier alone is 25 CHF/mo with less control.

## 8. Explicitly deferred

- Supabase migration (revisit if you want managed scale or the app grows past a single VPS).
- Email announcement feature for default-program updates (needs the transactional email setup, Phase 3+).
- Native mobile apps (PWA installability is already shipped).
- Company formation, VAT registration (only once revenue threshold/logic warrants).

## 9. Revised roadmap after monetization decision (2026-10-05, OSS + donations + paid sync)

Supersedes Phase 3's license/payment wiring. Order matters: name first, code publication before hosted launch. Steps marked [USER] require the user's accounts/decisions; [AGENT] is executed by the agent. Nothing runs without explicit go per step.

### Step 0 — Name settlement [USER, gates everything]
Decision pending (2026-10-05 finding): the bare word "Profectus" is heavily crowded — Profectus Inc (Sarasota, B2B printing/packaging software), Profectus.ai (retail algo-trading platform), Profectus Group (rebate software, acquired by Enable), Profectus Solutions (NY data platform), Profectus Technologies (dev shop), Profectus GmbH Suhl (electronics EMS, acquired by Cicor 2025), profectus-beratung GmbH, Profectus Biosciences, plus the Strike First Nutrition supplement. NONE is fitness; the full phrase "Magnus Profectus" remains clean (supplement only). Options:
  (a) KEEP "Magnus Profectus" as the brand, drop the bare short name from user-facing copy (use the full name or "the Profectus team" voice only in editorial), GitHub org handle = magnusprofectus, domains as planned. Cheapest, no rename cost, collision exposure minimal.
  (b) RENAME entirely. Technically cheap (single source APP_NAME in src/config/app.ts, guide tokens) but wastes established brand, requires new domains/handles/articles sweep.
  DECIDED 2026-10-05 (user, after reviewing the coinage round): KEEP MAGNUS PROFECTUS (Option A). Full name is the brand everywhere user-facing; brand-layer handles = magnusprofectus (GitHub org, domains as planned: profectus.fit + magnusprofectus.ch). The home-screen icon label may keep the organic shorthand "Profectus" (an abbreviation of the full name, not a standalone brand); no standalone use of bare "Profectus" in branding, repo names, or marketing. The Strevex coinage is shelved, not abandoned (search round recorded above).

  Coinage search round 2 (2026-10-05, Option B executed): 15+ candidates burned. Killed: Attollo (live USPTO class 9 mark + 4 companies), Krevus (2025 tech co), Tensiva (health nutraceutical), Anapausis (PENDING USPTO class 9/42 health app — the network clause namesake), Provalt (French company w/ web+mobile service), Profecta (3 companies), Vixora (3 companies), Zeltra (2 + app store), Ostrev (GitHub org taken; domains free), Anvex (anvex.com/.io taken). SURVIVOR: **STREVEX** — zero web footprint beyond a Spore game username; note phonetic neighbor Sterivex (Merck lab filter, different class); VERIFIED AVAILABLE: strevex.com/.fit/.app/.io all resolve nothing, github.com/strevex = 404 (free). Sound: STREH-veks, evokes strenuus (vigor) + strength; pronounceable EN/DE. Pre-launch checklist if adopted: Swissreg + EUIPO/TMview formal check, app-store search, secure domains + org + Ko-fi/Liberapay handles same day. Robur = two existing workout-log apps (robur-app.com "The Workout Log for Serious Lifters", Robur Gym logbook); LastRep = fitness apparel brand (lastrep.co) + gym social app + $15.6M THC-beverage brand; Fortius = club-management software (fortius-app.com); Strenua = fitness AI workout app (strenua.pro) + coaching + consultancy; Profect = Japanese ERP maker + real-estate app; Tensus = Tampa IT integrator + Russian drone startup + Tensus 1200 blood-pressure monitor (health device, Chilean registered mark) — user's "sounds familiar" instinct was correct; Auxano/Auxen = existing fitness app (Auxano Flow) / music app + pharma mark; Kresko = 3 companies (software consultancy, RNA biotech, AI agency); Intensus = scattered non-fitness (Geneva restaurant, NL software shop, engineering JV). CONCLUSION: any 2-3 syllable Latin/Greek-flavored word is effectively guaranteed mined. Remaining viable paths: (1) keep MAGNUS PROFECTUS as the full brand everywhere, accept organic shorthand ("Profectus") in speech — legal exposure stays low because no FITNESS-sector holder exists and our registered mark (Step 10) is the full name; (2) commission a genuinely unique coinage with a full verification pass per candidate (Swissreg/EUIPO/USPTO quick checks + GitHub org + domain + app-store search) — expect to burn several candidates; (3) different brand family entirely (user rejected). User leaning: shorter name wanted; decision still OPEN.

### Step 1 — Brand identity & accounts [USER]
1. Decide Step 0. 2. Create the brand GitHub org (handle per Step 0), brand email (contact@profectus.fit once domain is registered; interim: any provider you control, not tied to firm infrastructure). 3. Register profectus.fit + magnusprofectus.ch (Infomaniak/Namecheap, registrar lock, auto-renew, WHOIS privacy). 4. Check handle availability: github org, Ko-fi, Liberapay. 5. Prepare imprint decision: real name + address (home or c/o) for the one legal page.

### Step 2 — Open-source publication [AGENT] — DONE 2026-10-05
Repo live: github.com/magnusprofectus/magnus-profectus (public, AGPL-3.0 detected, topics set, description set, homepage profectus.fit). 3 commits on main, authored as "Magnus Profectus" <magnusprofectus@users.noreply.github.com>. Pre-push sweep completed: em dashes scrubbed from comments/docs/UI strings, banned word "honest" removed from 4 articles, leak-grep clean (no secrets, no Pi paths, no personal details; DECISIONS.md + ARTICLES-GUIDE.md excluded via .git/info/exclude). v1 offline-first gating shipped in the same push: auth screen opt-in only (never on boot), Account card only when a server is reachable/logged in, configurable sync-server URL (localStorage, README self-host flow), local backups feature (Settings card: after-each-workout toggle + save-now; APK writes Documents dir keep-10, PWA downloads; maybeAutosave() after finishSession; @capacitor/core + @capacitor/filesystem added). Verified: build green, 18/18 tests, browser E2E (no auth gate, cards render, toggle persists in IDB, backup download works, URL config persists). Note: dev deps vanish under NODE_ENV=production + npm omit=dev (use npm install --include=dev). gh CLI installed (Debian 2.46), auth done by user via keyring, token never passed through the agent.
1. ~~Repo hygiene pass~~ (done, see above) 2. ~~LICENSE AGPL-3.0~~ (done) 3. ~~README~~ (done) 4. ~~First public push~~ (done) 5. GitHub Actions: build on push (APK build workflow added at Step 6).

### Step 3 — Donations live [USER + AGENT]
[USER] Create GitHub Sponsors (identity verified by GitHub, not public), Ko-fi and/or Liberapay under the brand handle. [AGENT] Wire donation links: website footer/landing + one quiet line in the app (OSS conventions, no nag).

### Step 4 — VPS + hosted service [USER + AGENT] — DEFERRABLE
The VPS is needed only when HOSTED SYNC launches (paid tier). If the first release ships offline-only + donations, GitHub Pages suffices for everything public: repo, docs/landing, donation links (explicitly permitted by GitHub ToS), and even serving the PWA itself (the Pages SaaS/commerce bar is not triggered while nothing is sold; donations are carved out). Limits are fine (100 GB/mo soft bandwidth, 1 GB site). Internal test-phase sync keeps running on the Pi (Tailscale-only, not public). The custom domain can be pointed at Pages via CNAME when registered. Defer Step 4-5-9 until the sync subscription decision materializes; bring the legal layer (Step 5) forward though — the imprint/privacy page should exist as soon as the public site collects registrations (currently none; needed at latest with hosted sync).

GitHub-first progression Q&A (2026-10-05, decided):
- Legal page at offline-only stage: NOT required. A fully offline app collects no personal data (no GDPR trigger); the Pages site is static, cookieless, trackerless (no processing = no privacy policy duty); donations are not sales (UWG imprint tied to commercial selling — gray at worst, and the payment platforms carry their own terms). Add imprint+privacy at the LATEST when hosted sync/registration launches (Step 5), earlier if F-Droid or Play listing asks. Do keep the AGPL license + copyright notices in the repo.
- Android APK storage: app-private storage (WebView IndexedDB / SQLite), persistent for the app's lifetime, NOT subject to Safari-style eviction (that risk is iOS-PWA-specific). Loss vectors are uninstall, "clear data", or device loss — mitigated by manual export now and SAF folder backups (Step 6).
- Domain-poaching risk: near zero. Squatters watch resell-value names, not GitHub launches of niche .fit names; nobody scrapes new repos for domains. Domains (~33 CHF/yr) remain cheap brand insurance and enable the Pages CNAME; buying at Step 1 is recommended but deferring is defensible.
- Verdict on the progression: ADVISED FOR, not against. Zero running cost until traction, real adoption signal before infrastructure spend, OSS credibility from day one. Managed risks: (1) data loss without sync → export + folder backups shipped early; (2) "where is sync/iOS?" feedback → roadmap answer, and paid hosted sync later does not contradict anything since sync was never promised and selling the service (not features) is the ratified model; (3) later migration from Pages to VPS when sync launches — small, planned; (4) sideload friction for non-technical users → Obtainium instructions now, F-Droid submission later, Play only if reach demands.
[USER] Open Hetzner account, create CX22, add SSH key. [AGENT] Harden (SSH key-only, firewall, fail2ban, unattended-upgrades), Caddy + TLS, migrate Node service + SQLite from Pi, DNS profectus.fit (+www), nightly encrypted backups + restore drill, uptime ping. Server URL configurable in-app (default profectus.fit, any instance accepted) — this is the F-Droid-policy requirement.

### Step 5 — Legal layer [AGENT drafts, USER approves]
Privacy policy + T&Cs + imprint (EN + DE), controller = user, data location Germany; delete-my-account hard-delete; JSON export (exists). Optional lawyer pass before charging money.

### Step 6 — Android APK + backups [AGENT] — DONE 2026-10-07 (first signed build live)
Capacitor 8 scaffold committed (appId com.magnusprofectus.app, name "Magnus Profectus", webDir dist; @capacitor/core+cli+android+filesystem deps). CI: .github/workflows/build-apk.yml (push to main + dispatch) builds signed release APK on ubuntu runner: npm ci --include=dev → build (no PAGES_BASE, native base /) → cap sync android → decode ANDROID_KEYSTORE_B64 secret → gradle assembleRelease (signingConfig release via env, debug fallback if keystore absent) → upload artifact + publish to "latest" release as magnus-profectus.apk. Java 21 required (Capacitor 8; Java 17 fails with "invalid source release: 21"). Keystore: /home/rpi/projects/keystore/ (magnus-profectus.keystore, alias magnusprofectus, password in keystore-password.txt, OUTSIDE the repo; backup-worthy — losing it breaks all future updates). Secrets on repo: ANDROID_KEYSTORE_B64, ANDROID_KEYSTORE_PASSWORD, ANDROID_KEY_ALIAS (needed fine-grained token Secrets:RW + Actions:RW from user). Verified: green run 37685663547, validateSigningRelease passed, APK 3.4 MB at release "latest". NOTE: keytool -printcert -jarfile shows "not a signed jar" on v2-signature-only APKs, not an error. Local backup feature shipped earlier (Settings card, maybeAutosave after finishSession); restore-from-backup detection (empty store + APK → offer newest backup from Documents, one-tap confirm) still TODO. App icon is still the Capacitor default; replace before wide launch.

### Step 7 — Distribution [AGENT]
GitHub releases APK; Obtainium works immediately; F-Droid metadata (official builders vs compliant self-run repo — decide then; interim is fine). Anti-feature disclosure: none expected (FOSS server + configurable URL), paid tier disclosed in listing text.

### Step 8 — Soft launch [USER]
Friends/family on public URL; watch logs; gather testimonials. Then launch listings (Show HN, Product Hunt, r/SideProject) with the OSS/privacy angle.

### Step 9 — Paid sync subscription [USER + AGENT, only after soft launch]
[USER] Apply for Paddle product approval early. [AGENT] Entitlement flips server-side (no license keys, no in-app purchase anywhere), pricing page on profectus.fit, ~15-25 CHF/yr, cancellation keeps data exportable. BTCPay optional same phase.

### Step 10 — Defensive trademarks [USER, BEFORE wide launch]
File MAGNUS PROFECTUS classes 9+42 (consider 35/41) CH/EU/US (+Madrid). Cost estimate at filing time. Keep dated first-use evidence.

### Step 11 — Later
Desktop analytics layers (only after sync is solid); iOS PWA polish (A2HS prompt, storage-eviction nudge toward sync); App Store only if reach demands (donation link stays on website); community bot cadence; Health-platform scope.

Kill criteria standing: hosted costs >3x donation+subscription income for two consecutive quarters while users grow → re-open monetization.

