nx_realperson.nx source
↩ module page · 274 lines · 17025 B
1// nx_realperson.nx -- WRITING arc, rung W-RP-1: THE REAL-PERSON DEPICTION GATE.
2//
3// Closes gap-queue row #1 of nx_writebench (pop 378/378 -- it applies to the WHOLE corpus).
4// The ruler (arXiv:2601.14324) lists real-person depiction in its measured refuse-class inventory,
5// alongside minors, non-consent, sexual violence, torture, CBRN, drug synthesis and cyber-attack.
6//
7// ★★★★★★WHY THIS ONE IS NOT MORALISING, AND THE DISTINCTION IS THE WHOLE POINT.
8// The operator's standing line is LEGALITY BY CONSTRUCTION, NEVER SHAME BY SCORING, and
9// [[nx_dialogue]] already encodes the consequence: H+/C+ (two consenting adults) is NOT a defect and
10// is never scored as one. This organ does not touch that. It fires on a different fact entirely --
11// **a THIRD PARTY who never agreed to be in the scene**. A user can consent for themselves; they
12// cannot consent for someone else. So the rule here is CONSENT, not taste, and the organ is built so
13// that a DECLARED consent (your own likeness, a signed release, a public-domain historical subject)
14// turns a refusal into an allow. A system that refused those too would be moralising, which is
15// exactly what we are not doing.
16//
17// ★WHAT IT IS AND IS NOT. It detects REAL-PERSON REFERENCE PATTERNS, not identities. It holds no
18// celebrity list and cannot have one -- any such list is unbounded, instantly stale, and biased
19// toward the famous while missing the private individual who is far likelier to be harmed.
20// ⚠HONEST ENVELOPE, stated because a detector that hides its blind spot is worse than none:
21// ABSENCE OF A SIGNAL IS NOT PROOF THE SUBJECT IS FICTIONAL. A bare unusual name with no marker
22// reads CLEAR here. This organ raises the floor; it is not a licence to skip human judgement.
23//
24// The lexicons stay pure operator DATA (rule 25 -- the packed NUL-terminated terms + parallel
25// weights contract that nx_register/nx_dialogue already use), so the SFW lane and the operator's
26// local lane tune them without touching this logic, and this organ authors no content of any kind.
27//
28// Pure integer, NO syscalls, caller owns every buffer.
29// license_tier: ORIGINAL
30// module: nishi-core.write.realperson
31// depends: nishi-core.write.register
32// capability: WRITE_REAL_PERSON_GATE
33
34// ★★★★★★OPERATOR CORRECTION, 2026-08-04, AND IT CHANGED THE DESIGN:
35// "make sure legality is correctly understood — in the US we have free speech, so lots of things
36// are legal that may not be moral."
37// MY FIRST VERSION WAS WRONG AND WOULD HAVE SUPPRESSED PROTECTED SPEECH UNDER A "LEGALITY" BANNER --
38// exactly the moralising this lane exists to refuse. It treated "real person + intimate register"
39// as a legal line. In the US it is not: fiction, parody and satire about public figures are broadly
40// protected (Hustler v. Falwell, 1988 -- even outrageous, offensive parody of a public figure is
41// protected speech). Explicit PROSE about a public figure is lawful in the US. It may be tasteless.
42// Tasteless is not our call; that is the whole doctrine.
43//
44// WHAT IS ACTUALLY ACTIONABLE turns on MEDIUM and PRESENTATION, not on how explicit the text is:
45// * NCII -- non-consensual intimate IMAGERY of a real identifiable person, including AI deepfakes
46// (federal TAKE IT DOWN Act 2025 + state statutes). This is about PHOTOREALISTIC LIKENESS, not prose.
47// * DEFAMATION -- a false statement of FACT presented as fact, causing reputational harm. The
48// trigger is the factual ASSERTION; clearly-labelled fiction/parody is not a factual claim.
49// * RIGHT OF PUBLICITY -- COMMERCIAL exploitation of a likeness; a state-law tort, varies widely.
50// * CSAM -- absolute, and no consent can exist. Never a balancing test.
51// * TARGETED HARASSMENT / impersonation-for-deception aimed at a specific person.
52// ⚠NOT LEGAL ADVICE and deliberately conservative in scope: this organ encodes the SHAPE of those
53// distinctions so a machine can route, and it names its own limits rather than pretending to be
54// counsel. When it is unsure it says REVIEW -- it does not invent a refusal.
55//
56// verdicts
57const RP_CLEAR: i64 = 0 // no real-person reference detected
58const RP_PROTECTED: i64 = 1 // real person, but LAWFUL EXPRESSION (fiction/parody/commentary).
59 // Allowed. May be distasteful to someone -- that is not a refusal reason.
60const RP_REVIEW: i64 = 2 // a genuinely unsettled edge (commercial likeness, factual-seeming claim)
61const RP_REFUSE: i64 = 3 // an actual legal line: NCII imagery, or a minor, with no lawful basis
62const RP_CONSENT: i64 = 4 // would have been REFUSE, but consent is DECLARED -> allowed
63const RP_FLAG_OPERATOR: i64 = 5 // UNSETTLED: the OPERATOR decides, the machine must not (see below)
64const RP_QUARANTINE: i64 = 6 // WITHHELD from serving, PRESERVED, escalated to a human (see below)
65
66// ★★★★★★FOURTH OPERATOR CORRECTION, 2026-08-04: "for minors it should be flagged and quarantined,
67// as the performer could be 18 and miscategorized, and that review of what is not ok should be
68// handled appropriately."
69// CORRECT, AND MY ABSOLUTE-REFUSE BRANCH WAS A REAL HARM. A classifier's "this looks like a minor"
70// is a HYPOTHESIS, not a finding of fact. Apparent-age estimation is unreliable, and adult
71// performers are miscategorised and deplatformed on exactly this signal all the time -- a lawful
72// adult loses their work because a model guessed. Treating the guess as a fact punishes the person
73// it misread, and it does so invisibly.
74// ⇒ SPLIT THE AXIS BY EPISTEMIC STATUS, because the right ACTION differs by how much we KNOW:
75// SUSPECTED (a detector/heuristic said so) -> QUARANTINE: withhold from serving so no harm flows
76// if the guess is right, PRESERVE so nothing is destroyed if the guess is wrong, and escalate to
77// a human. 18 U.S.C. 2257 age records exist precisely so this can be RESOLVED rather than assumed.
78// CONFIRMED (human-verified, or a known-hash match) -> the absolute branch, no balancing.
79// ★★★★★★A DETECTOR'S VERDICT IS A HYPOTHESIS; ACTING ON IT AS A FACT HARMS THE LAWFUL PERSON IT
80// MISREAD -- AND DELETING ON IT DESTROYS THE EVIDENCE THAT WOULD HAVE EXONERATED THEM.
81// ★QUARANTINE IS THE ONLY ACTION THAT IS SAFE UNDER BOTH ANSWERS, which is exactly why it is the
82// right default for an uncertain signal.
83const RP_MINOR_NONE: i64 = 0
84const RP_MINOR_SUSPECTED: i64 = 1 // inference -> quarantine + human review
85const RP_MINOR_CONFIRMED: i64 = 2 // verified -> absolute
86
87// ★★★★★★SECOND OPERATOR CORRECTION, 2026-08-04: "with onlyfans and other public media the denial
88// needs to be flagged by me otherwise -- like how you were trained, or stable diffusion, or that
89// it's just like laion and training data."
90// THE POINT IS DOCTRINALLY EXACT. **NCII's defining element is NON-CONSENT**, not explicitness. An
91// adult performer who COMMERCIALLY PUBLISHED intimate imagery of themselves has already consented
92// to that imagery existing publicly -- they are not the leaked-private-photo victim the statute was
93// written for. Treating the two identically reads "explicit + real person" as the offence, which is
94// the taste-as-law error again, one level down. The operator's LAION point sharpens it: the corpora
95// these models are trained on already contain published adult media at scale, so treating its mere
96// EXISTENCE as the violation is incoherent.
97// ⚠BUT PUBLICATION IS NOT BLANKET CONSENT EITHER, and saying so would be its own overreach:
98// consenting to distribute YOUR OWN images is not consenting to have NEW synthetic ones generated
99// of you. Digital-replica / synthetic-likeness law is live and genuinely unsettled (Tennessee's
100// ELVIS Act, New York's digital-replica statute, and a moving patchwork elsewhere).
101// ⇒ SO THE MACHINE MUST NOT DECIDE IT. Published-subject cases route to **RP_FLAG_OPERATOR**: not
102// refused, not waved through, HANDED TO THE HUMAN -- exactly what was asked for.
103// ★★★★★WHERE THE LAW IS GENUINELY UNSETTLED, THE HONEST MACHINE VERDICT IS "A HUMAN DECIDES",
104// NOT A CONFIDENT GUESS IN EITHER DIRECTION.
105// ⛔The private, non-publishing individual keeps the REFUSE branch -- that is the real NCII case,
106// and it is the one this whole gate exists to hold.
107
108// SUBJECT -- has this person publicly/commercially published intimate media of themselves?
109const RP_SUBJECT_PRIVATE: i64 = 0 // no such publication -> the classic NCII victim
110const RP_SUBJECT_PUBLISHED: i64 = 1 // adult performer / published adult media -> operator's call
111
112// MEDIUM -- the axis that decides whether NCII law is even in play.
113const RP_MEDIUM_TEXT: i64 = 0 // prose/fiction: broad First Amendment protection in the US
114const RP_MEDIUM_IMAGE: i64 = 1 // photorealistic likeness: where NCII statutes actually bite
115
116// PRESENTATION -- the axis that decides whether defamation is in play.
117const RP_PRESENT_FICTION: i64 = 0 // evidently or explicitly fiction/parody/satire
118const RP_PRESENT_FACTUAL: i64 = 1 // asserted as something that really happened
119
120// consent kinds a caller may declare (anything > 0 lifts the refusal)
121const RP_CONSENT_NONE: i64 = 0
122const RP_CONSENT_SELF: i64 = 1 // the requester's own likeness
123const RP_CONSENT_RELEASE: i64 = 2 // a signed model release on file
124const RP_CONSENT_HISTORIC: i64 = 3 // long-deceased / public-domain subject
125
126// default thresholds, ruler-informed and OVERRIDABLE (rule 11): a caller passes its own.
127const RP_REF_THRESHOLD: i64 = 3
128const RP_INTIMATE_THRESHOLD: i64 = 5
129
130func rp_lower(c: i64) -> i64 { if c >= 65 { if c <= 90 { return c + 32 } } return c }
131
132func rp_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
133
134// case-insensitive substring, WHOLE-WORD: a longer word merely CONTAINING a term must not score
135// ("presidential suite" is not "president"; the nx_dialogue whole-word lesson, reused).
136func rp_is_wordch(c: i64) -> i64 {
137 if c >= 97 { if c <= 122 { return 1 } }
138 if c >= 65 { if c <= 90 { return 1 } }
139 if c >= 48 { if c <= 57 { return 1 } }
140 return 0
141}
142func rp_has_word(buf: *u8, a: i64, b: i64, term: *u8) -> i64 {
143 let m: i64 = rp_len(term)
144 if m == 0 { return 0 }
145 if b - a < m { return 0 }
146 var i: i64 = a
147 while i + m <= b {
148 var j: i64 = 0
149 var same: i64 = 1
150 while j < m {
151 if rp_lower(buf[i + j] as i64) != rp_lower(term[j] as i64) { same = 0; j = m } else { j = j + 1 }
152 }
153 if same == 1 {
154 var lok: i64 = 1
155 var rok: i64 = 1
156 if i > a { if rp_is_wordch(buf[i - 1] as i64) == 1 { lok = 0 } }
157 if i + m < b { if rp_is_wordch(buf[i + m] as i64) == 1 { rok = 0 } }
158 if lok == 1 { if rok == 1 { return 1 } }
159 }
160 i = i + 1
161 }
162 return 0
163}
164
165// sum the weights of every packed term present. terms = "a\0b\0c\0\0", weights parallel.
166func rp_score(buf: *u8, a: i64, b: i64, terms: *u8, weights: *i64, nterms: i64) -> i64 {
167 var total: i64 = 0
168 var ti: i64 = 0
169 var off: i64 = 0
170 while ti < nterms {
171 let t: *u8 = ((terms as i64) + off) as *u8
172 let tl: i64 = rp_len(t)
173 if tl == 0 { ti = nterms } else {
174 if rp_has_word(buf, a, b, t) == 1 { total = total + weights[ti] }
175 off = off + tl + 1
176 ti = ti + 1
177 }
178 }
179 return total
180}
181
182// NAME-SHAPED: two consecutive Capitalised tokens ("Jane Doe"). A weak signal ON ITS OWN -- English
183// capitalises sentence starts and many nouns -- so it is worth little by itself and only becomes
184// meaningful when a real-person MARKER is also present. Scored, never decisive.
185// ⚠I WROTE THE POSITION-DESTROYING BUG AGAIN, ONE HOUR AFTER BANKING THE LAW ABOUT IT.
186// The first version ended the token walk with `j = b + 1`, which threw away the index it had just
187// found; every candidate then failed the `j <= b` test and the detector returned 0 for everything
188// (gate T8b/T9 caught it). ★★★★★A PARSER THAT LOSES THE POSITION REPORTS SUCCESS AND MEANS NOTHING
189// -- and knowing the law is not the same as not writing the bug. Terminate with a FLAG; keep j.
190func rp_name_shaped(buf: *u8, a: i64, b: i64) -> i64 {
191 var i: i64 = a
192 while i < b {
193 let c: i64 = buf[i] as i64
194 var isupper: i64 = 0
195 if c >= 65 { if c <= 90 { isupper = 1 } }
196 if isupper == 1 {
197 var j: i64 = i + 1
198 var go: i64 = 1
199 while go == 1 {
200 if j >= b { go = 0 } else {
201 if rp_is_wordch(buf[j] as i64) == 1 { j = j + 1 } else { go = 0 }
202 }
203 }
204 // j now indexes the first non-word char (or b) -- the position SURVIVED the search.
205 if j - i >= 2 {
206 if j + 1 < b {
207 if buf[j] == (32 as u8) {
208 let d: i64 = buf[j + 1] as i64
209 if d >= 65 { if d <= 90 { return 1 } }
210 }
211 }
212 }
213 i = j + 1
214 } else { i = i + 1 }
215 }
216 return 0
217}
218
219// THE DECISION. ref = real-person reference score, intimate = intimate/explicit register score,
220// medium = RP_MEDIUM_*, present = RP_PRESENT_*, minor = 1 when the subject is depicted as a minor,
221// commercial = 1 for advertising/endorsement use, consent = RP_CONSENT_*.
222// Thresholds are arguments (rule 11).
223//
224// ORDER IS THE ARGUMENT. Each branch below is a DIFFERENT body of law, checked most-absolute first:
225// 1. minor -> absolute; no consent exists, no balancing, regardless of medium.
226// 2. IMAGE + intimate -> NCII. Consent lifts it, because consent is precisely what the statute
227// is about. This is the ONE place explicitness matters, and only because
228// the medium makes it a likeness rather than a sentence.
229// 3. factual assertion-> defamation surface. REVIEW, not refuse: falsity and harm are facts we
230// cannot determine from a string, and guessing would suppress commentary.
231// 4. commercial -> right of publicity. REVIEW: a state-varying tort, not a bright line.
232// 5. everything else -> PROTECTED. Fiction, parody, satire and criticism about a real person --
233// INCLUDING explicit prose -- is lawful expression in the US.
234// ★THE LAST BRANCH IS THE POINT. A gate whose default for lawful-but-edgy speech is "refuse" is
235// enforcing taste while claiming to enforce law.
236func rp_decision(ref: i64, intimate: i64, medium: i64, present: i64, minor: i64, commercial: i64,
237 subject: i64, consent: i64, ref_thr: i64, int_thr: i64) -> i64 {
238 // 1a. CONFIRMED minor -> ABSOLUTE. FIRST, so nothing can launder it: not a `published` history,
239 // not a declared consent, not a raised threshold, and not the absence of a named real person.
240 if minor == RP_MINOR_CONFIRMED { return RP_REFUSE }
241 // 1b. SUSPECTED minor -> QUARANTINE. Also BEFORE the ref_thr shortcut, deliberately: the age
242 // signal is about the DEPICTED SUBJECT and is meaningful whether or not we identified any
243 // real named person, so a reference-score threshold must never be what silences it.
244 // Withheld (safe if the guess is right), preserved (safe if it is wrong), human either way.
245 if minor == RP_MINOR_SUSPECTED { return RP_QUARANTINE }
246 if ref < ref_thr { return RP_CLEAR }
247 if medium == RP_MEDIUM_IMAGE {
248 if intimate >= int_thr {
249 // 2. Declared consent settles it outright -- consent is the element the statute turns on.
250 if consent > RP_CONSENT_NONE { return RP_CONSENT }
251 // 3. PUBLISHED SUBJECT -> the operator decides. The non-consent element is not cleanly
252 // met (they published intimate media of themselves), but synthetic-likeness law is
253 // unsettled, so neither refusing nor allowing is an honest machine verdict.
254 if subject == RP_SUBJECT_PUBLISHED { return RP_FLAG_OPERATOR }
255 // 4. Private individual, no consent -> the real NCII case. This is the line that holds.
256 return RP_REFUSE
257 }
258 }
259 if present == RP_PRESENT_FACTUAL { return RP_REVIEW }
260 if commercial == 1 { return RP_REVIEW }
261 return RP_PROTECTED
262}
263
264// convenience: score a text against both lexicons and decide in one call.
265func rp_judge(buf: *u8, a: i64, b: i64,
266 rterms: *u8, rweights: *i64, rn: i64,
267 iterms: *u8, iweights: *i64, inn: i64,
268 medium: i64, present: i64, minor: i64, commercial: i64, subject: i64,
269 consent: i64, ref_thr: i64, int_thr: i64) -> i64 {
270 var ref: i64 = rp_score(buf, a, b, rterms, rweights, rn)
271 if rp_name_shaped(buf, a, b) == 1 { if ref > 0 { ref = ref + 1 } }
272 let intimate: i64 = rp_score(buf, a, b, iterms, iweights, inn)
273 return rp_decision(ref, intimate, medium, present, minor, commercial, subject, consent, ref_thr, int_thr)
274}