max / docengine
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
20 files changed,
+1721 insertions,
-0 deletions
| @@ -139,6 +139,227 @@ | |||
| 139 | 139 | .to_string() | |
| 140 | 140 | } | |
| 141 | 141 | ||
| 142 | + | /// What every rendering path must be true of, whatever else it does. | |
| 143 | + | /// | |
| 144 | + | /// **The oracle lives here rather than in the fuzz target**, and that is the | |
| 145 | + | /// point of the arrangement rather than a filing preference. `tests/regressions.rs` | |
| 146 | + | /// replays the committed corpus against this same function on stable, so a crash | |
| 147 | + | /// the fuzzer finds becomes a unit test by copying one file into `fuzz/regressions/`, | |
| 148 | + | /// and neither side can drift into checking less than the other. The pattern is | |
| 149 | + | /// `MNW/shared/git-command`'s, copied deliberately. | |
| 150 | + | /// | |
| 151 | + | /// Infra `15991c40`. The doors, counted before the harness was written as that task | |
| 152 | + | /// instructs: this crate's render entry points are called from **14 files across 6 | |
| 153 | + | /// repos** -- MNW server and multithreaded, goingson, balanced_breakfast, | |
| 154 | + | /// mnw-assumptions, bb-core -- with `render_permissive` the most used (10 sites), | |
| 155 | + | /// then `render_standard` (5), `sanitize_html` (3), `render_strict` (3), | |
| 156 | + | /// `restrict_media_hosts` (2), `render_chat` (1). There is one implementation | |
| 157 | + | /// behind all of them, so this is a single authority with many consumers rather | |
| 158 | + | /// than a grammar with two parsers, and a fuzz target is the right shape. | |
| 159 | + | pub mod oracle { | |
| 160 | + | /// Element names no output of any preset may contain. | |
| 161 | + | /// | |
| 162 | + | /// Checked as parsed tag NAMES rather than as substrings, for the reason | |
| 163 | + | /// written on [`check_output`]. | |
| 164 | + | const FORBIDDEN_TAGS: &[&str] = &[ | |
| 165 | + | "script", "iframe", "object", "embed", "form", "svg", "math", "base", "meta", "link", | |
| 166 | + | "style", "template", "noscript", | |
| 167 | + | ]; | |
| 168 | + | ||
| 169 | + | /// Attribute values that must never appear on a URL-bearing attribute. | |
| 170 | + | const FORBIDDEN_SCHEMES: &[&str] = &["javascript:", "vbscript:", "data:text/html"]; | |
| 171 | + | ||
| 172 | + | /// Attributes whose value is fetched or navigated to, so a scheme in one is | |
| 173 | + | /// a live capability rather than a string. | |
| 174 | + | const URL_ATTRS: &[&str] = &[ | |
| 175 | + | "href", | |
| 176 | + | "src", | |
| 177 | + | "srcset", | |
| 178 | + | "action", | |
| 179 | + | "formaction", | |
| 180 | + | "poster", | |
| 181 | + | "xlink:href", | |
| 182 | + | "data", | |
| 183 | + | "codebase", | |
| 184 | + | "background", | |
| 185 | + | ]; | |
| 186 | + | ||
| 187 | + | /// Assert the safety floor on one rendered output. | |
| 188 | + | /// | |
| 189 | + | /// **Parses tag and attribute NAMES; never pattern-matches the whole | |
| 190 | + | /// string.** That distinction is the correctness of this function rather | |
| 191 | + | /// than an optimisation, and the fuzzer proved it twice within four minutes | |
| 192 | + | /// of the target first running -- both times against the oracle, not the | |
| 193 | + | /// sanitizer: | |
| 194 | + | /// | |
| 195 | + | /// 1. A whole-string substring scan fired on a markdown image whose title | |
| 196 | + | /// quote made it fail to parse, so it fell through as literal prose | |
| 197 | + | /// reading `)`. ` onerror` was in the output | |
| 198 | + | /// as escaped TEXT while the real `<img>` beside it had been stripped | |
| 199 | + | /// clean. | |
| 200 | + | /// 2. Narrowing the scan to inside `<...>` was not enough either. It then | |
| 201 | + | /// fired on `<p title="</noscript><img src=x onerror=...>">`, | |
| 202 | + | /// where the string sits inside an entity-escaped attribute VALUE and a | |
| 203 | + | /// browser renders it as tooltip text. | |
| 204 | + | /// | |
| 205 | + | /// Both are the sanitizer working. A check that reports correct behaviour as | |
| 206 | + | /// a finding is worse than no check: it is the 3am false alarm that trains | |
| 207 | + | /// people to skim the tier, which is the failure the whole evidence | |
| 208 | + | /// programme exists to avoid. So the oracle skips quoted values by | |
| 209 | + | /// construction, and escaped content inside one can no longer reach it. | |
| 210 | + | /// | |
| 211 | + | /// Splitting on `<` is sound BECAUSE of what is under test: a sanitizer that | |
| 212 | + | /// escapes text is the premise, so an unescaped `<` in the output can only | |
| 213 | + | /// be a tag. If that ever stopped being true, the tag-name assertion is what | |
| 214 | + | /// would fire, which is the right failure. | |
| 215 | + | /// | |
| 216 | + | /// # Panics | |
| 217 | + | /// If any tag is a forbidden element, carries an `on*` handler, or points a | |
| 218 | + | /// URL-bearing attribute at a forbidden scheme. | |
| 219 | + | pub fn check_output(preset: &str, input: &str, out: &str) { | |
| 220 | + | let lower = out.to_ascii_lowercase(); | |
| 221 | + | let bytes = lower.as_bytes(); | |
| 222 | + | let fail = | |
| 223 | + | |what: &str| -> ! { panic!("{preset} {what}\n input: {input:?}\n output: {out:?}") }; | |
| 224 | + | ||
| 225 | + | let mut i = 0; | |
| 226 | + | while let Some(off) = lower[i..].find('<') { | |
| 227 | + | let mut p = i + off + 1; | |
| 228 | + | if bytes.get(p) == Some(&b'/') { | |
| 229 | + | p += 1; | |
| 230 | + | } | |
| 231 | + | let name_start = p; | |
| 232 | + | while p < bytes.len() | |
| 233 | + | && (bytes[p].is_ascii_alphanumeric() || bytes[p] == b':' || bytes[p] == b'-') | |
| 234 | + | { | |
| 235 | + | p += 1; | |
| 236 | + | } | |
| 237 | + | let tag = &lower[name_start..p]; | |
| 238 | + | if FORBIDDEN_TAGS.contains(&tag) { | |
| 239 | + | fail(&format!("emitted a <{tag}> element")); | |
| 240 | + | } | |
| 241 | + | ||
| 242 | + | // Attributes, until the tag closes. Quoted values are skipped whole, | |
| 243 | + | // which is what keeps escaped text inside one out of the scan. | |
| 244 | + | while p < bytes.len() && bytes[p] != b'>' { | |
| 245 | + | if bytes[p].is_ascii_whitespace() || bytes[p] == b'/' { | |
| 246 | + | p += 1; | |
| 247 | + | continue; | |
| 248 | + | } | |
| 249 | + | let attr_start = p; | |
| 250 | + | while p < bytes.len() | |
| 251 | + | && !bytes[p].is_ascii_whitespace() | |
| 252 | + | && bytes[p] != b'=' | |
| 253 | + | && bytes[p] != b'>' | |
| 254 | + | { | |
| 255 | + | p += 1; | |
| 256 | + | } | |
| 257 | + | let attr = &lower[attr_start..p]; | |
| 258 | + | if attr.starts_with("on") && attr.len() > 2 { | |
| 259 | + | fail(&format!("emitted the event handler {attr:?} on <{tag}>")); | |
| 260 | + | } | |
| 261 | + | while p < bytes.len() && bytes[p].is_ascii_whitespace() { | |
| 262 | + | p += 1; | |
| 263 | + | } | |
| 264 | + | if bytes.get(p) != Some(&b'=') { | |
| 265 | + | continue; | |
| 266 | + | } | |
| 267 | + | p += 1; | |
| 268 | + | while p < bytes.len() && bytes[p].is_ascii_whitespace() { | |
| 269 | + | p += 1; | |
| 270 | + | } | |
| 271 | + | let (value, next) = match bytes.get(p) { | |
| 272 | + | Some(&q @ (b'"' | b'\'')) => { | |
| 273 | + | let vs = p + 1; | |
| 274 | + | let mut e = vs; | |
| 275 | + | while e < bytes.len() && bytes[e] != q { | |
| 276 | + | e += 1; | |
| 277 | + | } | |
| 278 | + | (&lower[vs..e.min(bytes.len())], (e + 1).min(bytes.len())) | |
| 279 | + | } | |
| 280 | + | _ => { | |
| 281 | + | let vs = p; | |
| 282 | + | let mut e = vs; | |
| 283 | + | while e < bytes.len() && !bytes[e].is_ascii_whitespace() && bytes[e] != b'>' | |
| 284 | + | { | |
| 285 | + | e += 1; | |
| 286 | + | } | |
| 287 | + | (&lower[vs..e], e) | |
| 288 | + | } | |
| 289 | + | }; | |
| 290 | + | if URL_ATTRS.contains(&attr) { | |
| 291 | + | let v = value.trim(); | |
| 292 | + | for bad in FORBIDDEN_SCHEMES { | |
| 293 | + | if v.starts_with(bad) { | |
| 294 | + | fail(&format!("pointed {attr}= at {bad:?} on <{tag}>")); | |
| 295 | + | } | |
| 296 | + | } | |
| 297 | + | } | |
| 298 | + | p = next; | |
| 299 | + | } | |
| 300 | + | i = p.max(i + off + 1); | |
| 301 | + | } | |
| 302 | + | } | |
| 303 | + | ||
| 304 | + | /// Run every rendering entry point over one input and assert what must hold. | |
| 305 | + | /// | |
| 306 | + | /// Three properties: | |
| 307 | + | /// | |
| 308 | + | /// 1. **The safety floor**, on every preset. See [`check_output`]. | |
| 309 | + | /// 2. **The floor survives a second sanitization.** This is the mutation-XSS | |
| 310 | + | /// property and the one worth having: the risk is that re-parsing the | |
| 311 | + | /// output reveals markup the first pass did not emit, because somewhere | |
| 312 | + | /// downstream something parses the same bytes twice. | |
| 313 | + | /// 3. **`sanitize_html` reaches a fixed point by the second pass.** | |
| 314 | + | /// | |
| 315 | + | /// ## Why (3) rather than plain idempotence, which is what this asserted first | |
| 316 | + | /// | |
| 317 | + | /// Exact idempotence is FALSE, and the fuzzer proved it in thirty minutes on | |
| 318 | + | /// input built from the XSS seeds: pass one can emit a `<p>` nested inside a | |
| 319 | + | /// `<p>` through an `<a>`, and pass two restructures it because that is what | |
| 320 | + | /// html5ever's tree builder does with malformed nesting. Nothing dangerous | |
| 321 | + | /// appears in either output -- the floor holds on both -- and the difference | |
| 322 | + | /// is upstream tree-building we do not control. | |
| 323 | + | /// | |
| 324 | + | /// So exact equality is the wrong STRENGTH, not the wrong idea. It fires | |
| 325 | + | /// forever on malformed input nobody sends, which would bury the property | |
| 326 | + | /// that matters under noise -- and a check that cries wolf is the failure | |
| 327 | + | /// this whole tier is built to avoid. Convergence is true, checkable, and | |
| 328 | + | /// still catches the real thing: a sanitizer that never settles is one where | |
| 329 | + | /// each parse sees something new. Measured on the input that found this, | |
| 330 | + | /// `s(s(x)) == s(s(s(x)))` holds. | |
| 331 | + | /// | |
| 332 | + | /// The input itself is committed under `fuzz/regressions/`, so the pair of | |
| 333 | + | /// properties is pinned against exactly the case that shaped them. | |
| 334 | + | pub fn check(input: &str) { | |
| 335 | + | for (name, out) in [ | |
| 336 | + | ("permissive", super::render_permissive(input)), | |
| 337 | + | ("standard", super::render_standard(input)), | |
| 338 | + | ("strict", super::render_strict(input)), | |
| 339 | + | ("chat", super::render_chat(input)), | |
| 340 | + | ("phrase", super::render_phrase(input)), | |
| 341 | + | ("sanitize_html", super::sanitize_html(input)), | |
| 342 | + | ] { | |
| 343 | + | check_output(name, input, &out); | |
| 344 | + | ||
| 345 | + | // Re-sanitization, on the one entry point where it is meaningful: | |
| 346 | + | // `sanitize_html` takes HTML and returns HTML, so its output is a | |
| 347 | + | // legal input to itself. The render presets take markdown, so | |
| 348 | + | // feeding their HTML back in asks a different question and would | |
| 349 | + | // fail for reasons that are not defects. | |
| 350 | + | if name == "sanitize_html" { | |
| 351 | + | let twice = super::sanitize_html(&out); | |
| 352 | + | check_output("sanitize_html (second pass)", input, &twice); | |
| 353 | + | let thrice = super::sanitize_html(&twice); | |
| 354 | + | assert_eq!( | |
| 355 | + | twice, thrice, | |
| 356 | + | "sanitize_html had not settled by the third pass\n input: {input:?}\n twice: {twice:?}\n thrice: {thrice:?}" | |
| 357 | + | ); | |
| 358 | + | } | |
| 359 | + | } | |
| 360 | + | } | |
| 361 | + | } | |
| 362 | + | ||
| 142 | 363 | #[cfg(test)] | |
| 143 | 364 | mod top_level_tests { | |
| 144 | 365 | use super::*; |
| @@ -1,0 +1,4 @@ | |||
| 1 | + | target | |
| 2 | + | corpus | |
| 3 | + | artifacts | |
| 4 | + | coverage |
| @@ -1,0 +1,31 @@ | |||
| 1 | + | [package] | |
| 2 | + | name = "docengine-fuzz" | |
| 3 | + | version = "0.0.0" | |
| 4 | + | publish = false | |
| 5 | + | edition = "2024" | |
| 6 | + | ||
| 7 | + | [package.metadata] | |
| 8 | + | cargo-fuzz = true | |
| 9 | + | ||
| 10 | + | [dependencies] | |
| 11 | + | # `arbitrary` with `derive` is what lets the target take `&str` instead of | |
| 12 | + | # `&[u8]`. The input is markdown and HTML, both text grammars, and byte input | |
| 13 | + | # would spend most of the fuzzer's budget rediscovering UTF-8 before it reached | |
| 14 | + | # an angle bracket. | |
| 15 | + | libfuzzer-sys = { version = "0.4", features = ["arbitrary-derive"] } | |
| 16 | + | ||
| 17 | + | [dependencies.docengine] | |
| 18 | + | path = ".." | |
| 19 | + | # Every feature, because the doors counted for infra `15991c40` reach across | |
| 20 | + | # them: `restrict_media_hosts` and `img_to_video` are `media-urls`, and the | |
| 21 | + | # consumers that call them are the same consumers that call the presets. A | |
| 22 | + | # default-features fuzz of a crate whose consumers turn features on is fuzzing | |
| 23 | + | # a build nobody ships. | |
| 24 | + | features = ["full"] | |
| 25 | + | ||
| 26 | + | [[bin]] | |
| 27 | + | name = "render" | |
| 28 | + | path = "fuzz_targets/render.rs" | |
| 29 | + | test = false | |
| 30 | + | doc = false | |
| 31 | + | bench = false |
| @@ -1,0 +1,36 @@ | |||
| 1 | + | //! Structured fuzz over docengine's rendering and sanitization chain. | |
| 2 | + | //! | |
| 3 | + | //! Row 3 of `astra-soak-overview`, and the crate with the widest reach of any | |
| 4 | + | //! soak target so far. The doors were counted before this was written, as infra | |
| 5 | + | //! `15991c40` instructs: **14 files across 6 repos** call these entry points -- | |
| 6 | + | //! MNW server and multithreaded, goingson, balanced_breakfast, mnw-assumptions, | |
| 7 | + | //! bb-core -- and there is one implementation behind all of them. So this is a | |
| 8 | + | //! single authority with many consumers rather than a grammar with two parsers, | |
| 9 | + | //! which is what makes a fuzz target the right shape here and made a shared | |
| 10 | + | //! crate the right answer for `git_ssh`. | |
| 11 | + | //! | |
| 12 | + | //! ## The oracle lives in the crate, not here | |
| 13 | + | //! | |
| 14 | + | //! Everything asserted is `docengine::oracle::check`. That is deliberate: the | |
| 15 | + | //! committed regression replay in `tests/regressions.rs` calls the same function | |
| 16 | + | //! on stable, so a crash found here becomes a unit test by copying one file, and | |
| 17 | + | //! neither side can drift into checking less than the other. | |
| 18 | + | //! | |
| 19 | + | //! What it asserts: a safety floor on the output of every preset (no script, | |
| 20 | + | //! iframe, object, embed, form, svg, math, `javascript:`, `vbscript:` or event | |
| 21 | + | //! handler, however the input was shaped), and that `sanitize_html` is | |
| 22 | + | //! idempotent. The second is the one worth having and nothing else in the crate | |
| 23 | + | //! checks it: a sanitizer that is not idempotent is the mutation-XSS shape, | |
| 24 | + | //! where a second parse of the same bytes sees different markup than the first. | |
| 25 | + | //! | |
| 26 | + | //! Not-panicking is the weakest thing a fuzz target can assert, and a target | |
| 27 | + | //! that asserts only that reports clean forever while a preset quietly starts | |
| 28 | + | //! emitting an `onerror` attribute. | |
| 29 | + | ||
| 30 | + | #![no_main] | |
| 31 | + | ||
| 32 | + | use libfuzzer_sys::fuzz_target; | |
| 33 | + | ||
| 34 | + | fuzz_target!(|input: &str| { | |
| 35 | + | docengine::oracle::check(input); | |
| 36 | + | }); |
| @@ -1,0 +1,33 @@ | |||
| 1 | + | <img src=x onerror=alert(1)> | |
| 2 | + | <svg/onload=alert(1)> | |
| 3 | + | <a href="javascript:alert(1)">x</a> | |
| 4 | + | <iframe src="data:text/html,<script>alert(1)</script>"></iframe> | |
| 5 | + | <math><mtext><table><mglyph><style><!--</style><img src=x onerror=alert(1)> | |
| 6 | + | <data:tex/thtml,<script>alert(1)</script>"></iframe> | |
| 7 | + | <mat.h src=x onerror=alert(1)> | |
| 8 | + | <svg/onload=alert(1)> | |
| 9 | + | <a href="javascript:alert(1)">x</a> | |
| 10 | + | <iframe src="data:text/html,<script>alert(1)</script>"></iframe> | |
| 11 | + | <math><mtext><table><mglyph><style><!--</style><img src=x onerror=alert(1)> | |
| 12 | + | <data:tex/thtml,<script>alert(1)</script>"></iframe> | |
| 13 | + | <mat.h><mtext><table><mglyph><style><!--</style><img src=x onerror=alert(1)> | |
| 14 | + | <noscript><p title="</noscript><img src=x onerror=alert(1)>"> | |
| 15 | + | <![CDATA[<script>alert(1)</script>]]> | |
| 16 | + | <form><button formaction="javascript:alert(1)">x</button></form> | |
| 17 | + | <base href="//evil.example/"> | |
| 18 | + | <a href="javascript:alert(1)">enoscript><p title="</noscript><img src=x onerror=alert(1)>"> | |
| 19 | + | <![C><mtext><table><mglyph><style><!--</style><img src=x onerror=alert(1)> | |
| 20 | + | <noscript><p title="</noscript><img src=x onerror=alert(1)>"> | |
| 21 | + | <![CDATA[<script>alert(1)</script>]]> | |
| 22 | + | <form><button formaction="javascript:alert(1)">x</button></form> | |
| 23 | + | <base href="//evil.example/"> | |
| 24 | + | <a href="javascript:alert(1)">enoscript><p title="</noscript><img src=x onerror=alert(1)>"> | |
| 25 | + | <![CDATA[<script>alert(1)</script>]]> | |
| 26 | + | <form><button formaction="javascrme> | |
| 27 | + | <mat.h><mtext><table><mg(1)">enoscript><p title="</noscript><img src=x onerror=alert(1)>"> | |
| 28 | + | <![CDATA[<script>alert(1)</script>]]> | |
| 29 | + | <form><button formaction="javascript:alert(1)">x</button></form> | |
| 30 | + | <base href="//evil.example/"> | |
| 31 | + | <a href="javascript:alipt:alert(1)">x</button></form> | |
| 32 | + | <base href="//evil.example/"> | |
| 33 | + | <a href="javascript:alert(1)">entity-escaped scheme</a> |
| @@ -1,0 +1,16 @@ | |||
| 1 | + | # Seeds | |
| 2 | + | ||
| 3 | + | Curated, read-only, and small. These are the inputs a person chose: real site | |
| 4 | + | docs for the ordinary shapes, plus the classic XSS payloads and the two cases | |
| 5 | + | that caught the oracle out on its first run (a markdown image that falls through | |
| 6 | + | as prose carrying ` onerror=`, and an entity-escaped payload inside a `title` | |
| 7 | + | attribute value). | |
| 8 | + | ||
| 9 | + | They are NOT the corpus. Run the fuzzer with the corpus first and these second: | |
| 10 | + | ||
| 11 | + | cargo +nightly fuzz run render fuzz/corpus/render fuzz/seeds/render -- -max_total_time=1800 | |
| 12 | + | ||
| 13 | + | libFuzzer writes new inputs into the FIRST directory only, so this arrangement | |
| 14 | + | keeps the curated set curated and lets `fuzz/corpus/` grow. Passing seeds as the | |
| 15 | + | first argument by mistake put 3,042 machine-generated files in here on | |
| 16 | + | 2026-08-23, which is how the note came to be written down. |
| @@ -1,0 +1,181 @@ | |||
| 1 | + | # Payments & Refunds | |
| 2 | + | ||
| 3 | + | How payments work on Makenotwork. | |
| 4 | + | ||
| 5 | + | --- | |
| 6 | + | ||
| 7 | + | ## The Short Version | |
| 8 | + | ||
| 9 | + | Stripe handles all payments. You're the merchant of record. We don't take a cut of your revenue. Fans handle refunds with you or dispute via their bank. | |
| 10 | + | ||
| 11 | + | --- | |
| 12 | + | ||
| 13 | + | ## How Payments Work | |
| 14 | + | ||
| 15 | + | ### Fan Payments | |
| 16 | + | ||
| 17 | + | When fans buy your content or join a membership: | |
| 18 | + | ||
| 19 | + | 1. Fan pays via Stripe (~{{ stripe.percent | percent }} + {{ stripe.fixed | money }} per transaction) | |
| 20 | + | 2. Funds go directly to your connected Stripe account | |
| 21 | + | 3. Deposits to your bank on your chosen schedule | |
| 22 | + | 4. We never touch or hold your money | |
| 23 | + | ||
| 24 | + | ### Platform Membership | |
| 25 | + | ||
| 26 | + | Your monthly Makenotwork membership (${{ tiers.standard.basic }}-${{ tiers.standard.everything }}) is separate: | |
| 27 | + | ||
| 28 | + | - Billed to your payment method | |
| 29 | + | - Goes to us for platform access | |
| 30 | + | - Has nothing to do with your fan revenue | |
| 31 | + | ||
| 32 | + | --- | |
| 33 | + | ||
| 34 | + | ## You're the Merchant of Record | |
| 35 | + | ||
| 36 | + | When you connect Stripe, it creates an account for you: | |
| 37 | + | ||
| 38 | + | - **You are the merchant** - Fans are paying you, not us | |
| 39 | + | - **You set prices** - Including pay-what-you-want options | |
| 40 | + | - **You handle disputes** - Chargebacks and refunds are your responsibility | |
| 41 | + | - **Your Stripe account is yours** - If you leave, it stays with you | |
| 42 | + | ||
| 43 | + | The tradeoff: you absorb the (typically rare) chargeback risk. | |
| 44 | + | ||
| 45 | + | --- | |
| 46 | + | ||
| 47 | + | ## Payouts | |
| 48 | + | ||
| 49 | + | You control payout timing from your [Stripe dashboard](https://dashboard.stripe.com): standard (2-3 days), daily, weekly, monthly, or [instant](https://docs.stripe.com/payouts/instant-payouts) (1% fee in CA/EU/UK/SG/NO/HK/MY; 1.5% fee in US/AU/NZ/AE; min $0.50 USD or local equivalent, per [Stripe Instant Payouts docs](https://docs.stripe.com/payouts/instant-payouts)). See [Receiving Payouts](../guide/payouts.md) for full details on schedules, minimums, and international payouts. Payout schedule options are documented at https://docs.stripe.com/payouts. | |
| 50 | + | ||
| 51 | + | --- | |
| 52 | + | ||
| 53 | + | ## Refunds | |
| 54 | + | ||
| 55 | + | ### Our Policy | |
| 56 | + | ||
| 57 | + | Refund decisions are yours; you're the merchant of record. You can issue a full refund directly from the sale in your MNW dashboard, or handle full and partial refunds from your Stripe dashboard. | |
| 58 | + | ||
| 59 | + | ### How Fans Request Refunds | |
| 60 | + | ||
| 61 | + | Fans should contact you directly. You can: | |
| 62 | + | ||
| 63 | + | - Issue a full refund from the sale in your MNW dashboard, or a full or partial refund via your [Stripe dashboard](https://dashboard.stripe.com) | |
| 64 | + | - Offer alternative resolution (access fix, different content) | |
| 65 | + | - Decline if the purchase was delivered as promised | |
| 66 | + | ||
| 67 | + | ### Our Recommendation | |
| 68 | + | ||
| 69 | + | Clear refund policies reduce disputes. Consider: | |
| 70 | + | ||
| 71 | + | - Stating your policy on your page | |
| 72 | + | - Being generous with genuine mistakes | |
| 73 | + | - Responding promptly to requests | |
| 74 | + | ||
| 75 | + | A $5 refund is cheaper than a ${{ stripe.dispute_fee | int }} chargeback fee. | |
| 76 | + | ||
| 77 | + | --- | |
| 78 | + | ||
| 79 | + | ## Chargebacks | |
| 80 | + | ||
| 81 | + | If a fan disputes a charge with their bank: | |
| 82 | + | ||
| 83 | + | 1. **Your balance is debited** - Disputed amount plus fee (~${{ stripe.dispute_fee | int }}) | |
| 84 | + | 2. **You respond through Stripe** - Provide evidence the charge was legitimate | |
| 85 | + | 3. **Bank decides** - You either get the money back or lose it | |
| 86 | + | ||
| 87 | + | ### Why This Model | |
| 88 | + | ||
| 89 | + | The alternative (us being merchant of record) would mean we'd take on chargeback risk and price that into fees, hold reserves from your earnings, and have incentive to restrict what you can sell. | |
| 90 | + | ||
| 91 | + | ### Reducing Chargeback Risk | |
| 92 | + | ||
| 93 | + | Most chargebacks come from: | |
| 94 | + | ||
| 95 | + | - Unrecognized charges (fan forgot they joined a membership) | |
| 96 | + | - Unauthorized use (stolen card) | |
| 97 | + | - Dissatisfaction (fan expected something different) | |
| 98 | + | ||
| 99 | + | Clear communication prevents most disputes. Make sure fans know what they're paying for, how your billing descriptor appears on statements, and how to cancel memberships. See [Receiving Payouts](../guide/payouts.md#chargebacks-disputes) for dispute resolution details. | |
| 100 | + | ||
| 101 | + | --- | |
| 102 | + | ||
| 103 | + | ## Taxes | |
| 104 | + | ||
| 105 | + | ### What We Provide | |
| 106 | + | ||
| 107 | + | - **Transaction records** - Exportable history of all payments | |
| 108 | + | - **1099-K** (US creators) - Issued by Stripe if you meet [reporting thresholds](https://support.stripe.com/topics/1099-tax-forms) | |
| 109 | + | - **Invoices** - For your platform membership | |
| 110 | + | ||
| 111 | + | ### Your Responsibilities | |
| 112 | + | ||
| 113 | + | You're responsible for: | |
| 114 | + | ||
| 115 | + | - Reporting income from fan payments | |
| 116 | + | - Collecting and remitting sales tax if required in your jurisdiction | |
| 117 | + | - Understanding tax obligations for digital goods in your location | |
| 118 | + | ||
| 119 | + | ### VAT, GST, and Sales Tax | |
| 120 | + | ||
| 121 | + | If you sell digital goods to fans in the EU, UK, Australia, Canada, or other jurisdictions with digital sales tax, you may be required to collect and remit VAT, GST, or sales tax, even if you are outside those jurisdictions. | |
| 122 | + | ||
| 123 | + | Stripe may collect sales tax automatically in some regions depending on your account configuration. Check your [Stripe Tax settings](https://dashboard.stripe.com/tax) to see what's enabled. | |
| 124 | + | ||
| 125 | + | Since we do not act as Merchant of Record, tax collection and remittance is your responsibility. Consult a tax professional if you're unsure. | |
| 126 | + | ||
| 127 | + | ### Platform Fee Deductions | |
| 128 | + | ||
| 129 | + | Your Makenotwork membership fee may be deductible as a business expense. Keep your receipts. | |
| 130 | + | ||
| 131 | + | --- | |
| 132 | + | ||
| 133 | + | ## International Payments | |
| 134 | + | ||
| 135 | + | Each creator sells in one currency, taken from their Stripe account. Supported: USD, CAD, GBP, AUD, NZD, EUR. Every price that creator sets, and every charge and subscription for them, is in that currency. | |
| 136 | + | ||
| 137 | + | To sell here, your country must be supported by [Stripe Connect](https://stripe.com/global) and your Stripe account must settle in one of those six. Those are two separate conditions and both must hold. | |
| 138 | + | ||
| 139 | + | ### Who Pays for Currency Conversion | |
| 140 | + | ||
| 141 | + | The buyer does, and the buyer chooses how. When a buyer's card is in a different currency from the creator's, checkout offers two paths: | |
| 142 | + | ||
| 143 | + | 1. **Stripe converts at checkout.** Stripe presents the price in the buyer's currency and charges that. Stripe's exchange rate includes a currency conversion fee, which Stripe sets and which is between 2% and 4%. Stripe does not report that fee to us as a separate figure, so we do not itemise it and we do not estimate it. Stripe displays the exact converted total on its own checkout page before the buyer confirms, and the buyer's receipt from us records the exact amount charged. | |
| 144 | + | 2. **The buyer's bank converts.** The charge is made in the creator's currency and the buyer's card issuer converts at its own rate, which is set by that issuer. We cannot see it, display it, or estimate it, and we do not. | |
| 145 | + | ||
| 146 | + | In both cases the creator receives their price in their own currency and the buyer bears the cost of conversion. Neither path involves an exchange rate set by Makenotwork; we hold no rates and perform no conversions. | |
| 147 | + | ||
| 148 | + | ### Revenue Splits | |
| 149 | + | ||
| 150 | + | A project owner can invite another creator to a share of that project's revenue. **An invitation has to be accepted before it pays anything.** While it is pending the percentage is reserved, so the owner cannot promise it to someone else, but sales in the meantime belong entirely to the owner. A share begins at acceptance and is not backdated. | |
| 151 | + | ||
| 152 | + | Declining removes the invitation and frees the percentage. There is no obligation to accept, and nothing happens if you ignore it. | |
| 153 | + | ||
| 154 | + | ### Revenue Splits Across Currencies | |
| 155 | + | ||
| 156 | + | A revenue split is denominated in the currency of the project that generated it, which is that project's owner's currency. If you receive a split in a currency you do not settle in, Stripe converts it when it reaches you and the conversion cost comes out of your share, not the project's. We cannot tell you that rate in advance, because Stripe sets it at payout. | |
| 157 | + | ||
| 158 | + | You are shown this before you accept, which is the reason acceptance exists: nobody should carry a conversion cost they were never given the chance to refuse. The project owner is told the same thing when they send the invitation. | |
| 159 | + | ||
| 160 | + | See [Receiving Payouts](../guide/payouts.md#international-creators) for the detail. | |
| 161 | + | ||
| 162 | + | --- | |
| 163 | + | ||
| 164 | + | ## What We Don't Do | |
| 165 | + | ||
| 166 | + | - **Hold creator funds** - Money goes directly to your Stripe account | |
| 167 | + | - **Take a percentage** - Our fee is flat monthly membership only | |
| 168 | + | - **Control your pricing** - Set whatever prices you want | |
| 169 | + | - **Process payments ourselves** - Stripe handles everything | |
| 170 | + | - **Provide tax advice** - Consult a professional | |
| 171 | + | ||
| 172 | + | --- | |
| 173 | + | ||
| 174 | + | ## See Also | |
| 175 | + | ||
| 176 | + | - [You're the Merchant of Record](../about/merchant-of-record.md): what it means, pros and cons, tax tools | |
| 177 | + | - [Creator Guarantees](../about/guarantees.md): our commitments on revenue | |
| 178 | + | - [Pricing Tiers](../guide/tiers.md): tier features and pricing | |
| 179 | + | - [Stripe Global](https://stripe.com/global): supported countries | |
| 180 | + | - [Stripe: What You Need to Know](../guide/stripe.md): fees by country, currency and conversion, Stripe Tax | |
| 181 | + | - [Stripe Connect](https://stripe.com/connect): how the payment model works |
| @@ -1,0 +1,196 @@ | |||
| 1 | + | # Content Moderation & Enforcement | |
| 2 | + | ||
| 3 | + | What happens when accounts violate our policies, and what you should know about how moderation works right now. | |
| 4 | + | ||
| 5 | + | --- | |
| 6 | + | ||
| 7 | + | ## Current Limitations | |
| 8 | + | ||
| 9 | + | Moderation is currently handled by one person. Decisions are fast but not independently reviewable. Independent appeal review is a planned commitment in our [written guarantees](../about/guarantees.md#planned-guarantees), and hiring a second person is the top financial priority. Until then, the founder makes moderation decisions directly and in good faith, and every decision can be appealed. | |
| 10 | + | ||
| 11 | + | --- | |
| 12 | + | ||
| 13 | + | ## Our Approach | |
| 14 | + | ||
| 15 | + | Context and intent matter. We evaluate work as a whole, not isolated elements. Satire, critique, historical documentation, and artistic exploration are considered in full context. We enforce policies against harassment, illegal content, and fraud. We reserve the right to refuse service to anyone whose conduct makes the platform worse for everyone else. | |
| 16 | + | ||
| 17 | + | --- | |
| 18 | + | ||
| 19 | + | ## What's Not Allowed | |
| 20 | + | ||
| 21 | + | ### Harmful Content | |
| 22 | + | ||
| 23 | + | - **Dehumanization, harassment, and incitement to violence**: Content that attacks, degrades, or encourages violence toward individuals or groups | |
| 24 | + | - **Stricter review for content targeting marginalized groups**: Content that would be tolerable if directed at dominant groups may be removed when it targets communities facing systemic discrimination | |
| 25 | + | - **Doxxing**: Sharing private information (addresses, phone numbers, workplaces, etc.) without consent | |
| 26 | + | ||
| 27 | + | ### Platform Integrity | |
| 28 | + | ||
| 29 | + | - **Spam and fraud**: Deceptive practices, scams, or manipulative content | |
| 30 | + | - **Impersonation**: Misrepresenting identity to deceive others | |
| 31 | + | - **Illegal content**: Content that violates applicable law | |
| 32 | + | ||
| 33 | + | ### Content Type Restrictions | |
| 34 | + | ||
| 35 | + | - **Adult/NSFW content**: Not permitted on Makenotwork. We intend to launch a separate platform for adult creators with identical commitments when infrastructure is ready | |
| 36 | + | - **Unqualified promotion**: Creators promoting health products, financial services, or similar without appropriate qualification may be subject to scrutiny or moderation | |
| 37 | + | ||
| 38 | + | --- | |
| 39 | + | ||
| 40 | + | ## On Marginalized Groups | |
| 41 | + | ||
| 42 | + | We apply stricter review when content targets groups that face systemic discrimination or historical oppression. | |
| 43 | + | ||
| 44 | + | **Why this exists:** Harmful content targeting marginalized groups contributes to real-world discrimination and violence. Identical rules applied without context produce unequal effects. | |
| 45 | + | ||
| 46 | + | --- | |
| 47 | + | ||
| 48 | + | ## Enforcement Actions | |
| 49 | + | ||
| 50 | + | We enforce proportionally. Minor issues get a direct message. Serious or repeated issues get serious responses. | |
| 51 | + | ||
| 52 | + | ### Direct Message | |
| 53 | + | ||
| 54 | + | For minor or first-time issues: | |
| 55 | + | ||
| 56 | + | - We email you explaining what policy was violated and what needs to change | |
| 57 | + | - No account restrictions | |
| 58 | + | - No formal record on your account (formal warning tracking is not yet built) | |
| 59 | + | ||
| 60 | + | Most issues end here. People make mistakes. | |
| 61 | + | ||
| 62 | + | ### Content Removal | |
| 63 | + | ||
| 64 | + | For content that violates policy: | |
| 65 | + | ||
| 66 | + | - Specific content is removed or hidden | |
| 67 | + | - You're notified with explanation | |
| 68 | + | - Account remains active | |
| 69 | + | - You can appeal the decision | |
| 70 | + | ||
| 71 | + | ### Suspension | |
| 72 | + | ||
| 73 | + | For moderate violations or repeated issues: | |
| 74 | + | ||
| 75 | + | - Account access is restricted | |
| 76 | + | - You can still export your data | |
| 77 | + | - You can still appeal | |
| 78 | + | ||
| 79 | + | During suspension: | |
| 80 | + | - Your content remains but is hidden from fans | |
| 81 | + | - Fan memberships to your content are paused (fans aren't charged) | |
| 82 | + | - You can't upload or modify content | |
| 83 | + | ||
| 84 | + | ### Permanent Termination | |
| 85 | + | ||
| 86 | + | For serious violations or repeated moderate violations: | |
| 87 | + | ||
| 88 | + | - Account is permanently closed | |
| 89 | + | - Content is removed from public access | |
| 90 | + | - You have 30 days to export your data | |
| 91 | + | - Future accounts will also be terminated | |
| 92 | + | ||
| 93 | + | --- | |
| 94 | + | ||
| 95 | + | ## What Leads to Each Level | |
| 96 | + | ||
| 97 | + | ### Usually a Direct Message | |
| 98 | + | ||
| 99 | + | - Borderline content that could be interpreted as policy-violating | |
| 100 | + | - Technical policy violations (wrong format, metadata issues) | |
| 101 | + | - Minor behavioral issues (heated argument, single incident) | |
| 102 | + | ||
| 103 | + | ### Usually Content Removal | |
| 104 | + | ||
| 105 | + | - Clear policy violations in specific content | |
| 106 | + | - Content that received valid complaints and can't be defended | |
| 107 | + | ||
| 108 | + | ### Usually Suspension | |
| 109 | + | ||
| 110 | + | - Continued issues after a direct message | |
| 111 | + | - Moderate harassment or abuse | |
| 112 | + | - Repeated content violations | |
| 113 | + | - Deceptive practices | |
| 114 | + | ||
| 115 | + | ### Usually Termination | |
| 116 | + | ||
| 117 | + | - Severe harassment, threats, or doxxing | |
| 118 | + | - CSAM or content sexualizing minors | |
| 119 | + | - Fraud or scams | |
| 120 | + | - Ban evasion | |
| 121 | + | - Illegal activity | |
| 122 | + | - Repeated moderate violations | |
| 123 | + | ||
| 124 | + | --- | |
| 125 | + | ||
| 126 | + | ## Immediate Termination | |
| 127 | + | ||
| 128 | + | Some violations skip the escalation ladder: | |
| 129 | + | ||
| 130 | + | - **CSAM** - Immediate termination, law enforcement referral | |
| 131 | + | - **Credible threats of violence** - Immediate termination | |
| 132 | + | - **Illegal content** - Immediate termination | |
| 133 | + | - **Fraud** - Immediate termination | |
| 134 | + | ||
| 135 | + | For these, there's no warning period. | |
| 136 | + | ||
| 137 | + | --- | |
| 138 | + | ||
| 139 | + | ## Proactive Measures | |
| 140 | + | ||
| 141 | + | Every uploaded file is scanned for malware before it is served (see [Content Scanning](../tech/content-scanning.md)). We do not yet run automated image-matching for illegal content such as CSAM; that detection is report-driven and human-reviewed today. When we discover clearly illegal content, we remove it immediately, preserve it as required by law, and report it to the appropriate authorities (CSAM is reported to NCMEC's CyberTipline). Otherwise we operate reactively based on reports. Not every complaint results in action; false reports are common and sometimes coordinated. | |
| 142 | + | ||
| 143 | + | --- | |
| 144 | + | ||
| 145 | + | ## Data Handling for Terminated Accounts | |
| 146 | + | ||
| 147 | + | When your account is terminated: | |
| 148 | + | ||
| 149 | + | - **30-day export window** - You can download your content and data | |
| 150 | + | - **Content removed from public access** - Fans can't access it | |
| 151 | + | - **Financial records retained** - As required by law and payment processors | |
| 152 | + | ||
| 153 | + | After 30 days, your account data and content are deleted unless: | |
| 154 | + | ||
| 155 | + | - **Content we cannot ethically host** (CSAM, credible threats, illegal material) - Removed immediately. No export window for this content. | |
| 156 | + | - **Ban evasion records** - Account identifiers retained to enforce termination. Deleted after 2 years. | |
| 157 | + | ||
| 158 | + | Content may also be unlisted from discovery rather than removed, depending on the nature of the violation. Unlisted content remains accessible via direct link but does not appear in search or browse. | |
| 159 | + | ||
| 160 | + | --- | |
| 161 | + | ||
| 162 | + | ## Ban Evasion | |
| 163 | + | ||
| 164 | + | Creating new accounts after termination: | |
| 165 | + | ||
| 166 | + | - New accounts will be terminated when detected | |
| 167 | + | - Evasion may extend data retention periods | |
| 168 | + | - Repeated evasion may result in legal action | |
| 169 | + | ||
| 170 | + | --- | |
| 171 | + | ||
| 172 | + | ## Appeals | |
| 173 | + | ||
| 174 | + | Per our [Creator Guarantees](../about/guarantees.md): | |
| 175 | + | ||
| 176 | + | - Clear explanation of what policy was violated | |
| 177 | + | - Opportunity to appeal | |
| 178 | + | - Access to export your data even if suspended | |
| 179 | + | ||
| 180 | + | You can appeal any enforcement action, including terminations. See [Appeal Process](./appeals.md). | |
| 181 | + | ||
| 182 | + | --- | |
| 183 | + | ||
| 184 | + | ## Transparency | |
| 185 | + | ||
| 186 | + | - **Public moderation code**: Our moderation tools are in the public source code (excluding anti-spam measures that would be defeated by disclosure) | |
| 187 | + | - **Versioned policies**: This document is version-controlled; view history in our repository | |
| 188 | + | - **Major decisions documented**: Significant moderation decisions and policy changes are documented on The Changelog | |
| 189 | + | ||
| 190 | + | --- | |
| 191 | + | ||
| 192 | + | ## See Also | |
| 193 | + | ||
| 194 | + | - [Creator Guarantees](../about/guarantees.md) | |
| 195 | + | - [Appeal Process](./appeals.md) | |
| 196 | + | - [Acceptable Use Policy](./acceptable-use.md) |
| @@ -1,0 +1,131 @@ | |||
| 1 | + | # Copyright & DMCA | |
| 2 | + | ||
| 3 | + | How we handle copyright on Makenotwork. | |
| 4 | + | ||
| 5 | + | --- | |
| 6 | + | ||
| 7 | + | ## Our Position | |
| 8 | + | ||
| 9 | + | When you upload content to Makenotwork, you retain all rights. We don't claim any ownership, and our license to your content is limited to what's necessary to operate the platform (displaying it to fans, generating thumbnails, etc.). | |
| 10 | + | ||
| 11 | + | --- | |
| 12 | + | ||
| 13 | + | ## DMCA Compliance | |
| 14 | + | ||
| 15 | + | We comply with the Digital Millennium Copyright Act (DMCA). We respond to valid takedown notices and have procedures for handling copyright disputes. | |
| 16 | + | ||
| 17 | + | **Handled by email, not in-app.** The DMCA workflow on Makenotwork (takedown notices, counter-notifications, the statutory waiting period, and repeat-infringer tracking) runs through the designated agent email below, reviewed by a human. There is no self-serve in-app filing form today. We respond within the statutory window. In-app tooling for filing, tracking, and counter-notification is on the roadmap; this page describes how the process works regardless of where you submit. | |
| 18 | + | ||
| 19 | + | ### Designated Agent | |
| 20 | + | ||
| 21 | + | DMCA takedown notices should be sent to: | |
| 22 | + | ||
| 23 | + | **Email:** dmca@makenot.work | |
| 24 | + | ||
| 25 | + | **Mail:** | |
| 26 | + | Make Creative, LLC | |
| 27 | + | c/o Northwest Registered Agent LLC | |
| 28 | + | ATTN: DMCA Agent | |
| 29 | + | 1500 N Grant St, Ste N | |
| 30 | + | Denver, CO 80203 | |
| 31 | + | ||
| 32 | + | --- | |
| 33 | + | ||
| 34 | + | ## Filing a Takedown Notice | |
| 35 | + | ||
| 36 | + | If you believe content on Makenotwork infringes your copyright, send a notice containing: | |
| 37 | + | ||
| 38 | + | 1. **Your contact information** - Name, address, phone number, email | |
| 39 | + | 2. **Identification of the copyrighted work** - What work is being infringed | |
| 40 | + | 3. **Identification of the infringing material** - URL or other specific location on our platform | |
| 41 | + | 4. **Statement of good faith** - "I have a good faith belief that use of the material in the manner complained of is not authorized by the copyright owner, its agent, or the law" | |
| 42 | + | 5. **Statement of accuracy** - "The information in this notification is accurate, and under penalty of perjury, I am the owner, or authorized to act on behalf of the owner, of an exclusive right that is allegedly infringed" | |
| 43 | + | 6. **Your signature** - Physical or electronic | |
| 44 | + | ||
| 45 | + | Incomplete notices may not receive a response. | |
| 46 | + | ||
| 47 | + | --- | |
| 48 | + | ||
| 49 | + | ## What Happens When We Receive a Notice | |
| 50 | + | ||
| 51 | + | 1. **Review** - We review the notice for completeness and validity | |
| 52 | + | 2. **Removal** - If valid, we remove or disable access to the content | |
| 53 | + | 3. **Notification** - We notify the creator whose content was removed | |
| 54 | + | 4. **Counter-notification** - Creator may file a counter-notification (see below) | |
| 55 | + | ||
| 56 | + | Complex cases may require additional review. | |
| 57 | + | ||
| 58 | + | --- | |
| 59 | + | ||
| 60 | + | ## Counter-Notification | |
| 61 | + | ||
| 62 | + | If your content was removed and you believe the takedown was invalid, you can file a counter-notification. | |
| 63 | + | ||
| 64 | + | File a counter-notification if: | |
| 65 | + | ||
| 66 | + | - You own the copyright to the removed content | |
| 67 | + | - You have a license to use the content | |
| 68 | + | - The use is fair use or otherwise lawful | |
| 69 | + | - The content was misidentified | |
| 70 | + | ||
| 71 | + | Do not file a counter-notification if you know the content infringes someone's copyright. Counter-notifications are made under penalty of perjury. | |
| 72 | + | ||
| 73 | + | ### Required Elements | |
| 74 | + | ||
| 75 | + | Your counter-notification must include: | |
| 76 | + | ||
| 77 | + | 1. **Your contact information** - Name, address, phone number, email | |
| 78 | + | 2. **Identification of removed content** - Describe the content and where it appeared before removal | |
| 79 | + | 3. **Statement under penalty of perjury** - "I swear, under penalty of perjury, that I have a good faith belief that the material was removed or disabled as a result of mistake or misidentification of the material to be removed or disabled" | |
| 80 | + | 4. **Consent to jurisdiction** - "I consent to the jurisdiction of the Federal District Court for the judicial district in which my address is located, or if my address is outside the United States, the judicial district in which Make Creative, LLC is located, and I will accept service of process from the person who provided the original DMCA notification or an agent of such person" | |
| 81 | + | 5. **Your signature** - Physical or electronic | |
| 82 | + | ||
| 83 | + | Send counter-notifications to: **dmca@makenot.work** | |
| 84 | + | ||
| 85 | + | ### What Happens After Filing | |
| 86 | + | ||
| 87 | + | 1. We review for completeness | |
| 88 | + | 2. We notify the original complainant (they receive a copy) | |
| 89 | + | 3. **10-14 business day waiting period**: The complainant has this time to file a court action | |
| 90 | + | 4. **Content restored**: If no court action is filed, we restore your content | |
| 91 | + | ||
| 92 | + | The waiting period gives the complainant time to seek a court order. If the complainant files suit, your content stays down pending resolution. At that point, this is a legal matter between you and the complainant. | |
| 93 | + | ||
| 94 | + | --- | |
| 95 | + | ||
| 96 | + | ## Repeat Infringer Policy | |
| 97 | + | ||
| 98 | + | We terminate accounts of users who repeatedly infringe copyright. | |
| 99 | + | ||
| 100 | + | **How it works:** | |
| 101 | + | ||
| 102 | + | - **First valid DMCA:** Content removed, creator notified | |
| 103 | + | - **Second valid DMCA:** Content removed, creator notified of repeat status | |
| 104 | + | - **Third valid DMCA:** Account terminated | |
| 105 | + | ||
| 106 | + | "Valid" means the notice was complete, we removed content, and no successful counter-notification was filed. | |
| 107 | + | ||
| 108 | + | We may skip steps and terminate immediately for egregious infringement (large-scale piracy, commercial counterfeiting, etc.). | |
| 109 | + | ||
| 110 | + | --- | |
| 111 | + | ||
| 112 | + | ## What We Won't Do | |
| 113 | + | ||
| 114 | + | - **Remove content without proper notice** - Informal complaints or social media callouts aren't DMCA notices | |
| 115 | + | - **Act on incomplete notices** - All required elements must be present | |
| 116 | + | - **Ignore counter-notifications** - If a creator disputes a takedown, we follow the legal process | |
| 117 | + | - **Share creator contact info with complainants** - We forward notices to creators, not the reverse | |
| 118 | + | ||
| 119 | + | --- | |
| 120 | + | ||
| 121 | + | ## Abuse of DMCA | |
| 122 | + | ||
| 123 | + | Filing false DMCA notices is perjury. If you knowingly misrepresent that content is infringing, you may be liable for damages. We track abuse patterns and may block repeat false filers from our DMCA process. | |
| 124 | + | ||
| 125 | + | --- | |
| 126 | + | ||
| 127 | + | ## See Also | |
| 128 | + | ||
| 129 | + | - [Content Moderation](./moderation.md): Our broader moderation approach | |
| 130 | + | - [Appeal Process](./appeals.md): For non-copyright content issues | |
| 131 | + | - [Terms of Service](./terms-of-service.md): Content ownership terms |
| @@ -1,0 +1,113 @@ | |||
| 1 | + | # Terms of Service | |
| 2 | + | ||
| 3 | + | *Last updated: June 8, 2026* | |
| 4 | + | ||
| 5 | + | Makenotwork is operated by Make Creative, LLC ("we", "us", "our"). By using our service, you agree to these terms. | |
| 6 | + | ||
| 7 | + | ## The Short Version | |
| 8 | + | ||
| 9 | + | - You own your content | |
| 10 | + | - You're responsible for your content | |
| 11 | + | - We provide the platform, you provide the creativity | |
| 12 | + | - Don't do illegal things | |
| 13 | + | - Either party can end this relationship anytime | |
| 14 | + | ||
| 15 | + | ## Accounts | |
| 16 | + | ||
| 17 | + | ### Eligibility | |
| 18 | + | You must be 18+ or the age of majority in your jurisdiction to create a creator account. Fan accounts require you to be 13+ (or your jurisdiction's minimum). | |
| 19 | + | ||
| 20 | + | ### Account Security | |
| 21 | + | You're responsible for your account credentials. Enable two-factor authentication. If you suspect unauthorized access, contact us immediately at security@makenot.work. | |
| 22 | + | ||
| 23 | + | ### Account Types | |
| 24 | + | - **Creator accounts**: Pay a monthly tier fee, can upload and sell content | |
| 25 | + | - **Fan accounts**: Free, can purchase and access content | |
| 26 | + | ||
| 27 | + | ## Creator Terms | |
| 28 | + | ||
| 29 | + | ### Your Content | |
| 30 | + | You retain all rights to content you upload. By uploading, you grant us a license to host, display, and distribute your content as necessary to operate the service. | |
| 31 | + | ||
| 32 | + | ### Revenue | |
| 33 | + | We charge 0% platform fee on fan payments. Payment processing fees (~3%) are deducted before funds reach you. | |
| 34 | + | ||
| 35 | + | ### Prohibited Content | |
| 36 | + | Don't upload: | |
| 37 | + | - Content you don't have rights to distribute | |
| 38 | + | - Illegal content (varies by jurisdiction) | |
| 39 | + | - Content that violates others' rights | |
| 40 | + | - Malware or harmful code | |
| 41 | + | ||
| 42 | + | ### Content Moderation | |
| 43 | + | We remove content that violates these terms. We try to give notice before removal when possible. See [Content Moderation](./moderation.md) for details. | |
| 44 | + | ||
| 45 | + | ## Fan Terms | |
| 46 | + | ||
| 47 | + | ### Purchases | |
| 48 | + | When you buy content: | |
| 49 | + | - You get a license for personal use | |
| 50 | + | - You can download and keep files | |
| 51 | + | - You can't redistribute or resell | |
| 52 | + | - One-time purchases: access persists even if the creator leaves ({{ policy.buyer_access_days }}-day download window) | |
| 53 | + | - Membership-gated content: access persists during the {{ policy.buyer_access_days }}-day grace period if a creator deletes their account. After {{ policy.buyer_access_days }} days, content is removed. Active memberships are not billed during this period | |
| 54 | + | ||
| 55 | + | ### Memberships | |
| 56 | + | - Billed monthly | |
| 57 | + | - Cancel anytime | |
| 58 | + | - Access continues until end of billing period | |
| 59 | + | - No refunds for partial months | |
| 60 | + | ||
| 61 | + | ## Data & Privacy | |
| 62 | + | ||
| 63 | + | See our [Privacy Policy](./privacy-policy.md). Summary: | |
| 64 | + | - We collect minimal data | |
| 65 | + | - We don't track you | |
| 66 | + | - We don't sell your data | |
| 67 | + | - You can export or delete your data | |
| 68 | + | ||
| 69 | + | ## Termination | |
| 70 | + | ||
| 71 | + | ### By You | |
| 72 | + | Cancel anytime. Export your data first. Creator memberships end at the billing period. | |
| 73 | + | ||
| 74 | + | ### By Us | |
| 75 | + | We may terminate accounts that violate these terms. We'll provide notice when possible and allow data export for non-egregious violations. | |
| 76 | + | ||
| 77 | + | ## Disclaimers | |
| 78 | + | ||
| 79 | + | The service is provided "as is." We do our best but can't guarantee uptime, data integrity, or that you'll make money. Back up your content. | |
| 80 | + | ||
| 81 | + | ## Liability | |
| 82 | + | ||
| 83 | + | Our liability is limited to the amount you've paid us in the past 12 months. We're not liable for indirect damages, lost profits, or lost data. | |
| 84 | + | ||
| 85 | + | The disclaimers and limits in this section do not override the specific commitments in [What We Guarantee](../about/guarantees.md), including uptime, data preservation, backup, shutdown notice, and founder-pricing lock-in. Where this section and the Guarantees conflict, the Guarantees control. | |
| 86 | + | ||
| 87 | + | ## Disputes | |
| 88 | + | ||
| 89 | + | We prefer to resolve disputes directly. If that fails, disputes are governed by Colorado law and handled in Colorado courts. | |
| 90 | + | ||
| 91 | + | ## Changes | |
| 92 | + | ||
| 93 | + | We may update these terms: | |
| 94 | + | ||
| 95 | + | - **General changes**: 90 days notice before they take effect | |
| 96 | + | - **Privacy policy changes**: 90 days notice before they take effect | |
| 97 | + | - **Pricing changes**: {{ policy.price_change_notice_days }} days notice + grandfathering at current rate for at least {{ policy.grandfather_months }} months (see [guarantees](../about/guarantees.md)) | |
| 98 | + | - **Exceptions**: Changes required by law, court order, or to address an active security threat may take effect immediately | |
| 99 | + | ||
| 100 | + | We'll notify you by email when terms change. Continued use after the notice period constitutes acceptance. | |
| 101 | + | ||
| 102 | + | ## Contact | |
| 103 | + | ||
| 104 | + | Questions? Email legal@makenot.work. | |
| 105 | + | ||
| 106 | + | --- | |
| 107 | + | ||
| 108 | + | ## See Also | |
| 109 | + | ||
| 110 | + | - [Privacy Policy](./privacy-policy.md): Data collection and handling | |
| 111 | + | - [Acceptable Use Policy](./acceptable-use.md): Content rules | |
| 112 | + | - [What We Guarantee](../about/guarantees.md): Platform commitments | |
| 113 | + | - [How We Work](../about/how-we-work.md): Business model and pricing |
| @@ -1,0 +1,139 @@ | |||
| 1 | + | # Privacy Policy | |
| 2 | + | ||
| 3 | + | *Last updated: June 8, 2026* | |
| 4 | + | ||
| 5 | + | Makenotwork is operated by Make Creative, LLC. This policy explains what data we collect and how we use it. | |
| 6 | + | ||
| 7 | + | ## The Short Version | |
| 8 | + | ||
| 9 | + | - We collect the minimum data needed to operate | |
| 10 | + | - We don't track you across the web | |
| 11 | + | - We don't sell your data | |
| 12 | + | - We don't show ads | |
| 13 | + | - You can export or delete your data anytime | |
| 14 | + | ||
| 15 | + | ## What We Collect | |
| 16 | + | ||
| 17 | + | ### Account Information | |
| 18 | + | - Email address | |
| 19 | + | - Username | |
| 20 | + | - Password (hashed, we can't read it) | |
| 21 | + | - Payment information (handled by our payment processor, we don't store card numbers) | |
| 22 | + | ||
| 23 | + | ### Content | |
| 24 | + | - Files you upload | |
| 25 | + | - Metadata you provide (titles, descriptions, tags) | |
| 26 | + | - Projects and organization | |
| 27 | + | ||
| 28 | + | ### Transactions | |
| 29 | + | - Purchases and memberships | |
| 30 | + | - Payment amounts and dates | |
| 31 | + | - Payout records | |
| 32 | + | ||
| 33 | + | ### Technical Data | |
| 34 | + | - IP address (for security, rate limiting) | |
| 35 | + | - Browser type (for compatibility) | |
| 36 | + | - Error logs (for debugging) | |
| 37 | + | ||
| 38 | + | IP addresses are retained for 30 days, then deleted. | |
| 39 | + | ||
| 40 | + | ### Login and Session Data | |
| 41 | + | - IP address and browser type per session (for security alerts and session management) | |
| 42 | + | - Failed login attempt counts and timestamps (for account lockout protection) | |
| 43 | + | ||
| 44 | + | Session records are retained for 90 days after the session ends. Failed login data is reset after a successful login. | |
| 45 | + | ||
| 46 | + | ## What We Don't Collect | |
| 47 | + | ||
| 48 | + | - Browsing behavior or history | |
| 49 | + | - Location data (beyond IP-derived country for tax purposes) | |
| 50 | + | - Cross-site tracking or device fingerprinting for identification | |
| 51 | + | - Third-party tracking data | |
| 52 | + | - Social media profiles | |
| 53 | + | - Analytics of any kind. We run no analytics product, first-party or third-party, and no page-view or visitor measurement. | |
| 54 | + | ||
| 55 | + | The one thing your browser reports back to us is a Content Security Policy violation: if a page tries to load a script or style the policy forbids, the browser posts the blocked address and the page it happened on. That report carries no cookie, no identifier, and nothing about you, and it is sent only when a violation occurs. It exists so an injected script shows up in our logs instead of going unnoticed. | |
| 56 | + | ||
| 57 | + | ## How We Use Data | |
| 58 | + | ||
| 59 | + | - **Operating the service**: Hosting content, processing payments | |
| 60 | + | - **Communication**: Account notifications, support responses | |
| 61 | + | - **Security**: Detecting abuse, preventing fraud | |
| 62 | + | - **Legal compliance**: Tax reporting, responding to valid legal requests | |
| 63 | + | ||
| 64 | + | ## Data Sharing | |
| 65 | + | ||
| 66 | + | We share data only with: | |
| 67 | + | ||
| 68 | + | - **Payment processor**: Payment processing (see [Infrastructure & Vendors](../tech/infrastructure.md) for current provider) | |
| 69 | + | - **Email provider**: Sending the mail you receive, which means your address and the message itself (see [Infrastructure & Vendors](../tech/infrastructure.md) for current provider) | |
| 70 | + | - **Infrastructure providers**: Hosting, CDN (they process but don't access your data) | |
| 71 | + | - **Legal authorities**: Only when legally required, and we'll notify you unless prohibited | |
| 72 | + | ||
| 73 | + | We don't sell or share data for advertising. | |
| 74 | + | ||
| 75 | + | ## Your Rights | |
| 76 | + | ||
| 77 | + | ### Access | |
| 78 | + | Download all your data anytime from Settings > Export. | |
| 79 | + | ||
| 80 | + | ### Correction | |
| 81 | + | Edit your account information directly. | |
| 82 | + | ||
| 83 | + | ### Deletion | |
| 84 | + | Delete your account from Settings > Account > Delete. We remove your personal data within 30 days, except: | |
| 85 | + | - Transaction records (legal requirement) | |
| 86 | + | - If you have completed sales, purchased content remains accessible to buyers for 90 days after deletion, then is removed | |
| 87 | + | ||
| 88 | + | ### Portability | |
| 89 | + | Export includes all content, metadata, and transaction history in standard formats. | |
| 90 | + | ||
| 91 | + | ## Cookies | |
| 92 | + | ||
| 93 | + | We use cookies for: | |
| 94 | + | - **Session management**: Keeping you logged in | |
| 95 | + | - **Security**: Preventing unauthorized actions on your account | |
| 96 | + | ||
| 97 | + | We don't use tracking cookies or third-party cookies. | |
| 98 | + | ||
| 99 | + | ## Children | |
| 100 | + | ||
| 101 | + | We don't knowingly collect data from children under 13. | |
| 102 | + | ||
| 103 | + | ## International Transfers | |
| 104 | + | ||
| 105 | + | Your data is processed in the United States (application server and database) and the European Union (file storage in Germany and Finland). For the specific providers and regions that host it, see our [Infrastructure](../tech/infrastructure.md) page and the service list in [Credits](../about/credits.md), which links to each vendor (including Hetzner). | |
| 106 | + | ||
| 107 | + | For transfers of personal data from the EU/EEA to the United States, we rely on Standard Contractual Clauses (SCCs) as approved by the European Commission. Copies of our SCCs are available upon request at privacy@makenot.work. | |
| 108 | + | ||
| 109 | + | We also maintain data processing agreements with our infrastructure providers that include SCC commitments for any EU personal data they process on our behalf. | |
| 110 | + | ||
| 111 | + | ## GDPR (EU Users) | |
| 112 | + | ||
| 113 | + | You have rights under GDPR including access, rectification, erasure, and portability. Contact privacy@makenot.work to exercise these rights. | |
| 114 | + | ||
| 115 | + | Legal basis for processing: contract performance (operating your account), legitimate interest (security), legal obligation (tax records). | |
| 116 | + | ||
| 117 | + | We respond to data subject requests within 30 days. | |
| 118 | + | ||
| 119 | + | ## CCPA (California Users) | |
| 120 | + | ||
| 121 | + | You have the right to know what data we collect, request deletion, and opt out of data sales (we don't sell data, so there's nothing to opt out of). | |
| 122 | + | ||
| 123 | + | ## Changes | |
| 124 | + | ||
| 125 | + | We'll notify you of material changes via email. | |
| 126 | + | ||
| 127 | + | ## Contact | |
| 128 | + | ||
| 129 | + | Privacy questions: privacy@makenot.work | |
| 130 | + | ||
| 131 | + | Data protection inquiries: dpo@makenot.work | |
| 132 | + | ||
| 133 | + | --- | |
| 134 | + | ||
| 135 | + | ## See Also | |
| 136 | + | ||
| 137 | + | - [Terms of Service](./terms-of-service.md): Full legal terms | |
| 138 | + | - [Acceptable Use Policy](./acceptable-use.md): Content rules | |
| 139 | + | - [What We Guarantee](../about/guarantees.md): Data export and portability commitments |
| @@ -1,0 +1,99 @@ | |||
| 1 | + | # Transparency Reports | |
| 2 | + | ||
| 3 | + | What we will publish about moderation and legal requests. | |
| 4 | + | ||
| 5 | + | > **Status: pre-launch.** No transparency reports have been published yet. The first report will appear once moderation volume is high enough to anonymize effectively (see [Pre-Launch Note](#pre-launch-note)). This page describes the program we are committing to, not reports that already exist. | |
| 6 | + | ||
| 7 | + | --- | |
| 8 | + | ||
| 9 | + | ## Our Commitment | |
| 10 | + | ||
| 11 | + | We will publish regular transparency reports so you can verify that our enforcement matches our stated policies: | |
| 12 | + | ||
| 13 | + | - Content moderation actions | |
| 14 | + | - Account enforcement | |
| 15 | + | - Legal and government requests | |
| 16 | + | - DMCA notices | |
| 17 | + | ||
| 18 | + | --- | |
| 19 | + | ||
| 20 | + | ## What We Report | |
| 21 | + | ||
| 22 | + | ### Moderation Statistics | |
| 23 | + | ||
| 24 | + | - **Content removed** - Total pieces of content removed, by category | |
| 25 | + | - **Accounts warned** - Number of accounts receiving warnings | |
| 26 | + | - **Accounts suspended** - Temporary suspensions issued | |
| 27 | + | - **Accounts terminated** - Permanent terminations | |
| 28 | + | - **Appeals received** - How many decisions were appealed | |
| 29 | + | - **Appeals overturned** - How often we reversed our decisions | |
| 30 | + | ||
| 31 | + | ### Legal Requests | |
| 32 | + | ||
| 33 | + | - **Subpoenas received** - Requests from courts or government | |
| 34 | + | - **Requests complied with** - How many we provided data for | |
| 35 | + | - **Requests rejected** - How many we challenged or refused | |
| 36 | + | - **User notifications** - How many affected users we notified | |
| 37 | + | ||
| 38 | + | ### DMCA | |
| 39 | + | ||
| 40 | + | - **Takedown notices received** - Total valid DMCA notices | |
| 41 | + | - **Content removed via DMCA** - Items taken down | |
| 42 | + | - **Counter-notifications filed** - Disputes by creators | |
| 43 | + | - **Content restored** - Items put back after counter-notification | |
| 44 | + | ||
| 45 | + | --- | |
| 46 | + | ||
| 47 | + | ## Report Format | |
| 48 | + | ||
| 49 | + | Each report covers a calendar quarter and includes: | |
| 50 | + | ||
| 51 | + | - Raw numbers for each category | |
| 52 | + | - Comparison to previous quarters | |
| 53 | + | - Notable trends or changes | |
| 54 | + | - Explanation of any anomalies | |
| 55 | + | ||
| 56 | + | Reports are published as blog posts and archived in this documentation. | |
| 57 | + | ||
| 58 | + | --- | |
| 59 | + | ||
| 60 | + | ## Publication Schedule | |
| 61 | + | ||
| 62 | + | Once reporting begins, reports will be published quarterly, within 30 days of quarter end: | |
| 63 | + | ||
| 64 | + | - Q1 (Jan-Mar): Published by April 30 | |
| 65 | + | - Q2 (Apr-Jun): Published by July 31 | |
| 66 | + | - Q3 (Jul-Sep): Published by October 31 | |
| 67 | + | - Q4 (Oct-Dec): Published by January 31 | |
| 68 | + | ||
| 69 | + | --- | |
| 70 | + | ||
| 71 | + | ## What We Don't Publish | |
| 72 | + | ||
| 73 | + | - **Specific content details** - We don't republish removed content | |
| 74 | + | - **User identities** - We don't name individuals involved in moderation actions | |
| 75 | + | - **Ongoing investigations** - We don't disclose active legal matters | |
| 76 | + | - **Security vulnerabilities** - We don't detail exploitation attempts | |
| 77 | + | ||
| 78 | + | --- | |
| 79 | + | ||
| 80 | + | ## Pre-Launch Note | |
| 81 | + | ||
| 82 | + | Reports will begin once moderation volume is high enough to anonymize effectively. | |
| 83 | + | ||
| 84 | + | --- | |
| 85 | + | ||
| 86 | + | ## Source-Available Transparency | |
| 87 | + | ||
| 88 | + | Beyond reports: | |
| 89 | + | ||
| 90 | + | - **Policies are public** - All moderation criteria are documented here | |
| 91 | + | - **Code is public** - Automated systems can be inspected | |
| 92 | + | - **Decisions are explained** - Users receive specific reasons for actions | |
| 93 | + | ||
| 94 | + | --- | |
| 95 | + | ||
| 96 | + | ## See Also | |
| 97 | + | ||
| 98 | + | - [Content Moderation](./moderation.md): how we moderate | |
| 99 | + | - [Privacy Policy](./privacy-policy.md): how we handle data requests |
| @@ -1,0 +1,121 @@ | |||
| 1 | + | # Appeal Process | |
| 2 | + | ||
| 3 | + | How to dispute moderation decisions. | |
| 4 | + | ||
| 5 | + | *Makenotwork is currently a one-person operation. Appeals are reviewed directly by the founder. Independent review by a separate decision-maker is planned once the team grows.* | |
| 6 | + | ||
| 7 | + | --- | |
| 8 | + | ||
| 9 | + | ## What Can Be Appealed | |
| 10 | + | ||
| 11 | + | You can appeal: | |
| 12 | + | ||
| 13 | + | - Content removal | |
| 14 | + | - Account suspension | |
| 15 | + | - Account termination | |
| 16 | + | - Any other moderation action | |
| 17 | + | ||
| 18 | + | --- | |
| 19 | + | ||
| 20 | + | ## How to Appeal | |
| 21 | + | ||
| 22 | + | Every appeal reaches the same person and gets the same review. How you send it | |
| 23 | + | depends on what you're appealing. | |
| 24 | + | ||
| 25 | + | **Account suspension:** submit from your account dashboard. The form appears there | |
| 26 | + | while the suspension is active. | |
| 27 | + | ||
| 28 | + | **Content removal, account termination, and anything else:** email | |
| 29 | + | **appeals@makenot.work**. There is no dashboard form for these yet. If your account | |
| 30 | + | was terminated you are signed out and cannot reach the dashboard at all, so email is | |
| 31 | + | the only route, and it works. | |
| 32 | + | ||
| 33 | + | Include: | |
| 34 | + | ||
| 35 | + | 1. **Your username** or account email | |
| 36 | + | 2. **What action you're appealing** - What was removed or what restriction was applied | |
| 37 | + | 3. **Why you believe the decision was wrong** - Be specific | |
| 38 | + | 4. **Any relevant context** - Information we might have missed | |
| 39 | + | ||
| 40 | + | Emailed appeals are not second-class. The dashboard form exists for suspensions | |
| 41 | + | because that is where it was built first, and the rest are on the list. | |
| 42 | + | ||
| 43 | + | --- | |
| 44 | + | ||
| 45 | + | ## What Happens Next | |
| 46 | + | ||
| 47 | + | 1. **Acknowledgment** - We confirm receipt (usually within 24 hours) | |
| 48 | + | ||
| 49 | + | 2. **Review** - Your appeal is reviewed with fresh eyes. Currently, appeals are reviewed by the founder. Once the team grows, appeals will be reviewed by someone other than the original decision-maker | |
| 50 | + | ||
| 51 | + | 3. **Decision** - We notify you of the outcome with explanation | |
| 52 | + | ||
| 53 | + | 4. **If overturned** - Content is restored or restrictions are lifted | |
| 54 | + | ||
| 55 | + | 5. **If upheld** - We explain why and what options remain | |
| 56 | + | ||
| 57 | + | --- | |
| 58 | + | ||
| 59 | + | ## Timeline | |
| 60 | + | ||
| 61 | + | We resolve appeals within: | |
| 62 | + | ||
| 63 | + | - **Content removal:** 3-5 business days | |
| 64 | + | - **Account suspension:** 5-10 business days | |
| 65 | + | - **Account termination:** 10-14 business days | |
| 66 | + | ||
| 67 | + | Complex cases may take longer. We'll keep you informed of delays. | |
| 68 | + | ||
| 69 | + | --- | |
| 70 | + | ||
| 71 | + | ## What We Consider | |
| 72 | + | ||
| 73 | + | When reviewing appeals, we look at: | |
| 74 | + | ||
| 75 | + | - **Original context** - Was important context missed? | |
| 76 | + | - **Policy interpretation** - Was the policy applied correctly? | |
| 77 | + | - **Consistency** - Is this consistent with how we've handled similar cases? | |
| 78 | + | - **New information** - Did you provide information that changes the picture? | |
| 79 | + | ||
| 80 | + | --- | |
| 81 | + | ||
| 82 | + | ## Data Access During Appeals | |
| 83 | + | ||
| 84 | + | Even if your account is suspended or terminated: | |
| 85 | + | ||
| 86 | + | - You can request a data export | |
| 87 | + | - We preserve your data during the appeal window | |
| 88 | + | ||
| 89 | + | --- | |
| 90 | + | ||
| 91 | + | ## Limits | |
| 92 | + | ||
| 93 | + | Some decisions cannot be appealed: | |
| 94 | + | ||
| 95 | + | - **Legal requirements** - If we're legally required to remove content or terminate an account | |
| 96 | + | - **Imminent harm** - If we believe content poses immediate danger to someone | |
| 97 | + | - **CSAM** - Content involving minors is not subject to appeal | |
| 98 | + | ||
| 99 | + | For these cases, we'll explain why the decision is final. | |
| 100 | + | ||
| 101 | + | --- | |
| 102 | + | ||
| 103 | + | ## If You Disagree with the Appeal Outcome | |
| 104 | + | ||
| 105 | + | If your appeal is denied and you believe we made an error, you can appeal again after | |
| 106 | + | 30 days. Provide new information or arguments not considered the first time; your | |
| 107 | + | case will be re-examined from scratch. | |
| 108 | + | ||
| 109 | + | For suspensions the 30-day wait is enforced by the dashboard form, which will tell | |
| 110 | + | you how many days remain. One appeal is open at a time; submit again once the | |
| 111 | + | previous one has been decided. | |
| 112 | + | ||
| 113 | + | The wait exists so that a second look is a genuine second look rather than the same | |
| 114 | + | case resubmitted the same week. It is not a limit on how many times you can be heard. | |
| 115 | + | ||
| 116 | + | --- | |
| 117 | + | ||
| 118 | + | ## See Also | |
| 119 | + | ||
| 120 | + | - [Content Moderation](./moderation.md): How we make decisions | |
| 121 | + | - [Acceptable Use Policy](./acceptable-use.md): What we enforce |
| @@ -1,0 +1,119 @@ | |||
| 1 | + | # Acceptable Use Policy | |
| 2 | + | ||
| 3 | + | What you can and cannot do on Makenotwork. | |
| 4 | + | ||
| 5 | + | --- | |
| 6 | + | ||
| 7 | + | ## The Short Version | |
| 8 | + | ||
| 9 | + | Create and share your work. Respect others. Don't break the law. | |
| 10 | + | ||
| 11 | + | --- | |
| 12 | + | ||
| 13 | + | ## What's Allowed | |
| 14 | + | ||
| 15 | + | Makenotwork is for creators sharing original work with their fans. You can: | |
| 16 | + | ||
| 17 | + | - Upload and distribute your original content | |
| 18 | + | - Sell access to your work | |
| 19 | + | - Build a paying audience | |
| 20 | + | - Use creative tools and customization features | |
| 21 | + | - Export your data anytime | |
| 22 | + | - Include sponsorships and affiliate links in your content | |
| 23 | + | ||
| 24 | + | We support a wide range of creative expression, including work that's controversial, challenging, or provocative. | |
| 25 | + | ||
| 26 | + | ### Sponsorships and Endorsements | |
| 27 | + | ||
| 28 | + | Creators are free to include sponsored segments, affiliate links, and paid endorsements in their content. Sponsored content must be clearly labeled as advertising, and creators must comply with all applicable disclosure laws (including FTC guidelines, GDPR, and equivalent regulations in their jurisdiction). We strongly encourage creators to only recommend products they've personally used and are qualified to evaluate. Your audience trusts you. Treat that trust as the asset it is. | |
| 29 | + | ||
| 30 | + | Undisclosed paid advertisement is a serious moderation issue. Presenting sponsored content as organic recommendation undermines fan trust across the entire platform. | |
| 31 | + | ||
| 32 | + | --- | |
| 33 | + | ||
| 34 | + | ## What's Not Allowed | |
| 35 | + | ||
| 36 | + | ### Content That Harms People | |
| 37 | + | ||
| 38 | + | - **Dehumanization** - Content that treats people as less than human based on identity | |
| 39 | + | - **Harassment** - Targeted abuse, threats, or intimidation of individuals | |
| 40 | + | - **Incitement to violence** - Content encouraging real-world harm | |
| 41 | + | - **Doxxing** - Publishing private information to enable harassment | |
| 42 | + | - **CSAM** - Any sexual content involving minors (immediate removal, law enforcement referral) | |
| 43 | + | ||
| 44 | + | ### Content That Harms the Platform | |
| 45 | + | ||
| 46 | + | - **Spam** - Automated posting, fake engagement, or promotional flooding | |
| 47 | + | - **Fraud** - Scams, deceptive schemes, or financial manipulation, including misrepresenting your [generative AI tier](../about/generative-ai.md) (e.g., claiming Handmade when generative AI was used) | |
| 48 | + | - **Impersonation** - Pretending to be someone else to deceive | |
| 49 | + | - **Malware and harmful software** - Including but not limited to: | |
| 50 | + | - Uploading software that contains malware, spyware, or backdoors | |
| 51 | + | - Uploading software that misrepresents its functionality | |
| 52 | + | - Distributing cracked, pirated, or license-circumventing software | |
| 53 | + | - New uploads from unestablished accounts may be held for review | |
| 54 | + | ||
| 55 | + | ### Content We Don't Host | |
| 56 | + | ||
| 57 | + | - **Adult/NSFW content** - Not permitted on Makenotwork. We intend to launch a separate platform for adult creators with identical commitments when infrastructure is ready | |
| 58 | + | - **Illegal content** - Content that violates applicable law | |
| 59 | + | ||
| 60 | + | --- | |
| 61 | + | ||
| 62 | + | ## Context Matters | |
| 63 | + | ||
| 64 | + | We evaluate content in context. Satire, critique, historical documentation, and artistic exploration are considered when reviewing reported content. A documentary about hate groups isn't the same as hate group recruitment. We look at intent and effect, not surface content. | |
| 65 | + | ||
| 66 | + | --- | |
| 67 | + | ||
| 68 | + | ## Higher Standards for Discussing Marginalized Groups | |
| 69 | + | ||
| 70 | + | Content discussing marginalized groups is held to a higher standard. The reason is not that these groups are fragile; it is that platforms have historically amplified harm against them. The same words carry different weight depending on historical context and power dynamics. | |
| 71 | + | ||
| 72 | + | --- | |
| 73 | + | ||
| 74 | + | ## Account Behavior | |
| 75 | + | ||
| 76 | + | Beyond content, we expect users to: | |
| 77 | + | ||
| 78 | + | - **Use one account** - No sockpuppets or ban evasion | |
| 79 | + | - **Respect rate limits** - No automated abuse of platform features | |
| 80 | + | - **Honor content licenses** - Don't redistribute others' paid content | |
| 81 | + | - **Engage honestly** - No fake reviews, inflated metrics, or deceptive practices | |
| 82 | + | ||
| 83 | + | --- | |
| 84 | + | ||
| 85 | + | ## Consequences | |
| 86 | + | ||
| 87 | + | Violations result in action proportional to severity: | |
| 88 | + | ||
| 89 | + | - Minor first-time issues: Direct message explaining the issue | |
| 90 | + | - Repeated or moderate issues: Content removal, temporary restrictions | |
| 91 | + | - Serious or repeated violations: Account suspension or termination | |
| 92 | + | ||
| 93 | + | See [Content Moderation & Enforcement](./moderation.md) for details. | |
| 94 | + | ||
| 95 | + | You can appeal any action. See [Appeal Process](./appeals.md). | |
| 96 | + | ||
| 97 | + | --- | |
| 98 | + | ||
| 99 | + | ## Reporting Violations | |
| 100 | + | ||
| 101 | + | **Email:** reports@makenot.work | |
| 102 | + | ||
| 103 | + | Include: | |
| 104 | + | - Link to the content | |
| 105 | + | - Which policy you believe is violated | |
| 106 | + | - Any relevant context | |
| 107 | + | ||
| 108 | + | We review all reports. We don't disclose reporter identities to the reported user. | |
| 109 | + | ||
| 110 | + | --- | |
| 111 | + | ||
| 112 | + | ## See Also | |
| 113 | + | ||
| 114 | + | - [Generative AI Policy](../about/generative-ai.md): AI tier definitions and disclosure requirements | |
| 115 | + | - [Terms of Service](./terms-of-service.md): Full legal terms | |
| 116 | + | - [Privacy Policy](./privacy-policy.md): Data collection and handling | |
| 117 | + | - [FAQ](../support/faq.md): Content policy questions | |
| 118 | + | - [Content Moderation & Enforcement](./moderation.md): How we moderate and what happens when rules are broken | |
| 119 | + | - [Appeal Process](./appeals.md): Disputing decisions |