max / makenotwork
78 files changed,
+1437 insertions,
-1516 deletions
| @@ -26,7 +26,7 @@ Fair creator platform with 0% platform fee (only Stripe's ~3% processing fee). M | |||
| 26 | 26 | - **Basic** — $10/mo (text, all base features) | |
| 27 | 27 | - **Small Files** — $20/mo (audio, software, plugins, small downloads) | |
| 28 | 28 | - **Big Files** — $30/mo (video, courses, large downloads) | |
| 29 | - | - **Streaming** — $40/mo (live streaming + everything above) | |
| 29 | + | - **Everything** — $40/mo (all features, current and future) | |
| 30 | 30 | ||
| 31 | 31 | ## Ecosystem | |
| 32 | 32 |
| @@ -24,7 +24,7 @@ pub fn format_tier(tier: &str) -> &str { | |||
| 24 | 24 | "basic" => "Basic", | |
| 25 | 25 | "small_files" => "Small Files", | |
| 26 | 26 | "big_files" => "Big Files", | |
| 27 | - | "streaming" => "Streaming", | |
| 27 | + | "everything" => "Everything", | |
| 28 | 28 | _ => tier, | |
| 29 | 29 | } | |
| 30 | 30 | } | |
| @@ -93,7 +93,7 @@ mod tests { | |||
| 93 | 93 | fn format_tier_known() { | |
| 94 | 94 | assert_eq!(format_tier("basic"), "Basic"); | |
| 95 | 95 | assert_eq!(format_tier("small_files"), "Small Files"); | |
| 96 | - | assert_eq!(format_tier("streaming"), "Streaming"); | |
| 96 | + | assert_eq!(format_tier("everything"), "Everything"); | |
| 97 | 97 | } | |
| 98 | 98 | ||
| 99 | 99 | #[test] |
| @@ -3385,7 +3385,7 @@ dependencies = [ | |||
| 3385 | 3385 | ||
| 3386 | 3386 | [[package]] | |
| 3387 | 3387 | name = "makenotwork" | |
| 3388 | - | version = "0.4.2" | |
| 3388 | + | version = "0.4.3" | |
| 3389 | 3389 | dependencies = [ | |
| 3390 | 3390 | "anyhow", | |
| 3391 | 3391 | "argon2", |
| @@ -163,7 +163,7 @@ Stripe Connect Express for creator payouts. Creators connect their Stripe accoun | |||
| 163 | 163 | ||
| 164 | 164 | - Checkout sessions for one-time purchases and subscriptions | |
| 165 | 165 | - Webhook handlers for payment confirmation, subscription lifecycle, disputes | |
| 166 | - | - Creator tier subscriptions (Basic $10, Small Files $20, Big Files $30, Streaming $40) | |
| 166 | + | - Creator tier subscriptions (Basic $10, Small Files $20, Big Files $30, Everything $40) | |
| 167 | 167 | - Fan+ consumer subscriptions ($8/mo) | |
| 168 | 168 | - Promo codes (percentage/fixed discount, free access) | |
| 169 | 169 |
| @@ -6,7 +6,7 @@ Reference for MNW's ingest pipeline. Defines which formats can be safely convert | |||
| 6 | 6 | ||
| 7 | 7 | ## Design Principle | |
| 8 | 8 | ||
| 9 | - | - **BigFiles / Streaming tiers**: Store original file. Lossless preservation is the feature. | |
| 9 | + | - **BigFiles / Everything tiers**: Store original file. Lossless preservation is the feature. | |
| 10 | 10 | - **SmallFiles tier**: Store a high-quality transparent encode. Humans can't tell the difference. | |
| 11 | 11 | - Originals are always kept for BigFiles+. SmallFiles stores only the optimized version. | |
| 12 | 12 | - Never transcode lossy-to-lossy. Never transcode lossy-to-lossless (wastes space, no quality gain). | |
| @@ -57,7 +57,7 @@ Source format on the left, target on the top. Each cell describes what happens. | |||
| 57 | 57 | ``` | |
| 58 | 58 | Is the source lossless (WAV/AIFF/FLAC/ALAC)? | |
| 59 | 59 | YES: | |
| 60 | - | Tier = BigFiles/Streaming? | |
| 60 | + | Tier = BigFiles/Everything? | |
| 61 | 61 | -> Store as FLAC (lossless, ~50% smaller than WAV/AIFF) | |
| 62 | 62 | -> Keep original alongside if WAV/AIFF (creator can re-download) | |
| 63 | 63 | Tier = SmallFiles? | |
| @@ -116,7 +116,7 @@ Note: "AVOID" means technically possible but always degrades quality. "NEVER" me | |||
| 116 | 116 | ``` | |
| 117 | 117 | Is the source lossless/production (ProRes, uncompressed)? | |
| 118 | 118 | YES: | |
| 119 | - | Tier = BigFiles/Streaming? | |
| 119 | + | Tier = BigFiles/Everything? | |
| 120 | 120 | -> Re-encode to H.264 CRF 18 in MP4 (universal playback) | |
| 121 | 121 | -> Optionally also generate VP9/AV1 for web streaming | |
| 122 | 122 | -> Keep original? Only if tier storage allows it | |
| @@ -170,7 +170,7 @@ Fan downloads: the stored version (transparent quality). | |||
| 170 | 170 | ||
| 171 | 171 | Fan downloads: choice of original lossless or delivery format. | |
| 172 | 172 | ||
| 173 | - | ### Streaming ($40/mo) — "Lossless + adaptive streaming" | |
| 173 | + | ### Everything ($40/mo) — "Lossless + adaptive streaming" | |
| 174 | 174 | ||
| 175 | 175 | Same as BigFiles, plus: | |
| 176 | 176 | - Multiple quality tiers generated for adaptive streaming (HLS/DASH) |
| @@ -11,7 +11,7 @@ We have one revenue source: creator subscriptions. | |||
| 11 | 11 | | Basic | $10 | Written content hosting, delivery | | |
| 12 | 12 | | Small Files | $20 | Audio, software, plugins, small downloads | | |
| 13 | 13 | | Big Files | $30 | Video hosting, transcoding, large downloads | | |
| 14 | - | | Streaming | $40 | Live streaming infrastructure | | |
| 14 | + | | Everything | $40 | All features, current and future | | |
| 15 | 15 | ||
| 16 | 16 | That's it. No premium tiers. No "pro" features locked behind higher prices. No percentage of your earnings. | |
| 17 | 17 | ||
| @@ -76,7 +76,7 @@ See [tech_costs.md](../strategy/tech_costs.md) for line-item detail within each | |||
| 76 | 76 | | Basic | $10 | $0.85--1.90 | $8.10--9.15 | ~$2.28 | $5.82--6.87 | | |
| 77 | 77 | | Small Files | $20 | $1.90--3.80 | $16.20--18.10 | ~$2.30 | $13.90--15.80 | | |
| 78 | 78 | | Big Files | $30 | $3.60--8.60 | $21.40--26.40 | ~$2.33 | $19.07--24.07 | | |
| 79 | - | | Streaming | $40 | $5.00--9.70 | $30.30--35.00 | ~$2.35 | $27.95--32.65 | | |
| 79 | + | | Everything | $40 | $5.00--9.70 | $30.30--35.00 | ~$2.35 | $27.95--32.65 | | |
| 80 | 80 | ||
| 81 | 81 | Stripe Connect (Express accounts): $2/active account/mo + 0.25% of payout volume + $0.25/payout. Per-tier estimates assume one monthly payout with subscription price as floor proxy for payout volume — actual costs scale with creator earnings. | |
| 82 | 82 |
| @@ -43,7 +43,7 @@ Source: `docs/internal/business/economics.md`, `docs/internal/strategy/tech_cost | |||
| 43 | 43 | | Basic | $10 | $0.85-1.90 | $8.10-9.15 | ~$2.28 | **$5.82-6.87** | | |
| 44 | 44 | | Small Files | $20 | $1.90-3.80 | $16.20-18.10 | ~$2.30 | **$13.90-15.80** | | |
| 45 | 45 | | Big Files | $30 | $3.60-8.60 | $21.40-26.40 | ~$2.33 | **$19.07-24.07** | | |
| 46 | - | | Streaming | $40 | $5.00-9.70 | $30.30-35.00 | ~$2.35 | **$27.95-32.65** | | |
| 46 | + | | Everything | $40 | $5.00-9.70 | $30.30-35.00 | ~$2.35 | **$27.95-32.65** | | |
| 47 | 47 | ||
| 48 | 48 | **Stripe Connect** (Express accounts): $2/active account/mo + 0.25% of payout volume + $0.25/payout. Per-tier estimates assume 1 payout/month with subscription price as floor proxy for payout volume. Actual Stripe Connect costs scale with creator earnings — these are floor estimates. | |
| 49 | 49 |
| @@ -0,0 +1,194 @@ | |||
| 1 | + | # Legal & Tax Review Prep | |
| 2 | + | ||
| 3 | + | Prep document for professional review of Makenot.work legal docs. Goal: maximize value from billable hours by doing all homework first. | |
| 4 | + | ||
| 5 | + | **Platform summary:** Creator marketplace (music, software, writing, video). Creators pay $10-40/month subscription. Fans pay creators directly via Stripe Connect (Direct Charges). 0% platform fee. Make Creative, LLC (Colorado). One-person operation. Pre-launch (private alpha). | |
| 6 | + | ||
| 7 | + | **Payment model:** Stripe Connect Express. Creators are merchant of record. Fan payments go directly to creator's connected Stripe account. Platform never touches fan revenue. Platform revenue comes solely from creator subscriptions. | |
| 8 | + | ||
| 9 | + | --- | |
| 10 | + | ||
| 11 | + | ## Documents for Review | |
| 12 | + | ||
| 13 | + | All at `site-docs/public/`: | |
| 14 | + | ||
| 15 | + | | Document | Path | Words | Priority | | |
| 16 | + | |----------|------|-------|----------| | |
| 17 | + | | Terms of Service | `legal/terms-of-service.md` | ~800 | **Critical** | | |
| 18 | + | | Privacy Policy | `legal/privacy-policy.md` | ~900 | **Critical** | | |
| 19 | + | | Payments & Refunds | `legal/payments.md` | ~1,100 | **High** | | |
| 20 | + | | Content Moderation | `legal/moderation.md` | ~1,300 | Medium | | |
| 21 | + | | Copyright / DMCA | `legal/copyright.md` | ~1,000 | **High** | | |
| 22 | + | | Acceptable Use | `legal/acceptable-use.md` | ~900 | Medium | | |
| 23 | + | | Appeals | `legal/appeals.md` | ~600 | Low | | |
| 24 | + | | Transparency Reports | `legal/transparency.md` | ~500 | Low | | |
| 25 | + | | Guarantees | `about/guarantees.md` | ~1,000 | **High** | | |
| 26 | + | | Payouts guide | `guide/payouts.md` | ~700 | **High** (tax section) | | |
| 27 | + | ||
| 28 | + | **Total reading:** ~8,800 words across 10 docs. A lawyer can read this in under an hour. | |
| 29 | + | ||
| 30 | + | --- | |
| 31 | + | ||
| 32 | + | ## Part 1: Questions for a Lawyer | |
| 33 | + | ||
| 34 | + | ### Terms of Service — Critical | |
| 35 | + | ||
| 36 | + | 1. **Enforceability of informal tone.** The ToS is written in plain English, not legalese. Is it enforceable as-is, or does it need boilerplate (e.g., "WHEREAS," "NOTWITHSTANDING")? Can it stay readable and still hold up? | |
| 37 | + | ||
| 38 | + | 2. **Liability cap: "amount you've paid us in the past 12 months."** For a creator paying $10/month, cap is $120. If we cause data loss worth thousands, is $120 defensible? Does this need a floor? Is it enforceable in all jurisdictions we serve? | |
| 39 | + | ||
| 40 | + | 3. **"As is" disclaimer.** Currently one sentence: "The service is provided 'as is.' We do our best but can't guarantee uptime, data integrity, or that you'll make money." Is this sufficient, or does it need the standard ALL-CAPS warranty disclaimer? | |
| 41 | + | ||
| 42 | + | 4. **Unilateral terms changes.** "We may update these terms. We'll notify you of material changes. Continued use after changes constitutes acceptance." Problems: | |
| 43 | + | - "Material" is undefined | |
| 44 | + | - No notice period specified | |
| 45 | + | - "Continued use = acceptance" may not be valid in EU | |
| 46 | + | - Compare: guarantees.md promises 90 days notice for price changes but ToS has no such commitment for terms changes | |
| 47 | + | ||
| 48 | + | 5. **Termination notice: "when possible."** "We may terminate accounts that violate these terms. We'll provide notice when possible." This is vague. Should it commit to a specific notice period (e.g., 7 days) except for the carved-out immediate-termination cases in moderation.md? | |
| 49 | + | ||
| 50 | + | 6. **Missing indemnification clause.** The ToS has no indemnification provision. Is this intentional and fine, or an exposure risk? If a creator uploads infringing content and we get sued, what's our position? | |
| 51 | + | ||
| 52 | + | 7. **Content license scope.** "You grant us a license to host, display, and distribute your content as necessary to operate the service." Questions: | |
| 53 | + | - Does this survive account deletion? (It shouldn't, and the code deletes content, but the ToS doesn't say so explicitly) | |
| 54 | + | - Does it cover generating thumbnails, RSS feeds, search indexing, email previews? | |
| 55 | + | - Is "as necessary to operate" specific enough? | |
| 56 | + | ||
| 57 | + | 8. **Fan purchase license.** "You get a license to personal use; you can't redistribute or resell." Is "personal use" legally meaningful without defining it? Should this reference specific rights (e.g., "non-commercial, non-transferable")? | |
| 58 | + | ||
| 59 | + | 9. **Age requirements.** Creator: 18+. Fan: 13+. COPPA implications for 13-17 year old fans who provide email and make purchases? | |
| 60 | + | ||
| 61 | + | 10. **Jurisdiction mismatch.** ToS says Colorado law, Colorado courts. Platform serves 46+ countries. Is this enforceable for EU creators (where consumer protection laws may override choice of law)? | |
| 62 | + | ||
| 63 | + | 11. **Dispute resolution.** "We prefer to resolve disputes directly. If that fails, disputes are governed by Colorado law." No arbitration clause. Is this a deliberate choice? Pros/cons? | |
| 64 | + | ||
| 65 | + | ### Privacy Policy — Critical | |
| 66 | + | ||
| 67 | + | 12. **"Consent to transfer" for international data.** "Data may be processed in the United States. By using the service, you consent to this transfer." This is NOT a valid GDPR transfer mechanism post-Schrems II. Need Standard Contractual Clauses (SCCs) or another valid mechanism. | |
| 68 | + | ||
| 69 | + | 13. **GDPR legal basis.** Listed as: contract performance, legitimate interest (security), legal obligation (tax). Is "legitimate interest" sufficient for download/streaming IP tracking? Should this be more granular? | |
| 70 | + | ||
| 71 | + | 14. **Right to erasure exceptions.** "We remove your data within 30 days, except: Transaction records (legal requirement), Content others have purchased (they keep access)." Is "legal requirement" sufficient justification, or do we need to cite specific laws? | |
| 72 | + | ||
| 73 | + | 15. **Data retention periods.** | |
| 74 | + | - IP addresses: 30 days (stated and enforced in code) | |
| 75 | + | - Session records: 90 days (stated) | |
| 76 | + | - Account records post-termination: 2 years (stated in moderation.md, not in privacy policy) | |
| 77 | + | - Transaction records: indefinite (stated) | |
| 78 | + | - Are these defensible under GDPR data minimization? | |
| 79 | + | ||
| 80 | + | 16. **Children / COPPA.** "We don't knowingly collect data from children under 13." Fan accounts allow 13+. Do we need parental consent mechanisms for 13-15 year olds under GDPR (which sets the bar at 16 in some member states)? | |
| 81 | + | ||
| 82 | + | 17. **DPO designation.** Listed as dpo@makenot.work. Is a DPO required for our scale? If not required, does listing one create obligations? | |
| 83 | + | ||
| 84 | + | ### Copyright / DMCA — High | |
| 85 | + | ||
| 86 | + | 18. **DMCA agent registration.** The doc lists a designated agent with mailing address. Has the agent been registered with the US Copyright Office? (This is required for safe harbor. Filing is online at copyright.gov, ~$6.) | |
| 87 | + | ||
| 88 | + | 19. **Counter-notification: 10-14 business day waiting period.** The DMCA specifies 10-14 business days. Our doc says "10-14 business days." Is this correct, or is it 10-14 calendar days? | |
| 89 | + | ||
| 90 | + | 20. **Repeat infringer policy: 3 strikes.** Is three strikes reasonable? Does the policy need to account for counter-notifications that succeed (i.e., do overturned strikes reset the count)? | |
| 91 | + | ||
| 92 | + | ### Payments — High | |
| 93 | + | ||
| 94 | + | 21. **Merchant of record language.** We state clearly that creators are MoR. Does this adequately disclaim our liability for creator tax obligations? Could a creator argue we're jointly responsible? | |
| 95 | + | ||
| 96 | + | 22. **Chargeback fee: "$15."** We state this is Stripe's fee. Is it currently accurate? (Stripe's fee is $15 in the US but varies internationally.) Should we say "Stripe's dispute fee" instead of a specific number? | |
| 97 | + | ||
| 98 | + | 23. **No refund policy from platform.** "We don't process refunds on your behalf." Is this defensible for EU consumers who have a 14-day right of withdrawal for digital content? | |
| 99 | + | ||
| 100 | + | ### Guarantees — High | |
| 101 | + | ||
| 102 | + | 24. **Are guarantees legally binding?** The guarantees page makes specific commitments (0% fee, data export, 90-day shutdown notice, 12-month price grandfathering). Are these enforceable as contractual commitments? Should the ToS incorporate them by reference? | |
| 103 | + | ||
| 104 | + | 25. **Planned Guarantees.** The page lists commitments that are "not yet active." Could listing them create an implied commitment? Should they have a disclaimer? | |
| 105 | + | ||
| 106 | + | 26. **Shutdown protocol: 90 days.** Is this commitment enforceable if the LLC is dissolved? Should there be a trust or escrow for wind-down costs? | |
| 107 | + | ||
| 108 | + | ### Moderation — Medium | |
| 109 | + | ||
| 110 | + | 27. **Immediate termination without notice.** For CSAM, threats, illegal content, fraud. Is the carve-out clear enough? Does "credible threats of violence" need definition? | |
| 111 | + | ||
| 112 | + | 28. **Data retention post-termination: "Account records retained for 2 years."** This is in moderation.md but NOT in the privacy policy. These need to be consistent. | |
| 113 | + | ||
| 114 | + | 29. **"Higher standards for marginalized groups."** Is this legally defensible if challenged as discriminatory enforcement? Has this been tested? | |
| 115 | + | ||
| 116 | + | --- | |
| 117 | + | ||
| 118 | + | ## Part 2: Questions for a Tax Professional | |
| 119 | + | ||
| 120 | + | ### US Tax | |
| 121 | + | ||
| 122 | + | 30. **1099-K threshold.** We state "$600/year as of 2024." The IRS delayed the $600 threshold multiple times (was supposed to start 2022, delayed to 2023, then 2024, then 2025). What is the CURRENT threshold for the current and coming tax year? Is it safe to link to Stripe's page and let them handle it rather than stating a number? | |
| 123 | + | ||
| 124 | + | 31. **1099-MISC / 1099-NEC.** We state "We do not issue 1099-MISC or W-2 forms." Since creators are using Stripe Connect, does Stripe handle all tax reporting? Or does Make Creative, LLC have any reporting obligations for the subscription payments we receive? | |
| 125 | + | ||
| 126 | + | 32. **Platform subscription deductibility.** payments.md says "Your Makenot.work subscription may be deductible as a business expense." Can we say this? Is it accurate for hobby creators vs professional creators? | |
| 127 | + | ||
| 128 | + | ### International Tax | |
| 129 | + | ||
| 130 | + | 33. **VAT/GST on platform subscriptions.** We charge creators $10-40/month. For EU creators, should we be collecting VAT on our subscription fee? (We sell a digital service to EU customers — this likely triggers EU VAT obligations under the One-Stop Shop scheme.) | |
| 131 | + | ||
| 132 | + | 34. **VAT/GST on fan purchases.** Creators are MoR. We state "VAT/GST collection is your responsibility." Is this sufficient, or do we need to provide tooling? Do we have any secondary liability? | |
| 133 | + | ||
| 134 | + | 35. **Cross-border withholding.** "If your country requires tax withholding on cross-border payments, Stripe handles this based on your W-8BEN or equivalent tax form." Is this accurate? Does Stripe actually handle withholding, or just collect the forms? | |
| 135 | + | ||
| 136 | + | 36. **US sales tax on digital goods.** Several US states require sales tax on digital goods. As a platform (not MoR), do we have any nexus or marketplace facilitator obligations? | |
| 137 | + | ||
| 138 | + | --- | |
| 139 | + | ||
| 140 | + | ## Part 3: Specific Language Fixes Needed | |
| 141 | + | ||
| 142 | + | These are things I already know are wrong or incomplete. Please confirm or correct: | |
| 143 | + | ||
| 144 | + | 37. **Privacy policy says 30-day deletion; moderation says 2-year retention.** These conflict. Proposed fix: add data retention schedule to privacy policy that lists all retention periods explicitly. | |
| 145 | + | ||
| 146 | + | 38. **ToS lacks effective date.** No "Last updated" or "Effective date" anywhere. | |
| 147 | + | ||
| 148 | + | 39. **No arbitration clause.** Deliberate — we prefer court over forced arbitration. Please confirm this is advisable for a small platform. | |
| 149 | + | ||
| 150 | + | 40. **No class action waiver.** Deliberate — we don't want to block class actions. Please confirm this doesn't create unusual exposure. | |
| 151 | + | ||
| 152 | + | 41. **DMCA address uses residential apartment.** The DMCA designated agent address is a residential address. Is this fine for the Copyright Office registration, or should we use a registered agent? | |
| 153 | + | ||
| 154 | + | --- | |
| 155 | + | ||
| 156 | + | ## Suggested Engagement Structure | |
| 157 | + | ||
| 158 | + | ### Option A: Single attorney, 2-3 hours | |
| 159 | + | - Review ToS + Privacy Policy (critical docs, ~1,700 words) | |
| 160 | + | - Answer questions 1-17 (highest priority) | |
| 161 | + | - Flag any other issues noticed | |
| 162 | + | - Written memo with recommended changes | |
| 163 | + | ||
| 164 | + | ### Option B: Split engagement, 4-5 hours | |
| 165 | + | - **Internet/platform attorney (3 hours):** Questions 1-29 (ToS, privacy, DMCA, moderation) | |
| 166 | + | - **Tax professional (1-2 hours):** Questions 30-36 (US + international tax) | |
| 167 | + | ||
| 168 | + | ### Option C: Full review, 6-8 hours | |
| 169 | + | - All 10 documents reviewed | |
| 170 | + | - All 41 questions addressed | |
| 171 | + | - Redlined versions of ToS and Privacy Policy | |
| 172 | + | - Tax compliance memo | |
| 173 | + | ||
| 174 | + | ### Recommendation: Option B | |
| 175 | + | The tax questions are specialized and won't be answered well by a general internet lawyer. The legal questions are standard platform law. Two specialists for 4-5 hours total will produce better results than one generalist for 6-8 hours. | |
| 176 | + | ||
| 177 | + | --- | |
| 178 | + | ||
| 179 | + | ## What I've Already Done | |
| 180 | + | ||
| 181 | + | - All docs written in plain English (no legalese to decipher) | |
| 182 | + | - Code verified against doc claims (0% fee, data deletion, export, etc.) | |
| 183 | + | - All contact emails set up (legal@, privacy@, dpo@, dmca@, etc.) | |
| 184 | + | - All features described in docs are implemented in code | |
| 185 | + | - Payment model (Stripe Connect Direct Charges) is correctly described | |
| 186 | + | - GDPR/CCPA sections exist (may need refinement) | |
| 187 | + | - Three rounds of creator trust audit completed | |
| 188 | + | ||
| 189 | + | ## What I Need Back | |
| 190 | + | ||
| 191 | + | 1. **Redlined ToS and Privacy Policy** — specific language changes, not general advice | |
| 192 | + | 2. **Yes/no on each numbered question** — with brief explanation where answer is "no" or "it depends" | |
| 193 | + | 3. **Tax compliance checklist** — what do we need to do before accepting EU creators | |
| 194 | + | 4. **Priority ranking** — which issues must be fixed before launch vs can wait |
| @@ -98,7 +98,7 @@ Before adding a creator to `creators/`: | |||
| 98 | 98 | - [ ] What are they paying in fees? (Patreon 10%, Gumroad 10%, etc.) | |
| 99 | 99 | - [ ] Have they publicly expressed platform frustration? | |
| 100 | 100 | - [ ] What's their audience size and engagement? | |
| 101 | - | - [ ] Which makenot.work tier fits them? (Basic $10, Small Files $20, Big Files $30, Streaming $40) | |
| 101 | + | - [ ] Which makenot.work tier fits them? (Basic $10, Small Files $20, Big Files $30, Everything $40) | |
| 102 | 102 | - [ ] Is there a natural community entry point? (Discord, Patreon, subreddit) | |
| 103 | 103 | ||
| 104 | 104 |
| @@ -0,0 +1,209 @@ | |||
| 1 | + | # Creator Outreach Tiers | |
| 2 | + | ||
| 3 | + | Categorized for hand-written outreach. Per-creator talking points in `creators/`. | |
| 4 | + | ||
| 5 | + | --- | |
| 6 | + | ||
| 7 | + | ## Tier 1 — Alpha testers | |
| 8 | + | ||
| 9 | + | Ideological alignment or outspoken platform critics. Likely to respond to an alpha invitation, tolerate rough edges, and give real feedback. These are people who care about the *problem* MNW solves, not just the product. | |
| 10 | + | ||
| 11 | + | ### Recently left or actively leaving a platform | |
| 12 | + | These creators are mid-migration or just finished one. The pain is fresh. A second move is a smaller ask than the first. | |
| 13 | + | ||
| 14 | + | | Creator | What happened | What they sell | Why MNW | | |
| 15 | + | |---------|--------------|----------------|---------| | |
| 16 | + | | **Unwoman** | Left Patreon Jan 2025 over per-creation billing elimination | Music | Actively looking for alternatives right now | | |
| 17 | + | | **Anne Helen Petersen** | Left Substack Oct 2025 (bots, rage optimization). Recovered 70% subs in 2 weeks | Newsletter | Already proved audience will follow | | |
| 18 | + | | **Ed Zitron** | Left Substack for Ghost. Writes about platform enshittification | Newsletter | Second migration is smaller ask. Already on Ghost (flat fee model) | | |
| 19 | + | | **Lyz Lenz** | Left Substack (bots, rage optimization) | Newsletter | Same pattern as AHP | | |
| 20 | + | | **Virginia Sole-Smith** | Lost ~50% audience in Substack-to-Patreon switch | Newsletter | Cares deeply about portability — that's the pitch | | |
| 21 | + | | **Alison Roman** | Left Substack Sep 2025 for Ghost | Food writing | Already moved once, paying Ghost fees | | |
| 22 | + | | **FoggyKitchen** | Left Udemy Mar 2025 (revenue "only fraction" of direct) | DevOps courses | Self-hosting now — MNW removes the ops burden | | |
| 23 | + | | **Sweet Softies** | Left Etsy AND Ravelry. Wrote public reviews | Crochet patterns | Already on Payhip (5%). MNW is cheaper at scale | | |
| 24 | + | | **Liz Corke** | Left Ravelry 2019-2020 over accessibility/inclusion failures | Knitting patterns | Vocal departure, on Payhip now | | |
| 25 | + | | **Barb Sotiropoulos** | Left Patreon 2022 — content treadmill anxiety | Art/writing | Flat fee is opposite of what drove her away | | |
| 26 | + | | **Michael Kelly** | 7+ year Patreon veteran frustrated by forced subscription billing migration | Music | Public frustration, timing is right | | |
| 27 | + | | **Every** | Left Substack 2021 over 10% fee and lock-in. Built own software | Newsletter collective | Paying ongoing engineering costs for custom platform | | |
| 28 | + | | **Thomas Frank** | Mid-migration from Gumroad to Lemon Squeezy | Notion templates | Catching him mid-move. $100K+/mo revenue, $10K+/yr in fees | | |
| 29 | + | ||
| 30 | + | ### Ideological alignment — anti-extraction, open source, maker ethos | |
| 31 | + | These people's *brand* is the same fight MNW is in. | |
| 32 | + | ||
| 33 | + | | Creator | Why they're aligned | What they sell | Audience | | |
| 34 | + | |---------|-------------------|----------------|----------| | |
| 35 | + | | **Cory Doctorow** | Coined "enshittification." Leading voice on platform extraction | Books, writing | Large. May be too busy but worth one email | | |
| 36 | + | | **Molly White** | Brand is "platforms shouldn't exploit people." Donation-funded | Writing (citation.needed) | Smaller but extremely influential in tech | | |
| 37 | + | | **Louis Rossmann** | Runs FULU Foundation. Anti-rent-seeking is his entire brand | Repair advocacy | 2.49M YouTube. Source-available code is his language | | |
| 38 | + | | **Casey Muratori** | Handmade philosophy. Anti-bloat, anti-framework. Deepest technical alignment | Programming education | Smaller but massively influential in systems programming | | |
| 39 | + | | **Nicky Case** | Open-source creative philosophy. Donation-funded | Interactive explanations | Every fee dollar is pure loss | | |
| 40 | + | | **iFixit / Limor Fried** | Open-knowledge, right-to-repair. Strategic alignment | Hardware, guides | 80K+ repair manuals. Adafruit Discord ~38K | | |
| 41 | + | | **Tom Nicholas** | Makes videos about the broken creator economy. Audience is primed | Video essays | ~500K YouTube | | |
| 42 | + | | **Folding Ideas** | "Line Goes Up" exposes exploitative systems. Paying % to same platforms he criticizes | Video essays | Large YouTube + Patreon | | |
| 43 | + | ||
| 44 | + | ### Technical overlap — Rust community, dev tools, would actually read the source | |
| 45 | + | These people would evaluate MNW technically, not just as users. Their endorsement carries weight with developers. | |
| 46 | + | ||
| 47 | + | | Creator | Why | What they sell | Audience | | |
| 48 | + | |---------|-----|----------------|----------| | |
| 49 | + | | **fasterthanlime** | Deep Rust content. Natural stack overlap | Patreon articles | Small but influential in Rust | | |
| 50 | + | | **Jon Gjengset** | Rust educator. Would understand and appreciate the implementation | Patreon, educational content | ~100K | | |
| 51 | + | | **Tsoding** | Anti-framework, build-from-scratch philosophy. Exact cultural fit | Twitch/YouTube | 78K | | |
| 52 | + | | **TJ DeVries** | Neovim core. Recently went independent | Twitch/YouTube | ~20K | | |
| 53 | + | | **ThePrimeagen** | Left Netflix to go independent. Loud dev community voice | YouTube/Patreon/Twitch | 473K YouTube | | |
| 54 | + | | **Julia Evans** | Proved willingness to switch (Gumroad to Shopify). Zines are perfect fit | Programming zines | Paying ~$150/mo platform fees | | |
| 55 | + | | **Paul Hudson** | Hacking with Swift. Subscription model on Gumroad = compounding fees | Books, courses | Swift community | | |
| 56 | + | | **Bartosz Ciechanowski** | Interactive explanations. Low frequency, high quality — flat fee rewards this | Patreon articles | Small, intensely loyal | | |
| 57 | + | ||
| 58 | + | ### Vocal about fees / demonetization — public complaints documented | |
| 59 | + | Fresh wounds. The pitch writes itself. | |
| 60 | + | ||
| 61 | + | | Creator | The complaint | What they sell | Recovery potential | | |
| 62 | + | |---------|--------------|----------------|-------------------| | |
| 63 | + | | **Benn Jordan** | Losing ~$1,100/mo to Patreon fees | Music, sample packs | ~$13K/yr recoverable | | |
| 64 | + | | **Red Means Recording** | Publicly critical of creator exploitation | Music, sample packs | Gumroad 10% + per-txn | | |
| 65 | + | | **Airwindows** | Every fee % is pure loss on donations — no product margin to absorb it | Audio plugins (free/donation) | 100% of fees are waste | | |
| 66 | + | | **anotherxlife** | Publicly documented leaving Gumroad (10% fee, PayPal issues) | Beat-making resources | Already switched once | | |
| 67 | + | | **Angela Collier** | Publicly critical of platforms incentivizing sensationalism | Physics education | ~300K YouTube | | |
| 68 | + | | **Amp Somers** | Revenue dropped $6.5K to $300/mo. Sued YouTube | Health/sex ed | Demonetization poster child | | |
| 69 | + | | **Chase Ross** | Proved keyword discrimination: "transgender" = demonetized | Trans education | Part of 2019 LGBTQ+ lawsuit | | |
| 70 | + | | **Perplexing Ruins** | Named in reporting on itch.io payout delays. $3,700 in limbo | TTRPG print-and-play | Active frustration | | |
| 71 | + | | **Rick Beato** | 4,000+ copyright claims. $36.52 on 250K-view video | Music education | 5M+ YouTube — large but deeply frustrated | | |
| 72 | + | ||
| 73 | + | --- | |
| 74 | + | ||
| 75 | + | ## Tier 2 — Profitable switchers | |
| 76 | + | ||
| 77 | + | Big enough that $10-40/mo is trivially recovered from fee savings. Small or loyal enough that their audience would follow them. Some ideological alignment (hates fees, values independence) but not necessarily vocal about it. | |
| 78 | + | ||
| 79 | + | ### High fee burden — the math is obvious | |
| 80 | + | ||
| 81 | + | | Creator | Current fees | Revenue | MNW savings | What they sell | | |
| 82 | + | |---------|-------------|---------|-------------|----------------| | |
| 83 | + | | **Jenny Nicholson** | Patreon = 85% of income. 73.5K patrons. Apple 30% hits Nov 2026 | Massive | Thousands/mo | Video essays | | |
| 84 | + | | **Easlo** | ~$2K/mo (~$24K/yr) to Gumroad on $20K/mo revenue | $20K/mo | ~$24K/yr | Notion templates | | |
| 85 | + | | **Traf** | ~$40K fees on $397K Gumroad revenue in 9 months | $44K/mo | ~$50K/yr | iOS icon packs | | |
| 86 | + | | **Max Ulichney** | $10K+/yr to Gumroad (10% + per-txn) on six figures | Six figures | $10K+/yr | Procreate brushes | | |
| 87 | + | | **Goodnight Moon ASMR** | ~$1.6K/mo (~$19K/yr) to Patreon | ~$16K/mo | ~$15-17K/yr | ASMR audio/video | | |
| 88 | + | | **FrivolousFox ASMR** | ~$1.1K/mo (~$13K/yr) to Patreon | ~$11K/mo | ~$13K/yr | ASMR content | | |
| 89 | + | | **HappyDownloads** | ~$50K+ lifetime Etsy fees on $500K+ revenue | $500K+ lifetime | $50K+ lifetime | Digital planners | | |
| 90 | + | | **Fix This Build That** | Triple storefront: Gumroad + Shopify + Etsy | 1.7M YouTube | Combined 10-15% | Woodworking plans | | |
| 91 | + | | **731 Woodworks** | 3-10% across 3 platforms | 100K+ YouTube | Consolidation savings | Woodworking plans | | |
| 92 | + | | **Hex3D** | 5+ platforms (Cults3D 20%, MyMiniFactory 10-15%, Patreon 10%) | Substantial | Consolidation | 3D printing STLs | | |
| 93 | + | | **Dru Riley** | Gumroad fees on $699/yr membership + reports | 45K email subs | Recurring fee savings | Business analysis | | |
| 94 | + | | **Curtiss King** | Already went DTC. Six-figure independent business | Six figures | Infrastructure consolidation | Beat making, courses | | |
| 95 | + | | **You Suck at Producing** | Gumroad 10% + per-txn on courses/sample packs | ~700K YouTube | Significant | Music production | | |
| 96 | + | ||
| 97 | + | ### Loyal communities that would follow | |
| 98 | + | ||
| 99 | + | | Creator | Why the audience would port | Current platform | Audience size | | |
| 100 | + | |---------|---------------------------|-----------------|---------------| | |
| 101 | + | | **Darknet Diaries** | Cybersecurity audience would verify MNW's security claims | Patreon | Growing rapidly | | |
| 102 | + | | **Coffeezilla** | Audience allergic to scams. Source-available code = credibility | Patreon | 4.5M YouTube | | |
| 103 | + | | **Technology Connections** | No sponsors, no merch, Patreon-only. Donates excess | Patreon | 2.5M YouTube | | |
| 104 | + | | **Dan Carlin** | Already sells direct ($1-2/ep). His model IS direct sales | Own site | Millions per episode | | |
| 105 | + | | **Noah Caldwell-Gervais** | Marathon content (2-5hr). Algorithm useless. Patreon is everything | Patreon | Dedicated | | |
| 106 | + | | **Matt Colville** | Crowdfunded $16M+. Audience already pays direct | MCDM (direct) | TTRPG gateway | | |
| 107 | + | | **Hainbach** | Sample packs + courses. Technically-minded audience | Patreon, Bandcamp | ~300K YouTube | | |
| 108 | + | | **Emily Hopkins** | Sample packs. Perfect Small Files fit | Patreon | ~300K YouTube | | |
| 109 | + | | **DivKid** | Extreme niche influence in tight-knit Eurorack scene | YouTube | ~50K | | |
| 110 | + | | **Mylar Melodies** | Losing ~13% to Patreon + processing | Patreon | Synth community | | |
| 111 | + | | **Primer** | Infrequent posts. Algorithm hostile. Patreon-dependent | Patreon | Science/math sims | | |
| 112 | + | | **Well There's Your Problem** | Small, dedicated. Lives by patron support | Patreon | Engineering podcast | | |
| 113 | + | ||
| 114 | + | ### Force multipliers — converting one reaches their community | |
| 115 | + | ||
| 116 | + | | Creator | Multiplier effect | Their niche | | |
| 117 | + | |---------|------------------|-------------| | |
| 118 | + | | **Kayse Morris** (CEO Teacher) | Teaches TPT sellers how to diversify. One conversion = thousands | TPT/education | | |
| 119 | + | | **Kristen Doyle** | Documents TPT's decline. Mentors other teachers | TPT/education | | |
| 120 | + | | **Lindsay Bowden** | Top 1% TPT seller + coaching. Losing ~$60K+/yr to TPT fees | TPT/education | | |
| 121 | + | | **Slime Green Beats** | Publish platform comparisons. Advocate own websites to avoid fees | Beat making | | |
| 122 | + | | **Snickerdoodle Knits** | Business mentor to pattern designers. Published fee comparisons | Craft/knitting | | |
| 123 | + | | **MediaPeruana Knits** | Published most detailed analysis of designer income in the niche | Craft/knitting | | |
| 124 | + | | **Navie D** | Better Beatmaker course 1000+ students. Force multiplier | Beat making | | |
| 125 | + | | **Flame Sound** | Bedroom Producers Blog (one of most-read music blogs) + 99Sounds | Sound design | | |
| 126 | + | | **Fable and Folly** | Podcast network. Mission = helping audio fiction producers earn more | Audio fiction | | |
| 127 | + | ||
| 128 | + | ### Podcast networks — one deal = all their shows | |
| 129 | + | ||
| 130 | + | | Network | Shows | Current platform | Key leverage | | |
| 131 | + | |---------|-------|-----------------|-------------| | |
| 132 | + | | **Headgum** | ~75 shows (NADDPOD 20K+, Doughboys 13K+) | Patreon | Network fee stack: network cut + Patreon 10% + Apple 30% | | |
| 133 | + | | **Night Vale Presents** | 8 shows (Welcome to Night Vale) | Patreon | 100% Patreon-dependent | | |
| 134 | + | | **Last Podcast Network** | 13+ shows | Patreon | All premium behind Patreon | | |
| 135 | + | | **Multitude** | Dozens + 15 external clients | Patreon | Network switch = multiplier | | |
| 136 | + | | **Grim & Mild** | Lore (43K+ patrons) + multiple shows | Patreon + Apple | 43K patrons make fees enormous | | |
| 137 | + | | **Maximum Fun** | Worker-owned coop. Custom membership system | Own system | Mission-aligned. Already built custom to avoid fees | | |
| 138 | + | ||
| 139 | + | --- | |
| 140 | + | ||
| 141 | + | ## Tier 3 — Long shots | |
| 142 | + | ||
| 143 | + | Makes financial sense to switch but no signal of platform unhappiness. May be partnered with or invested in a competitor. Worth a shot but don't spend much time on them. | |
| 144 | + | ||
| 145 | + | ### Large, established, no frustration signal | |
| 146 | + | ||
| 147 | + | | Creator | Current setup | Why long shot | | |
| 148 | + | |---------|--------------|---------------| | |
| 149 | + | | **Simone Giertz** | Patreon (8,100+ supporters) | No public complaints. Maker ethos but content with Patreon | | |
| 150 | + | | **Captain Disillusion** | Patreon | No complaints. Algorithm-hostile content but hasn't discussed alternatives | | |
| 151 | + | | **Clickspring** | Patreon | Months between uploads but no platform frustration expressed | | |
| 152 | + | | **hbomberguy** | Patreon | Patreon skepticism documented but hasn't acted on it | | |
| 153 | + | | **Jacob Geller** | Patreon (1.4M YouTube) | Multi-format, diverse revenue. No urgency to switch | | |
| 154 | + | | **styropyro** | Patreon (2.54M YouTube) | Low friction ($3/mo tiers) but no complaints | | |
| 155 | + | | **Ahoy** | Patreon | Algorithm punishes quality but hasn't explored alternatives | | |
| 156 | + | | **Adam Neely** | Patreon | Algorithm frustration but Patreon working fine | | |
| 157 | + | | **Applied Science** | YouTube only | Penalized for infrequent posting but no platform discussion | | |
| 158 | + | | **Cody's Lab** | YouTube | Demonetized but seems resigned, not seeking alternatives | | |
| 159 | + | | **Lavendaire** | Shopify + Kajabi | Paying $200-900/mo but running established business | | |
| 160 | + | | **Traversy Media** | YouTube + Udemy | Discussed direct sales but hasn't moved | | |
| 161 | + | ||
| 162 | + | ### Competitor-adjacent or embedded | |
| 163 | + | ||
| 164 | + | | Creator | Situation | Why long shot | | |
| 165 | + | |---------|-----------|---------------| | |
| 166 | + | | **Lindsay Ellis** | Patreon + Nebula | Nebula partnership may create loyalty | | |
| 167 | + | | **Jessie Gender** | YouTube + Patreon | Shadowbanning frustration but no alternatives discussed | | |
| 168 | + | | **ContraPoints** | Patreon | Large, complex operation. Unlikely to move on alpha invite | | |
| 169 | + | | **Innuendo Studios** | Patreon | Understands platform power but hasn't explored alternatives | | |
| 170 | + | | **PhilosophyTube** | Patreon | Same pattern as ContraPoints | | |
| 171 | + | | **Dokibird** | YouTube + Twitch | Left Nijisanji (exploitation) but building on YouTube/Twitch now | | |
| 172 | + | | **GeneratePress** | Own site (2.4M+ downloads) | Never used marketplaces. Already fully independent | | |
| 173 | + | | **Biddy Tarot** | Own site, Amazon, Etsy | 7-figure business. Switching cost high | | |
| 174 | + | | **Khe Hy** | Podia | Switched platforms twice already. May be fatigued | | |
| 175 | + | | **Brad Hargreaves** | Ghost | Already on flat-fee platform. Low urgency | | |
| 176 | + | ||
| 177 | + | ### Unreachable or monitor-only | |
| 178 | + | ||
| 179 | + | | Creator | Reason | | |
| 180 | + | |---------|--------| | |
| 181 | + | | **Naomi Wu** | [UNREACHABLE] — censored/absent since mid-2023 | | |
| 182 | + | | **Armchair Historian** | Built own platform. Unlikely to switch to another | | |
| 183 | + | | **Defector** | Worker-owned coop with own subscription system. No reason to switch | | |
| 184 | + | | **404 Media** | Already on lean Ghost + Stripe stack. Hard to improve on | | |
| 185 | + | ||
| 186 | + | --- | |
| 187 | + | ||
| 188 | + | ## Talking Points by Pitch Angle | |
| 189 | + | ||
| 190 | + | ### "You're paying X% that you don't have to" | |
| 191 | + | For Patreon creators: calculate their monthly fee and show the delta. Jenny Nicholson, Benn Jordan, Goodnight Moon, Technology Connections. | |
| 192 | + | ||
| 193 | + | ### "Apple is about to take 30% of your iOS subscribers" | |
| 194 | + | Patreon creators with iOS audiences. Deadline: November 2026. Jenny Nicholson, Headgum, Night Vale, any large Patreon. | |
| 195 | + | ||
| 196 | + | ### "You already proved your audience will follow you" | |
| 197 | + | For creators who already migrated once. Anne Helen Petersen, Ed Zitron, Lyz Lenz, Virginia Sole-Smith, Julia Evans, Sweet Softies. | |
| 198 | + | ||
| 199 | + | ### "You built this to avoid platform fees — we already built it" | |
| 200 | + | For creators running their own infrastructure. Dan Carlin, Every, FoggyKitchen, Curtiss King, Matt Colville. | |
| 201 | + | ||
| 202 | + | ### "The code is open. You can verify every claim" | |
| 203 | + | For technical/skeptical audiences. Darknet Diaries, Coffeezilla, fasterthanlime, Casey Muratori, ThePrimeagen. | |
| 204 | + | ||
| 205 | + | ### "Your content gets penalized by algorithms. We don't have algorithms" | |
| 206 | + | For quality-over-frequency creators. Ahoy, Captain Disillusion, Clickspring, Bartosz Ciechanowski, Primer, Noah Caldwell-Gervais. | |
| 207 | + | ||
| 208 | + | ### "One conversion reaches your whole community" | |
| 209 | + | For multipliers. Kayse Morris, Kristen Doyle, Lindsay Bowden, Slime Green Beats, Snickerdoodle Knits, Navie D. |
| @@ -11,7 +11,7 @@ Instead, creators pay a flat monthly subscription to use the platform, based on | |||
| 11 | 11 | - **Basic** (text, all base features): **$10/month** | |
| 12 | 12 | - **Small Files** (audio, software, plugins, downloads): **$20/month** | |
| 13 | 13 | - **Big Files** (video, courses, large downloads): **$30/month** | |
| 14 | - | - **Streaming** (live streaming + everything above): **$40/month** | |
| 14 | + | - **Everything** (all features, current and future): **$40/month** | |
| 15 | 15 | ||
| 16 | 16 | The platform's source code is publicly available, meaning anyone can inspect or audit it. Creators can export all their data and take their audience with them if they ever leave. There's no lock-in. | |
| 17 | 17 |
| @@ -117,7 +117,7 @@ These scale with each additional creator. | |||
| 117 | 117 | ||
| 118 | 118 | Video has the widest range because usage varies enormously. A creator uploading 4K weekly costs much more than one uploading 720p monthly. | |
| 119 | 119 | ||
| 120 | - | ### Streaming Tier | |
| 120 | + | ### Everything Tier | |
| 121 | 121 | ||
| 122 | 122 | | Component | Monthly Cost | Assumptions | | |
| 123 | 123 | |-----------|--------------|-------------| |
| @@ -509,8 +509,8 @@ | |||
| 509 | 509 | <div class="tier"> | |
| 510 | 510 | <span class="tier-price">$40</span> | |
| 511 | 511 | <span class="tier-period">/ month</span> | |
| 512 | - | <span class="tier-name">Streaming</span> | |
| 513 | - | <div class="tier-desc">Live streaming plus everything above.</div> | |
| 512 | + | <span class="tier-name">Everything</span> | |
| 513 | + | <div class="tier-desc">All features, current and future.</div> | |
| 514 | 514 | </div> | |
| 515 | 515 | </div> | |
| 516 | 516 |
| @@ -946,10 +946,10 @@ client.<span class="fn">blob_confirm</span>(&hash, size).<span class="kw">aw | |||
| 946 | 946 | <div class="tier-desc">+ Video, courses, large downloads. Higher storage quotas.</div> | |
| 947 | 947 | </div> | |
| 948 | 948 | <div class="tier"> | |
| 949 | - | <span class="tier-name">Streaming</span> | |
| 949 | + | <span class="tier-name">Everything</span> | |
| 950 | 950 | <span class="tier-price">$40</span> | |
| 951 | 951 | <span class="tier-period">/ month</span> | |
| 952 | - | <div class="tier-desc">+ Live streaming infrastructure. Everything included.</div> | |
| 952 | + | <div class="tier-desc">All features, current and future.</div> | |
| 953 | 953 | </div> | |
| 954 | 954 | </div> | |
| 955 | 955 |
| @@ -10,7 +10,7 @@ PostgreSQL database. 57 migrations in `migrations/`, auto-applied on boot via sq | |||
| 10 | 10 | | Projects & Content | 8 | Creator projects, items, versions, chapters, insertions, sections, bundles | | |
| 11 | 11 | | Tags & Taxonomy | 4 | Hierarchical tags, item tagging, platform labels | | |
| 12 | 12 | | Commerce | 7 | Transactions, subscriptions, promo codes, license keys | | |
| 13 | - | | Creator Tiers | 2 | Platform subscription tiers (Basic/Small/Big/Streaming) | | |
| 13 | + | | Creator Tiers | 2 | Platform subscription tiers (Basic/Small/Big/Everything) | | |
| 14 | 14 | | Email & Mailing | 4 | Mailing lists, subscribers, suppressions, signups | | |
| 15 | 15 | | Social | 3 | Follows, blog posts, custom links | | |
| 16 | 16 | | Collections | 2 | User-curated item lists | | |
| @@ -265,7 +265,7 @@ Per-machine activations. UNIQUE(license_key_id, machine_id) prevents double-acti | |||
| 265 | 265 | ## Creator Tiers | |
| 266 | 266 | ||
| 267 | 267 | ### creator_subscriptions | |
| 268 | - | Platform subscription for creators (Basic $10, Small Files $20, Big Files $30, Streaming $40). One row per creator. | |
| 268 | + | Platform subscription for creators (Basic $10, Small Files $20, Big Files $30, Everything $40). One row per creator. | |
| 269 | 269 | ||
| 270 | 270 | - **FK:** user_id → users CASCADE (UNIQUE) | |
| 271 | 271 | - **Key columns:** tier, status, stripe_subscription_id UNIQUE, grace_enforced_at |
| @@ -56,8 +56,9 @@ Audit date: 2026-04-26. Perspective: skeptical creator evaluating MNW. | |||
| 56 | 56 | | Feature | Status | | |
| 57 | 57 | |---------|--------| | |
| 58 | 58 | | Live streaming (RTMP, chat, clips) | Not implemented | | |
| 59 | - | | Fan+ subscription | DB only, no UI | | |
| 60 | - | | Video transcoding/adaptive | Partial (upload works, playback missing) | | |
| 59 | + | | Fan+ subscription | Implemented (checkout, billing, badge — docs were stale) | | |
| 60 | + | | Video upload/playback | Implemented (upload, player, access control — docs were stale) | | |
| 61 | + | | Video transcoding/adaptive | Not implemented (upload-format-only delivery) | | |
| 61 | 62 | | Content Archive (12-month preservation) | Not implemented | | |
| 62 | 63 | | Independent moderation appeals | Not implemented (one-person team) | | |
| 63 | 64 | | 99.9% uptime | Not implemented (currently 99.5% target) | |
| @@ -3,12 +3,12 @@ | |||
| 3 | 3 | ## Status | |
| 4 | 4 | Done: All pre-beta phases. Active: Creator setup (Stripe), manual testing. Next: Soft launch. | |
| 5 | 5 | ||
| 6 | - | v0.4.1. Audit grade A. ~1,233 tests. | |
| 6 | + | v0.4.3. Audit grade A. ~1,412 tests. | |
| 7 | 7 | ||
| 8 | 8 | --- | |
| 9 | 9 | ||
| 10 | 10 | ## Code Review Remediation — Deferred | |
| 11 | - | - [ ] Monitor scheduler.rs (635), git/mod.rs (613), license_keys.rs (684) for growth | |
| 11 | + | - [ ] Monitor scheduler.rs (1184), git/mod.rs (224), license_keys.rs (684) for growth | |
| 12 | 12 | - [ ] Consider splitting bin/mnw-admin.rs git-auth commands into separate module | |
| 13 | 13 | ||
| 14 | 14 | --- | |
| @@ -54,15 +54,15 @@ v0.4.1. Audit grade A. ~1,233 tests. | |||
| 54 | 54 | - [ ] Test free download flow (GO), PWYW flow (BB), purchase flow (AF), subscription flow (GO) | |
| 55 | 55 | - [ ] Test discount code on AF purchase | |
| 56 | 56 | - [ ] Test license key delivery after AF purchase | |
| 57 | - | - [ ] Capture screenshots for docs (dashboard, audio player, discover, pricing, git browser) | |
| 57 | + | - [ ] Capture screenshots for docs (dashboard, audio player, discover, pricing, git browser) — or replace with sandbox links | |
| 58 | 58 | ||
| 59 | 59 | ### Documentation — Remaining | |
| 60 | - | - [ ] Review new docs against live UI for accuracy (button labels, navigation paths) | |
| 61 | - | - [ ] liability.md legal review (has [PENDING LEGAL REVIEW] placeholders) | |
| 62 | - | - [ ] dmca-counter.md designated agent address (needs DMCA agent registration) | |
| 60 | + | - [x] Review new docs against live UI for accuracy (button labels, navigation paths) — fixed in round 3 audit | |
| 61 | + | - [ ] liability.md legal review (has [PENDING LEGAL REVIEW] placeholders) — rolled into legal review prep | |
| 62 | + | - [ ] dmca-counter.md designated agent address (needs DMCA agent registration) — rolled into legal review prep | |
| 63 | 63 | ||
| 64 | 64 | ### Git Access Provisioning | |
| 65 | - | - [ ] Web UI for managing SSH keys per MNW account (residents/collaborators add keys in dashboard) | |
| 65 | + | - [ ] Dashboard page for SSH key management (API + HTMX partials exist at `routes/api/ssh_keys.rs`, needs dashboard tab) | |
| 66 | 66 | - [ ] Per-repo collaborator access (grant push by MNW username, stored in DB, wired to authorized_keys rebuild) | |
| 67 | 67 | - [ ] Replace manual `setup-ssh-keys.sh` with account-driven key management | |
| 68 | 68 | ||
| @@ -87,7 +87,7 @@ v0.4.1. Audit grade A. ~1,233 tests. | |||
| 87 | 87 | ||
| 88 | 88 | ## Frontend Audit — Remaining | |
| 89 | 89 | ||
| 90 | - | - [ ] Add a visual to landing page (HTML/CSS ready, needs `static/images/landing-screenshot.png`) | |
| 90 | + | - [x] Landing page visual — replaced screenshot with sandbox link ("Try the dashboard without signing up") | |
| 91 | 91 | - [ ] Create og:image social card (1200x630, for landing page and fallback — distinct from logo.png) | |
| 92 | 92 | ||
| 93 | 93 | --- | |
| @@ -111,109 +111,89 @@ Files > 100 MB are now held for review instead of downloaded into RAM. Next step | |||
| 111 | 111 | - [ ] Allows horizontal scaling independently of request serving | |
| 112 | 112 | - [ ] Consider GPU-accelerated analysis if volume warrants it | |
| 113 | 113 | ||
| 114 | - | ### Other scanning hardening | |
| 115 | - | - [x] ~~Add timeout to YARA scanning. Fixed: `scanner.set_timeout(30s)` via yara-x native API.~~ | |
| 116 | - | - [ ] Cap ClamAV response buffer size (currently unbounded `read_to_end`) | |
| 117 | - | - [x] ~~Nested archive detection: check magic bytes, not just file extensions. Fixed: magic bytes check for ZIP, gzip, 7z, RAR in archive.rs.~~ | |
| 118 | 114 | ||
| 119 | 115 | --- | |
| 120 | 116 | ||
| 121 | 117 | ## Code Fuzz Findings (2026-04-25) | |
| 122 | 118 | ||
| 123 | - | Three rounds of adversarial code review. 51 findings total: 50 fixed, 1 accepted risk, 1 deferred. | |
| 119 | + | Three rounds of adversarial code review. 51 findings total: 50 fixed, 1 accepted risk, 2 deferred. Fixed items moved to todo_done.md. | |
| 124 | 120 | ||
| 125 | 121 | ### Accepted Risk | |
| 126 | 122 | - Idempotency check not atomic with operation — concurrent requests both execute (`db/idempotency.rs`). Safe because underlying ops are themselves idempotent. | |
| 123 | + | - Revoked session usable for up to 30s -- session cache IS cleared by revoke_session and revoke_other_sessions handlers; window only applies to direct DB manipulation (admin) | |
| 127 | 124 | ||
| 128 | 125 | ### Deferred | |
| 129 | 126 | - 7-day SyncKit JWT with no per-user revocation (`constants.rs:37`). Stolen token usable for full window. Requires key rotation infrastructure (SyncKit S4, post-beta). | |
| 127 | + | - Rate limit IP extraction trusts X-Forwarded-For when traffic bypasses Cloudflare (helpers.rs). Fix requires splitting rate limit extraction by path: CF-Connecting-IP for public web routes, peer socket for internal/CLI/git. Needs careful routing since CLI, git smart HTTP, and SyncKit all hit the same server but some bypass Cloudflare. | |
| 128 | + | - S3 key/file size UPDATE queries lack ownership in SQL -- defense-in-depth; callers verify ownership (db/items.rs) | |
| 130 | 129 | ||
| 131 | - | ### Resolved (28 findings) | |
| 132 | - | All critical, serious, and minor findings from rounds 1 and 2 are fixed. See git history for details. | |
| 130 | + | --- | |
| 133 | 131 | ||
| 134 | - | ## Code Fuzz Findings -- Round 3 (2026-04-25) | |
| 132 | + | ## Creator Trust Audit (2026-04-25, round 2 2026-04-26) | |
| 135 | 133 | ||
| 136 | - | ### Fixed | |
| 137 | - | - [x] SubscriptionStatus missing Trialing/Incomplete/IncompleteExpired variants (db/enums.rs) | |
| 138 | - | - [x] SyncKit auth does not block deactivated users (synckit_auth.rs) | |
| 139 | - | - [x] Build token comparison not constant-time (routes/builds.rs) | |
| 140 | - | - [x] Subscription access checks ignore paused_at (db/subscriptions.rs) | |
| 141 | - | - [x] Cover/MediaImage uploads bypass storage cap with i64::MAX (db/creator_tiers.rs) | |
| 142 | - | - [x] Promo code use_count consumed even when user already owns item (db/transactions.rs) | |
| 143 | - | - [x] Idempotency middleware caches empty string instead of real body (metrics.rs) | |
| 144 | - | - [x] OAuth: no dummy hash on user-not-found path (timing leak, routes/oauth.rs) | |
| 145 | - | - [x] OAuth: no password length cap (Argon2 DoS, routes/oauth.rs) | |
| 146 | - | - [x] OAuth: suspended/deactivated users can still authorize (routes/oauth.rs) | |
| 147 | - | - [x] OAuth session validation: result.valid not checked before suspension (routes/oauth.rs) | |
| 148 | - | - [x] OAuth legacy session path ignores deactivated flag (routes/oauth.rs) | |
| 149 | - | - [x] Subscription test fixture missing paused_at field (db/models/subscription.rs) | |
| 150 | - | - [x] Git routes have no rate limiting (routes/git/mod.rs) | |
| 151 | - | - [x] No Content-Security-Policy header (lib.rs) | |
| 152 | - | - [x] /metrics endpoint unprotected (lib.rs) | |
| 153 | - | - [x] Upload confirm: no idempotency, no S3 cleanup on storage error (routes/storage/uploads.rs) | |
| 154 | - | - [x] Version confirm: no idempotency, no S3 cleanup on storage error (routes/storage/versions.rs) | |
| 155 | - | - [x] Image confirm: storage increment after DB write, no idempotency (routes/storage/images.rs) | |
| 156 | - | - [x] Media confirm: no content_type/extension re-validation, no S3 cleanup (routes/storage/media.rs) | |
| 157 | - | ||
| 158 | - | - [x] CSRF token not rotated after login -- now regenerated in login_user (auth.rs, csrf.rs) | |
| 159 | - | - [x] Read-modify-write race on sort_order/position -- atomic INSERT...SELECT (db/custom_links.rs, db/collections.rs) | |
| 160 | - | - [x] N+1 reorder loops without transactions -- wrapped in transactions (db/custom_links.rs, db/collections.rs) | |
| 161 | - | - [x] Race condition in custom domain creation -- SELECT FOR UPDATE in transaction (db/custom_domains.rs) | |
| 162 | - | ||
| 163 | - | - [x] Double-purchase TOCTOU -- partial unique index on (buyer_id, item_id/project_id) WHERE status='pending' prevents concurrent checkouts (migration 073, checkout handlers) | |
| 164 | - | ||
| 165 | - | - [x] Promo code max_uses bypassable on paid path -- use_count now reserved at checkout time, released by scheduler on stale cleanup (migration 074, checkout handlers, scheduler) | |
| 134 | + | Two rounds of creator-perspective audit. 25+ findings resolved (moved to todo_done.md). Incident post-mortems will publish as posts in the MNW Changelog blog project. | |
| 166 | 135 | ||
| 167 | - | ### Deferred | |
| 168 | - | - Rate limit IP extraction trusts X-Forwarded-For when traffic bypasses Cloudflare (helpers.rs). Fix requires splitting rate limit extraction by path: CF-Connecting-IP for public web routes, peer socket for internal/CLI/git. Needs careful routing since CLI, git smart HTTP, and SyncKit all hit the same server but some bypass Cloudflare. | |
| 169 | - | - S3 key/file size UPDATE queries lack ownership in SQL -- defense-in-depth; callers verify ownership (db/items.rs) | |
| 170 | - | ||
| 171 | - | ### Accepted | |
| 172 | - | - Revoked session usable for up to 30s -- session cache IS cleared by revoke_session and revoke_other_sessions handlers; window only applies to direct DB manipulation (admin) | |
| 136 | + | ### Competitive Positioning (acknowledged, not bugs) | |
| 137 | + | - No free tier — deliberate tradeoff. Earn-back credit program planned. | |
| 138 | + | - No mobile fan app — creator apps exist, no general fan app. | |
| 139 | + | - No editorial discovery — search, tags, follows only. Interested in non-algorithmic discovery methods. | |
| 140 | + | - $10/mo minimum is biggest competitive gap vs Bandcamp/Gumroad/itch.io (all have free tiers). | |
| 173 | 141 | ||
| 174 | 142 | --- | |
| 175 | 143 | ||
| 176 | - | ## Creator Trust Audit (2026-04-25) | |
| 144 | + | ## Creator Trust Audit (2026-04-27, round 3) | |
| 177 | 145 | ||
| 178 | - | Systematic creator-perspective audit of docs, legal, code, and competitive positioning. | |
| 146 | + | Resolved (moved to todo_done.md): download budget removal, grace period duration, tax disclaimer, unlimited downloads doc, Stripe suspension doc, "original creative work" definition, post-cancellation retention, analytics "we don't track" expansion, Streaming→Everything rename, video "coming soon" labels removed, HSTS verified, git repo disk cleanup, succession plan, pricing page tier consistency, free item purchase redirect, dashboard Everything tier label. | |
| 179 | 147 | ||
| 180 | - | ### Resolved (20+ findings) | |
| 181 | - | All doc/code fixes, trust gaps, security issues, and doc clarity items are complete. Key changes: subscription export endpoint, offsite backups with WAM alerting, API key hashing, security headers, fan subscription pause on suspension, account limbo state, support ticket portal, expanded tax/payout/discovery/storage docs, privacy policy updates. See git history. | |
| 148 | + | ### Remaining | |
| 149 | + | - [ ] **Legal/tax professional review** — prep doc at `docs/internal/legal_review_prep.md` with 41 specific questions across ToS, privacy, DMCA, payments, tax. Recommended: split engagement (internet attorney 3h + tax professional 1-2h) | |
| 182 | 150 | ||
| 183 | - | ### Doc/Code Contradictions (all resolved) | |
| 184 | - | - [x] Payout minimum: aligned payouts.md with Stripe reality ($1 minimum), named Stripe explicitly | |
| 185 | - | - [x] Content protection watermarking: scoped claim to "audio and image files delivered without watermarks", disclosed text fingerprinting | |
| 186 | - | - [x] Mailing list import: reworded as roadmap item, linked to migration guide | |
| 187 | - | - [x] IP retention: added daily scheduler job scrubbing IPs from user_sessions, download_fingerprints, streaming_sessions at 30 days | |
| 151 | + | ## Creator Trust Audit (2026-04-27, round 4) | |
| 188 | 152 | ||
| 189 | - | ### Missing Creator-Facing Documentation | |
| 190 | - | - [x] Named Stripe explicitly in payouts.md and payments.md (replaced all "payment processor" references) | |
| 191 | - | - [x] Creator application criteria added to getting-started.md (what we look for, what gets rejected) | |
| 192 | - | - [x] Tips documented (new guide/tips.md) | |
| 193 | - | - [x] Bundles documented (new guide/bundles.md) | |
| 194 | - | - [x] Revenue splits documented (new guide/splits.md) | |
| 195 | - | - [x] Currencies/countries: linked to Stripe's own docs (46+ countries, 135+ currencies) rather than maintaining stale tables; fixed grammar from bulk find-replace | |
| 153 | + | Resolved mechanically: fan-plus.md "not yet available" removed (feature is live). how-we-work.md video "not yet available" removed (video upload/playback works). roadmap.md embeds + video moved from Direction to What's Built. Vaporware table in todo-creator-trust-audit.md updated. | |
| 196 | 154 | ||
| 197 | - | ### Trust Gaps | |
| 198 | - | - [x] 30-day post-termination export window -- migration 076 adds terminated_at; admin terminate route (requires prior suspension); scheduler deletes after 30 days; Stripe subscriptions canceled; termination email sent with export instructions | |
| 199 | - | - [x] Per-item content removal admin action -- migration 075, admin routes (remove/restore), email notifications, publish guards prevent re-publishing removed items | |
| 200 | - | - ~~No incident post-mortems or public historical incident log~~ — will publish as posts in the MNW Changelog blog project | |
| 155 | + | ### Docs — needs content decisions | |
| 156 | + | - [x] **Tax documentation**: Already covered in payouts.md (lines 33-53) — US 1099-K, non-US guidance, Stripe links, "not tax advice" disclaimer. Pattern: statements + links to Stripe, avoids hardcoded thresholds. | |
| 157 | + | - [x] **Support contact info**: Already covered — support/contact.md has 6 email addresses + response SLAs, dashboard has ticket form (user_support.html → WAM), forums exist | |
| 158 | + | - [x] **Stripe country limitations**: Added Stripe availability note with link to stripe.com/global in getting-started.md, before "What we look for" | |
| 159 | + | - [x] **"Material changes" in ToS**: Replaced vague "material changes" with specific notice periods: 30 days general, 90 days privacy, 90 days + grandfathering pricing, immediate for legal/security emergencies | |
| 160 | + | - [x] **Creator earnings data / social proof**: Too early — platform is new. Founder uses it for own creations. Revisit when real creators are onboarded. | |
| 161 | + | - [x] **Team/band accounts**: Added "Teams & Bands" section to getting-started.md — shared account vs individual accounts with co-authors, migration path | |
| 201 | 162 | ||
| 202 | - | ### Competitive Positioning (acknowledged, not bugs) | |
| 203 | - | - No free tier — deliberate tradeoff. Earn-back credit program planned. | |
| 204 | - | - No mobile fan app — creator apps exist, no general fan app. | |
| 205 | - | - No editorial discovery — search, tags, follows only. Interested in non-algorithmic discovery methods. | |
| 163 | + | ### Security | |
| 164 | + | - [x] **IP retention cleanup verification**: Added `scheduler_job_runs` table (migration 081), job run recording for all 6 privacy jobs, new `fingerprint_ip_scrub` + `streaming_session_cleanup` jobs, "Privacy & Compliance" section on `/health` page showing last-run time + rows affected + status indicator. Daily jobs now also run on first tick after restart. | |
| 165 | + | ||
| 166 | + | ### Competitive | |
| 167 | + | - [x] **Free trial application**: Waitlist application now includes free trial request fields (tier preference, trial length, reason). Available in both the join wizard and API route. Admin reviews and grants trials manually. | |
| 168 | + | - [x] **Mobile fan app**: Expanded FAQ entry with native iOS/Android plans (library, offline, push). Added "Mobile apps" section to roadmap Direction. | |
| 169 | + | - [x] **Email automation**: Added FAQ entry clarifying broadcasts + auto-notifications only, no drip/segmentation, suggesting external email service for advanced needs | |
| 170 | + | ||
| 171 | + | ### Low priority | |
| 172 | + | - [x] **Custom domains prominence**: Added link to custom-domains.md in getting-started "Share your link" step | |
| 173 | + | - [x] **Creator storefront preview/demo**: Added storefront customization (3 tiers: theme basics, custom CSS, full template access, all tiers) to roadmap Direction. Preview/demo deferred to beta. | |
| 206 | 174 | ||
| 207 | 175 | --- | |
| 208 | 176 | ||
| 209 | - | ## Content Fingerprinting — Remaining | |
| 210 | - | - [ ] Invisible image watermarks — LSB encoding (stub exists at `fingerprint/watermark_image.rs`) | |
| 211 | - | - [ ] Invisible audio watermarks — spread-spectrum (stub exists at `fingerprint/watermark_audio.rs`) | |
| 212 | - | - [ ] Wire visible stamps into download routes (stamp text files before serving) | |
| 213 | - | - [ ] Wire ZWC watermarks into download routes (watermark text files before serving) | |
| 214 | - | - [ ] ZIP/tar archive stamping (inject LICENSE.txt at archive root) | |
| 215 | - | - [ ] Dashboard UI for fingerprint tracing (lookup by fingerprint_id, view download history) | |
| 216 | - | - [ ] Anti-hotlink header checks in streaming routes (logic exists in `fingerprint/streaming.rs`) | |
| 177 | + | ## Launch Readiness (2026-04-27) | |
| 178 | + | ||
| 179 | + | ### Fixed | |
| 180 | + | - [x] Pricing page: Big Files and Everything enabled in calculator | |
| 181 | + | - [x] Purchase page: free items redirect to item page instead of broken checkout form | |
| 182 | + | - [x] Dashboard: Everything tier shows "Coming soon" instead of broken Subscribe button | |
| 183 | + | - [x] Pricing calculator: flipped colors so competitors show red when MNW is cheaper | |
| 184 | + | - [x] Removed demo data: migration 080 deletes Elena Vasquez seed content | |
| 185 | + | - [x] Docs accuracy: fixed "Connect Payments" → "Connect with Stripe", publish flow, notification labels, added tips notification | |
| 186 | + | - [x] Landing page: replaced screenshot placeholder with sandbox link | |
| 187 | + | - [x] Human testing code review: all 99 checklist items verified in code (routes, handlers, templates all exist) | |
| 188 | + | ||
| 189 | + | ### Pre-Launch Remaining | |
| 190 | + | - [ ] Stripe live mode: confirm creator Stripe Connect onboarding complete (not test mode) | |
| 191 | + | - [ ] Human testing: complete sign-off table in `deploy/human_testing.md` (code verified, needs manual walkthrough) | |
| 192 | + | - [ ] Content seeding: at least one real creator with published content on discover page | |
| 193 | + | - [ ] Content seeding items from Pre-Beta section above (subscription tier, license keys, discount codes, purchase flow tests) | |
| 194 | + | - [ ] Outreach: hand-write emails using tiered creator list at `docs/internal/outreach/tiers.md`. Per-creator talking points and pitch angles included. Start with Tier 1 (alpha testers), then Tier 2 (profitable switchers) | |
| 195 | + | ||
| 196 | + | --- | |
| 217 | 197 | ||
| 218 | 198 | --- | |
| 219 | 199 | ||
| @@ -264,7 +244,7 @@ All doc/code fixes, trust gaps, security issues, and doc clarity items are compl | |||
| 264 | 244 | - [ ] Remux where possible (H.264 in MOV -> H.264 in MP4, zero quality loss) | |
| 265 | 245 | - [ ] Auto-generated thumbnails (ffmpeg frame extraction at configurable timestamp) | |
| 266 | 246 | ||
| 267 | - | #### Phase 14E-5: Streaming Tier Features | |
| 247 | + | #### Phase 14E-5: Everything Tier Features | |
| 268 | 248 | - [ ] Adaptive bitrate streaming (HLS/DASH) — multiple quality levels per video | |
| 269 | 249 | - [ ] Audio: FLAC + Opus 128 + Opus 64 quality ladder | |
| 270 | 250 | - [ ] Video: original + 1080p + 720p + 480p quality ladder (VP9 or AV1) | |
| @@ -318,14 +298,10 @@ All doc/code fixes, trust gaps, security issues, and doc clarity items are compl | |||
| 318 | 298 | Weak points identified vs Ko-fi. Ordered by effort/impact. | |
| 319 | 299 | ||
| 320 | 300 | #### Easy Wins | |
| 321 | - | - [x] Tips/donations — accept one-time payments without a product attached | |
| 322 | - | - [x] Revenue splits — record split obligations on purchases/tips for multi-author projects | |
| 323 | - | - [ ] Embeddable widgets — buy button / audio preview / checkout popup for external sites (Ko-fi's embed model is how many creators discover the platform) | |
| 324 | 301 | - [ ] Fundraising goals — display campaign target + progress bar on project page (simple DB field + UI, high engagement signal) | |
| 325 | 302 | ||
| 326 | 303 | #### Medium Effort | |
| 327 | 304 | - [ ] Commissions — listing with portfolio, slot limits, client messaging, upfront payment (Ko-fi has full workflow; artists expect this) | |
| 328 | - | - [ ] Physical product listings — already planned above in Phase 20C | |
| 329 | 305 | ||
| 330 | 306 | #### Structural Gaps (acknowledged, not urgent) | |
| 331 | 307 | - [ ] Zero-cost entry — Ko-fi free tier costs $0 and takes 0% on tips. MNW's minimum is $10/mo. Earn-back credit softens this but doesn't eliminate the barrier for artists earning nothing yet. No action needed — this is a deliberate model difference, not a bug. | |
| @@ -343,7 +319,7 @@ Weak points identified vs Ko-fi. Ordered by effort/impact. | |||
| 343 | 319 | ### Phase 21: Scheduled Content — Remaining | |
| 344 | 320 | - [ ] Pre-save + pre-order, countdown display, calendar view | |
| 345 | 321 | ||
| 346 | - | ### Phase 22: Streaming | |
| 322 | + | ### Phase 22: Live Streaming (Everything tier) | |
| 347 | 323 | - [ ] Trigger: >500 creators, stable 1yr | |
| 348 | 324 | ||
| 349 | 325 | ### Phase 23: DSP | |
| @@ -399,17 +375,9 @@ Weak points identified vs Ko-fi. Ordered by effort/impact. | |||
| 399 | 375 | - [ ] MNW: OG metadata for item/project pages (social sharing cards) | |
| 400 | 376 | - [ ] MNW blog posts: auto-preview linked URLs (same as MT) | |
| 401 | 377 | ||
| 402 | - | ### Type Safety — Remaining | |
| 403 | - | - [ ] `PriceCents(i32)` newtype | |
| 404 | - | ||
| 405 | - | ### Reconsider | |
| 406 | - | - [ ] Cloudflare Email Address Obfuscation (currently OFF — was mangling git clone URLs) | |
| 407 | 378 | ||
| 408 | 379 | --- | |
| 409 | 380 | ||
| 410 | - | ## Audit Items | |
| 411 | - | - [ ] Verify Postmark DKIM selector `20170907043118pm` in Postmark dashboard (returned empty in Run 6 DNS check) | |
| 412 | - | ||
| 413 | 381 | ## Dependencies (blocked on upstream) | |
| 414 | 382 | - [ ] Monitor yara-x for wasmtime >=42.0.2 (11 CVEs including 2 critical — RUSTSEC-2026-0095, -0096) | |
| 415 | 383 | - [ ] Monitor aws-sdk-s3 for lru fix (RUSTSEC-2026-0002) | |
| @@ -419,7 +387,6 @@ Weak points identified vs Ko-fi. Ordered by effort/impact. | |||
| 419 | 387 | ## Deferred | |
| 420 | 388 | - [ ] Corporate structure: holding company (Makecreative Holdings LLC) with subsidiary LLCs for liability isolation if itsall.work launches. Setup checklist, Stripe contingency plan, entity details documented. | |
| 421 | 389 | - [ ] Revenue-share crowdfunding: enable creators to fund projects by selling future revenue shares. 5-phase plan (MVP, controlled rollout, platform features, Reg CF compliance, full launch). Requires securities attorney consultation (~$5K) as first step. Year 1 cost ~$80K, separate from core MNW ops. See financial_dashboard.md. | |
| 422 | - | - [ ] sqlx offline mode | |
| 423 | 390 | - [ ] Team/organization accounts | |
| 424 | 391 | - [ ] Creator @makenot.work email addresses (forwarding-only to creator's real email, vanity address as premium feature). Migadu Mini ($90/yr) for business email; creator addresses via forwarding aliases on Maxi plan or lightweight relay. No mailbox hosting for creators. | |
| 425 | 392 | - [ ] Tax-year revenue summary, invoice generation, 1099 guidance | |
| @@ -429,7 +396,6 @@ Weak points identified vs Ko-fi. Ordered by effort/impact. | |||
| 429 | 396 | - [ ] Podcast private RSS feeds (per-subscriber unique RSS, Spotify integration — Patreon/Substack have this) | |
| 430 | 397 | - [ ] OG image generation | |
| 431 | 398 | - [ ] UTM parameter tracking | |
| 432 | - | - [ ] Notification digest preferences, in-app notification center | |
| 433 | 399 | - [ ] Blog post revision history | |
| 434 | 400 | - [ ] Series/serial ordering, reading progress | |
| 435 | 401 | - [ ] Traffic/referrer tracking | |
| @@ -444,11 +410,11 @@ MNW/server/src/ | |||
| 444 | 410 | lib.rs, main.rs, config.rs, error.rs, auth.rs, db/ | |
| 445 | 411 | storage.rs, payments/, templates/, routes/ | |
| 446 | 412 | git/, git_issues/, synckit_auth.rs, build_runner.rs, validation/ | |
| 447 | - | fingerprint/ (registry, visible stamps, watermarks, streaming) | |
| 413 | + | license_templates.rs (license presets for items) | |
| 448 | 414 | import/ (CSV converter, pipeline, intermediate format) | |
| 449 | 415 | MNW/server/tests/ | |
| 450 | 416 | integration.rs, harness/, workflows/*.rs | |
| 451 | - | MNW/server/migrations/ (001-070) | |
| 417 | + | MNW/server/migrations/ (001-080) | |
| 452 | 418 | MNW/server/templates/ | |
| 453 | 419 | MNW/server/deploy/ | |
| 454 | 420 | MNW/server/site-docs/public/, MNW/server/site-docs/unpublished/ | |
| @@ -459,4 +425,4 @@ MNW/server/docs/filetype_matrix.md (format compatibility, transcoding rules, tie | |||
| 459 | 425 | ``` | |
| 460 | 426 | ||
| 461 | 427 | ## Deps | |
| 462 | - | sqlx 0.8, uuid 1, chrono 0.4, argon2 0.5, tower-sessions 0.15, docengine (path dep, replaces pulldown-cmark + ammonia), aws-sdk-s3 1, async-stripe 0.37, reqwest 0.12, postmark (live), webauthn-rs 0.5 | |
| 428 | + | sqlx 0.8, uuid 1, chrono 0.4, argon2 0.5, tower-sessions 0.14 (store 0.15), docengine (path dep), s3-storage (path dep, wraps aws-sdk-s3 1), async-stripe 0.37, reqwest 0.12, postmark (live), webauthn-rs 0.5 |
| @@ -0,0 +1,123 @@ | |||
| 1 | + | # Makenotwork TODO — Completed | |
| 2 | + | ||
| 3 | + | Items moved from todo.md. See git history for implementation details. | |
| 4 | + | ||
| 5 | + | --- | |
| 6 | + | ||
| 7 | + | ## File Scanning Hardening | |
| 8 | + | - [x] Add timeout to YARA scanning. Fixed: `scanner.set_timeout(30s)` via yara-x native API. | |
| 9 | + | - [x] Nested archive detection: check magic bytes, not just file extensions. Fixed: magic bytes check for ZIP, gzip, 7z, RAR in archive.rs. | |
| 10 | + | ||
| 11 | + | --- | |
| 12 | + | ||
| 13 | + | ## Code Fuzz Findings (2026-04-25) | |
| 14 | + | ||
| 15 | + | Three rounds of adversarial code review. 51 findings total: 50 fixed, 1 accepted risk, 2 deferred. | |
| 16 | + | ||
| 17 | + | ### Rounds 1 & 2 (28 findings) | |
| 18 | + | All critical, serious, and minor findings fixed. See git history for details. | |
| 19 | + | ||
| 20 | + | ### Round 3 | |
| 21 | + | - [x] SubscriptionStatus missing Trialing/Incomplete/IncompleteExpired variants (db/enums.rs) | |
| 22 | + | - [x] SyncKit auth does not block deactivated users (synckit_auth.rs) | |
| 23 | + | - [x] Build token comparison not constant-time (routes/builds.rs) | |
| 24 | + | - [x] Subscription access checks ignore paused_at (db/subscriptions.rs) | |
| 25 | + | - [x] Cover/MediaImage uploads bypass storage cap with i64::MAX (db/creator_tiers.rs) | |
| 26 | + | - [x] Promo code use_count consumed even when user already owns item (db/transactions.rs) | |
| 27 | + | - [x] Idempotency middleware caches empty string instead of real body (metrics.rs) | |
| 28 | + | - [x] OAuth: no dummy hash on user-not-found path (timing leak, routes/oauth.rs) | |
| 29 | + | - [x] OAuth: no password length cap (Argon2 DoS, routes/oauth.rs) | |
| 30 | + | - [x] OAuth: suspended/deactivated users can still authorize (routes/oauth.rs) | |
| 31 | + | - [x] OAuth session validation: result.valid not checked before suspension (routes/oauth.rs) | |
| 32 | + | - [x] OAuth legacy session path ignores deactivated flag (routes/oauth.rs) | |
| 33 | + | - [x] Subscription test fixture missing paused_at field (db/models/subscription.rs) | |
| 34 | + | - [x] Git routes have no rate limiting (routes/git/mod.rs) | |
| 35 | + | - [x] No Content-Security-Policy header (lib.rs) | |
| 36 | + | - [x] /metrics endpoint unprotected (lib.rs) | |
| 37 | + | - [x] Upload confirm: no idempotency, no S3 cleanup on storage error (routes/storage/uploads.rs) | |
| 38 | + | - [x] Version confirm: no idempotency, no S3 cleanup on storage error (routes/storage/versions.rs) | |
| 39 | + | - [x] Image confirm: storage increment after DB write, no idempotency (routes/storage/images.rs) | |
| 40 | + | - [x] Media confirm: no content_type/extension re-validation, no S3 cleanup (routes/storage/media.rs) | |
| 41 | + | - [x] CSRF token not rotated after login -- now regenerated in login_user (auth.rs, csrf.rs) | |
| 42 | + | - [x] Read-modify-write race on sort_order/position -- atomic INSERT...SELECT (db/custom_links.rs, db/collections.rs) | |
| 43 | + | - [x] N+1 reorder loops without transactions -- wrapped in transactions (db/custom_links.rs, db/collections.rs) | |
| 44 | + | - [x] Race condition in custom domain creation -- SELECT FOR UPDATE in transaction (db/custom_domains.rs) | |
| 45 | + | - [x] Double-purchase TOCTOU -- partial unique index on (buyer_id, item_id/project_id) WHERE status='pending' prevents concurrent checkouts (migration 073, checkout handlers) | |
| 46 | + | - [x] Promo code max_uses bypassable on paid path -- use_count now reserved at checkout time, released by scheduler on stale cleanup (migration 074, checkout handlers, scheduler) | |
| 47 | + | ||
| 48 | + | --- | |
| 49 | + | ||
| 50 | + | ## Creator Trust Audit (2026-04-25) | |
| 51 | + | ||
| 52 | + | Systematic creator-perspective audit of docs, legal, code, and competitive positioning. 20+ findings resolved. Key changes: subscription export endpoint, offsite backups with WAM alerting, API key hashing, security headers, fan subscription pause on suspension, account limbo state, support ticket portal, expanded tax/payout/discovery/storage docs, privacy policy updates. | |
| 53 | + | ||
| 54 | + | ### Doc/Code Contradictions | |
| 55 | + | - [x] Payout minimum: aligned payouts.md with Stripe reality ($1 minimum), named Stripe explicitly | |
| 56 | + | - [x] Content protection watermarking: scoped claim to "audio and image files delivered without watermarks", disclosed text fingerprinting | |
| 57 | + | - [x] Mailing list import: reworded as roadmap item, linked to migration guide | |
| 58 | + | - [x] IP retention: added daily scheduler job scrubbing IPs from user_sessions, download_fingerprints, streaming_sessions at 30 days | |
| 59 | + | ||
| 60 | + | ### Missing Creator-Facing Documentation | |
| 61 | + | - [x] Named Stripe explicitly in payouts.md and payments.md (replaced all "payment processor" references) | |
| 62 | + | - [x] Creator application criteria added to getting-started.md (what we look for, what gets rejected) | |
| 63 | + | - [x] Tips documented (new guide/tips.md) | |
| 64 | + | - [x] Bundles documented (new guide/bundles.md) | |
| 65 | + | - [x] Revenue splits documented (new guide/splits.md) | |
| 66 | + | - [x] Currencies/countries: linked to Stripe's own docs (46+ countries, 135+ currencies) rather than maintaining stale tables; fixed grammar from bulk find-replace | |
| 67 | + | ||
| 68 | + | ### Trust Gaps | |
| 69 | + | - [x] 30-day post-termination export window -- migration 076 adds terminated_at; admin terminate route (requires prior suspension); scheduler deletes after 30 days; Stripe subscriptions canceled; termination email sent with export instructions | |
| 70 | + | - [x] Per-item content removal admin action -- migration 075, admin routes (remove/restore), email notifications, publish guards prevent re-publishing removed items | |
| 71 | + | ||
| 72 | + | --- | |
| 73 | + | ||
| 74 | + | ## Creator Trust Audit Round 2 (2026-04-26) | |
| 75 | + | ||
| 76 | + | ### Doc/Code Contradiction | |
| 77 | + | - [x] appeals.md presents independent review as active — no disclaimer. Added disclaimer at top, softened "independent reviewer" language to reflect single-operator reality. | |
| 78 | + | ||
| 79 | + | ### Missing Documentation | |
| 80 | + | - [x] export.md does not mention git repo exclusion. Added note with clone command. | |
| 81 | + | - [x] No documentation on missed subscription payments. Added to tiers.md: past_due behavior, Stripe retries, upload blocking, content stays live. | |
| 82 | + | - [x] API rate limits in api-overview.md were "check response headers" only. Added full table with burst/sustained limits per endpoint category. | |
| 83 | + | - [x] tiers.md mentioned "analytics" without linking to analytics.md. Added links in tier summary and Basic tier detail. | |
| 84 | + | ||
| 85 | + | --- | |
| 86 | + | ||
| 87 | + | ## Ko-fi Comparison Gaps (2026-04-22) — Easy Wins | |
| 88 | + | - [x] Tips/donations — accept one-time payments without a product attached | |
| 89 | + | - [x] Revenue splits — record split obligations on purchases/tips for multi-author projects | |
| 90 | + | ||
| 91 | + | --- | |
| 92 | + | ||
| 93 | + | ## Loose Ends Cleanup (2026-04-27) | |
| 94 | + | ||
| 95 | + | ### Code Fixes | |
| 96 | + | - [x] Cap ClamAV response buffer size — `.take(16_384)` in scanning/clamav.rs (was unbounded `read_to_end`) | |
| 97 | + | ||
| 98 | + | ### Already Done (removed from todo) | |
| 99 | + | - [x] `PriceCents(i32)` newtype — fully implemented in `db/validated_types.rs` | |
| 100 | + | - [x] sqlx offline mode — active in CI (`SQLX_OFFLINE=true` in ci-on-push.sh, run-ci.sh) | |
| 101 | + | - [x] Postmark DKIM selector verification — confirmed complete 2026-04-22 per audit_review.md | |
| 102 | + | ||
| 103 | + | ### Stripped | |
| 104 | + | - Content fingerprinting removed entirely (download fingerprints, visible stamps, ZWC watermarks, audio/image watermark stubs, anti-hotlink checks, streaming session management). Felt icky — tracking buyer downloads to trace leaks is surveillance, not protection. License templates (used by license keys) relocated to `src/license_templates.rs`. DB tables (`download_fingerprints`, `streaming_sessions`) left in place but no longer written to. | |
| 105 | + | - Content-protection docs updated to remove fingerprinting claims. | |
| 106 | + | ||
| 107 | + | ### Archived | |
| 108 | + | - Cloudflare Email Address Obfuscation — disabled because it was mangling git clone URLs. No action needed. | |
| 109 | + | ||
| 110 | + | --- | |
| 111 | + | ||
| 112 | + | ## Creator Trust Audit (2026-04-27, round 3) | |
| 113 | + | ||
| 114 | + | - [x] Removed fictional "download budget" from tiers.md, how-we-work.md, faq.md — code has no separate download quota, all files count toward total storage | |
| 115 | + | - [x] Specified 30-day cancellation grace period duration in tiers.md (was vague "grace period applies") | |
| 116 | + | - [x] Replaced HTML pending comment in payouts.md with visible disclaimer ("not tax advice, consult a professional") | |
| 117 | + | - [x] Added "Downloads are unlimited" to tiers.md — no bandwidth caps or throttling | |
| 118 | + | - [x] Added Stripe account suspension section to payouts.md — documents the risk and what creators can do | |
| 119 | + | - [x] Defined "original creative work" in 01-getting-started.md — covers, remixes, fan fiction, AI-assisted all addressed | |
| 120 | + | - [x] Added post-cancellation retention details to guarantees.md — 30 days published, then hidden (not deleted), resubscribe to restore | |
| 121 | + | - [x] Expanded analytics.md "We don't track" list — explicitly lists page views, referrals, UTM, geo, conversion funnels as absent | |
| 122 | + | - [x] Renamed Streaming tier to Everything — enum, DB migration 079, all templates, all docs, CLAUDE.md, env vars | |
| 123 | + | - [x] Removed "video coming soon" labels from how-we-work.md, items.md — video uploads are implemented |
| @@ -0,0 +1,3 @@ | |||
| 1 | + | -- Rename "streaming" creator tier to "everything" | |
| 2 | + | UPDATE creator_subscriptions SET tier = 'everything' WHERE tier = 'streaming'; | |
| 3 | + | UPDATE users SET creator_tier = 'everything' WHERE creator_tier = 'streaming'; |
| @@ -0,0 +1,12 @@ | |||
| 1 | + | -- Remove demo data seeded in 003_seed_demo.sql. | |
| 2 | + | -- CASCADE handles chapters, item_tags, and other child rows. | |
| 3 | + | ||
| 4 | + | DELETE FROM items WHERE project_id IN ( | |
| 5 | + | '22222222-2222-2222-2222-222222222221', | |
| 6 | + | '22222222-2222-2222-2222-222222222222', | |
| 7 | + | '22222222-2222-2222-2222-222222222223' | |
| 8 | + | ); | |
| 9 | + | ||
| 10 | + | DELETE FROM projects WHERE user_id = '11111111-1111-1111-1111-111111111111'; | |
| 11 | + | ||
| 12 | + | DELETE FROM users WHERE id = '11111111-1111-1111-1111-111111111111'; |