code wiki / (root) / nx_takedown.nx

nx_takedown.nx source

↩ module page · 111 lines · 6277 B

1// nx_takedown.nx -- WRITING/HOSTING arc, rung W-TD-1: NOTICE-AND-TAKEDOWN, the SAFE-HARBOUR POSTURE. 2// 3// ★★★★★★THIRD OPERATOR CORRECTION, 2026-08-04, and it moved the compliance work to a different 4// place entirely: "how it works really is like the dmca takedown -- i don't act as the arbiter of 5// the content and inherit that legal headache, but like google or bing or ai companies i use what 6// is available till its requested to be removed, and i inherit that different set of requirements." 7// 8// THIS IS THE CORRECT ARCHITECTURE AND MY EARLIER ONE WAS BACKWARDS. I had been building a 9// PRE-PUBLICATION ARBITER. In US law that posture is not merely unhelpful, it is often WORSE: 10// * Editorial screening is what turns a conduit into a PUBLISHER, and publishers answer for what 11// they let through. The safe harbours (DMCA 512, and 230 for third-party content) are built for 12// intermediaries who do NOT sit in judgement of every item. 13// * ★★★★★★ACTUAL KNOWLEDGE IS THE ENEMY OF SAFE HARBOUR. 512(c) protection turns on the absence 14// of actual or "red flag" knowledge. A detector that concludes "this is probably unlawful" and 15// proceeds anyway MANUFACTURES the very knowledge that removes the protection. So an aggressive 16// pre-screen can strictly increase exposure. That is the deep reason the operator is right. 17// ⇒ THE DUTY THAT ACTUALLY BINDS IS RESPONSE, NOT PRIOR RESTRAINT: a reachable notice path, 18// expeditious removal on a VALID notice, honest records, and a repeat-infringer policy (512(i)). 19// 20// ⛔THE ONE CLASS THAT IS NOT A TAKEDOWN AT ALL: CSAM. There is an affirmative REPORT-AND-PRESERVE 21// duty (18 U.S.C. 2258A, reporting to NCMEC), and quietly deleting it is not compliance -- it 22// destroys evidence. It gets its own branch and can never be answered with "removed, case closed". 23// 24// ⚠NOT LEGAL ADVICE. This encodes the SHAPE of the regime so a machine can route and a human can 25// answer; it does not decide anyone's case, and where the law is unsettled it says so. 26// 27// Pure integer, NO syscalls, caller owns every buffer. 28// license_tier: ORIGINAL 29// module: nishi-core.hosting.takedown 30// capability: HOSTING_NOTICE_AND_TAKEDOWN 31 32// claim classes 33const TD_COPYRIGHT: i64 = 0 // DMCA 512: counter-notice + restoration exists 34const TD_NCII: i64 = 1 // TAKE IT DOWN Act: 48h removal duty, no casual restoration 35const TD_DEFAMATION: i64 = 2 // truth/harm are for a human (often a court), not a string match 36const TD_PUBLICITY: i64 = 3 // right of publicity, a state-varying tort 37const TD_CSAM: i64 = 4 // NOT a takedown -- preserve + report 38 39// actions 40const TD_REJECT_INCOMPLETE: i64 = 0 // notice missing required elements -> do NOT act on it 41const TD_REMOVE: i64 = 1 // expeditious removal (soft-delete: rule 13, history is sacred) 42const TD_REVIEW_HUMAN: i64 = 2 // genuinely contested -> a person decides 43const TD_PRESERVE_REPORT: i64 = 3 // CSAM: preserve evidence + mandatory report. NEVER silent delete. 44 45// statutory clocks (hours). -1 = "expeditious", deliberately not a fabricated number. 46const TD_HOURS_NCII: i64 = 48 47const TD_HOURS_EXPEDITIOUS: i64 = 0 - 1 48 49// 512(i) repeat-infringer policy: a threshold that EXISTS is the requirement; the number is policy. 50const TD_REPEAT_DEFAULT: i64 = 3 51 52// A notice must carry its required elements before anyone acts on it. Acting on a defective notice 53// is its own exposure -- the target can sue over a wrongful takedown -- so incompleteness is a 54// REFUSAL TO ACT, not a reason to remove "just in case". 55// ★FAIL-CLOSED IN THE DIRECTION THAT PROTECTS BOTH PARTIES: no removal AND no silent discard; 56// the caller is expected to write back asking for the missing element. 57func td_notice_valid(has_work: i64, has_locator: i64, has_contact: i64, 58 has_goodfaith: i64, has_signature: i64) -> i64 { 59 if has_work != 1 { return 0 } 60 if has_locator != 1 { return 0 } 61 if has_contact != 1 { return 0 } 62 if has_goodfaith != 1 { return 0 } 63 if has_signature != 1 { return 0 } 64 return 1 65} 66 67// the clock for a class. NCII is a real statutory number; copyright is "expeditious" and we refuse 68// to invent a figure for it (★WHEN NO NUMBER IS ENACTED, DO NOT MANUFACTURE ONE). 69func td_deadline_hours(class: i64) -> i64 { 70 if class == TD_NCII { return TD_HOURS_NCII } 71 return TD_HOURS_EXPEDITIOUS 72} 73 74// is this notice past its statutory clock? -1 deadline (expeditious) can never be "overdue" by a 75// number, so it reports 0 here and is escalated by policy, not by arithmetic. 76func td_overdue(class: i64, age_hours: i64) -> i64 { 77 let d: i64 = td_deadline_hours(class) 78 if d < 0 { return 0 } 79 if age_hours > d { return 1 } 80 return 0 81} 82 83// THE ROUTING DECISION. 84// ORDER IS THE ARGUMENT, most-absolute first: 85// 1. CSAM -> preserve + report, regardless of notice completeness. A defective notice does 86// not make the duty go away, and removal alone would destroy evidence. 87// 2. invalid -> refuse to act (and answer the sender). Never remove on a defective notice. 88// 3. NCII -> remove. The statute's element is non-consent, and the notice asserts it. 89// 4. copyright -> remove; the counter-notice path is what protects the uploader. 90// 5. the rest -> a human decides. Defamation and publicity turn on facts a host cannot find. 91func td_action(class: i64, valid: i64) -> i64 { 92 if class == TD_CSAM { return TD_PRESERVE_REPORT } 93 if valid != 1 { return TD_REJECT_INCOMPLETE } 94 if class == TD_NCII { return TD_REMOVE } 95 if class == TD_COPYRIGHT { return TD_REMOVE } 96 return TD_REVIEW_HUMAN 97} 98 99// Counter-notice / restoration. DMCA gives the uploader this path; NCII does not get a casual 100// restoration, and CSAM never does. ★A RESTORATION PATH THAT IGNORES THE CLASS IS A LIABILITY. 101func td_restorable(class: i64) -> i64 { 102 if class == TD_COPYRIGHT { return 1 } 103 return 0 104} 105 106// 512(i): terminating repeat infringers "in appropriate circumstances". The POLICY EXISTING and 107// being applied is the requirement; the threshold is the operator's, passed in. 108func td_repeat_action(strikes: i64, threshold: i64) -> i64 { 109 if strikes >= threshold { return 1 } 110 return 0 111}