code wiki / _hdl_build / nx_anatomy_risk.nx
nx_anatomy_risk.nx source
↩ module page · 161 lines · 9451 B
1// nx_anatomy_risk.nx -- the AnatomyRisk object: a PRE-RENDER body-horror RISK score from the composed prompt text.
2// FAITHFUL integer port of elder-ai-platform/services/svc-identity/anatomy_score_v2.py (Mode A -- the no-GPU proxy that
3// predicts anatomy-failure risk from KNOWN bug-class features in the prompt). Weights are the Python floats x1000 (no-float
4// doctrine); score = 1000 - total_risk, clamped [0,1000] (HIGHER = LESS body-horror risk). This is the QC the operator
5// tests Elara against ("we used to get body horror"): it fires on the exact contradictions a prompt-builder can create
6// (rear pose + face-into-camera, ecu + full-body tokens, undress + clothed tokens, too many hand tokens...). It also
7// EMITS which factors fired, so a flag is ACTIONABLE (clear feedback, per the no-bare-refusal rule) not a bare number.
8// 8 of the 11 Python features are prompt-derivable and ported here; the 3 that need a structured scene_context the
9// sovereign daemon does not yet produce (has_companion_but_pose_solo, background_clutter_high, lighting_location_mismatch)
10// are DEFERRED (documented, not silently dropped) until the daemon carries a typed scene. Object model: companion_arch.md.
11// license_tier: ORIGINAL
12import "nx_syscalls.nx"
13
14func ar_cat(dst: *u8, off: i64, s: *u8) -> i64 { var o: i64=off; var i: i64=0; while s[i]!=(0 as u8){dst[o]=s[i]; o=o+1; i=i+1} return o }
15// case-insensitive: is `needle` a substring of hay[0..hlen)? 1/0
16func ar_contains(hay: *u8, hlen: i64, needle: *u8) -> i64 {
17 var nl: i64 = 0; while needle[nl]!=(0 as u8) { nl=nl+1 }
18 if nl==0 { return 0 }
19 var i: i64 = 0
20 while i + nl <= hlen {
21 var j: i64 = 0; var ok: i64 = 1
22 while j < nl {
23 var a: i64 = hay[i+j]&0xff; var b: i64 = needle[j]&0xff
24 if a>=65 { if a<=90 { a=a+32 } }
25 if b>=65 { if b<=90 { b=b+32 } }
26 if a!=b { ok=0; j=nl } else { j=j+1 }
27 }
28 if ok==1 { return 1 }
29 i=i+1
30 }
31 return 0
32}
33// case-insensitive NON-overlapping occurrence count of `needle` in hay[0..hlen)
34func ar_count(hay: *u8, hlen: i64, needle: *u8) -> i64 {
35 var nl: i64 = 0; while needle[nl]!=(0 as u8) { nl=nl+1 }
36 if nl==0 { return 0 }
37 var cnt: i64 = 0
38 var i: i64 = 0
39 while i + nl <= hlen {
40 var j: i64 = 0; var ok: i64 = 1
41 while j < nl {
42 var a: i64 = hay[i+j]&0xff; var b: i64 = needle[j]&0xff
43 if a>=65 { if a<=90 { a=a+32 } }
44 if b>=65 { if b<=90 { b=b+32 } }
45 if a!=b { ok=0; j=nl } else { j=j+1 }
46 }
47 if ok==1 { cnt=cnt+1; i=i+nl } else { i=i+1 }
48 }
49 return cnt
50}
51// word count = runs of non-space characters
52func ar_wordcount(hay: *u8, hlen: i64) -> i64 {
53 var cnt: i64 = 0; var inw: i64 = 0; var i: i64 = 0
54 while i < hlen {
55 let c: i64 = hay[i]&0xff
56 if c==32 { inw=0 } else { if c==9 { inw=0 } else { if c==10 { inw=0 } else { if inw==0 { cnt=cnt+1; inw=1 } } } }
57 i=i+1
58 }
59 return cnt
60}
61
62// Compute the anatomy-risk score for a composed prompt. Writes fired factor names (comma-sep) to factors_out.
63// Returns the score in [0,1000] (1000 = no risk). Mirrors anatomy_score_v2.py RISK_FEATURES_WEIGHTS x1000.
64func go_anatomy_risk(prompt: *u8, plen: i64, factors_out: *u8) -> i64 {
65 var risk: i64 = 0
66 var fo: i64 = 0
67
68 // rear_pose_with_face_visible (0.40): a rear/behind facing + a face-visible cue = a classic body-horror generator
69 var is_rear: i64 = 0
70 if ar_contains(prompt, plen, "from behind" as *u8)==1 { is_rear=1 }
71 if ar_contains(prompt, plen, "rear view" as *u8)==1 { is_rear=1 }
72 if ar_contains(prompt, plen, "from the back" as *u8)==1 { is_rear=1 }
73 if ar_contains(prompt, plen, "back to the camera" as *u8)==1 { is_rear=1 }
74 if ar_contains(prompt, plen, "seen from behind" as *u8)==1 { is_rear=1 }
75 var face_vis: i64 = 0
76 if ar_contains(prompt, plen, "her face" as *u8)==1 { face_vis=1 }
77 if ar_contains(prompt, plen, "looking at" as *u8)==1 { face_vis=1 }
78 if ar_contains(prompt, plen, "eye contact" as *u8)==1 { face_vis=1 }
79 if ar_contains(prompt, plen, "into the camera" as *u8)==1 { face_vis=1 }
80 if ar_contains(prompt, plen, "gaze into" as *u8)==1 { face_vis=1 }
81 if is_rear==1 { if face_vis==1 { risk=risk+400; fo=ar_cat(factors_out, fo, "rear_pose_with_face_visible," as *u8) } }
82
83 // ecu_close_up_mentions_full_body (0.25)
84 var is_ecu: i64 = 0
85 if ar_contains(prompt, plen, "extreme close-up" as *u8)==1 { is_ecu=1 }
86 if ar_contains(prompt, plen, "extreme closeup" as *u8)==1 { is_ecu=1 }
87 if ar_contains(prompt, plen, "macro shot" as *u8)==1 { is_ecu=1 }
88 var full_body: i64 = 0
89 if ar_contains(prompt, plen, "full body" as *u8)==1 { full_body=1 }
90 if ar_contains(prompt, plen, "full-body" as *u8)==1 { full_body=1 }
91 if ar_contains(prompt, plen, "her thighs" as *u8)==1 { full_body=1 }
92 if ar_contains(prompt, plen, "her legs" as *u8)==1 { full_body=1 }
93 if ar_contains(prompt, plen, "her hips" as *u8)==1 { full_body=1 }
94 if is_ecu==1 { if full_body==1 { risk=risk+250; fo=ar_cat(factors_out, fo, "ecu_close_up_mentions_full_body," as *u8) } }
95
96 // side_view_mentions_both_sides (0.30)
97 var is_side: i64 = 0
98 if ar_contains(prompt, plen, "profile view" as *u8)==1 { is_side=1 }
99 if ar_contains(prompt, plen, "side view" as *u8)==1 { is_side=1 }
100 if ar_contains(prompt, plen, "in profile" as *u8)==1 { is_side=1 }
101 var both_side: i64 = 0
102 if ar_contains(prompt, plen, "both hands" as *u8)==1 { both_side=1 }
103 if ar_contains(prompt, plen, "both arms" as *u8)==1 { both_side=1 }
104 if ar_contains(prompt, plen, "both legs" as *u8)==1 { both_side=1 }
105 if ar_contains(prompt, plen, "both nipples" as *u8)==1 { both_side=1 }
106 if is_side==1 { if both_side==1 { risk=risk+300; fo=ar_cat(factors_out, fo, "side_view_mentions_both_sides," as *u8) } }
107
108 // wet_token_no_wet_context (0.20)
109 var wet: i64 = 0
110 if ar_contains(prompt, plen, "wet " as *u8)==1 { wet=1 }
111 if ar_contains(prompt, plen, "soaked" as *u8)==1 { wet=1 }
112 if ar_contains(prompt, plen, "dripping" as *u8)==1 { wet=1 }
113 if ar_contains(prompt, plen, "drenched" as *u8)==1 { wet=1 }
114 if ar_contains(prompt, plen, "moist" as *u8)==1 { wet=1 }
115 var wetctx: i64 = 0
116 if ar_contains(prompt, plen, "shower" as *u8)==1 { wetctx=1 }
117 if ar_contains(prompt, plen, "pool" as *u8)==1 { wetctx=1 }
118 if ar_contains(prompt, plen, "bath" as *u8)==1 { wetctx=1 }
119 if ar_contains(prompt, plen, "rain" as *u8)==1 { wetctx=1 }
120 if ar_contains(prompt, plen, "ocean" as *u8)==1 { wetctx=1 }
121 if ar_contains(prompt, plen, "swim" as *u8)==1 { wetctx=1 }
122 if ar_contains(prompt, plen, "beach" as *u8)==1 { wetctx=1 }
123 if ar_contains(prompt, plen, "sweat" as *u8)==1 { wetctx=1 }
124 if wet==1 { if wetctx==0 { risk=risk+200; fo=ar_cat(factors_out, fo, "wet_token_no_wet_context," as *u8) } }
125
126 // multiple_hand_tokens (0.25, scaled hand_count/6): hands are the #1 body-horror source
127 var hands: i64 = ar_count(prompt, plen, "hand" as *u8) + ar_count(prompt, plen, "fingers" as *u8) + ar_count(prompt, plen, "fingertips" as *u8)
128 if hands >= 4 { var c: i64 = 250*hands/6; if c>250 { c=250 } risk=risk+c; fo=ar_cat(factors_out, fo, "multiple_hand_tokens," as *u8) }
129
130 // mirror_prop_with_non_selfie_pose (0.20): mirror + rear + not a selfie
131 var mirror: i64 = 0
132 if ar_contains(prompt, plen, "mirror" as *u8)==1 { mirror=1 }
133 if ar_contains(prompt, plen, "reflection" as *u8)==1 { mirror=1 }
134 var selfie: i64 = 0
135 if ar_contains(prompt, plen, "selfie" as *u8)==1 { selfie=1 }
136 if ar_contains(prompt, plen, "phone" as *u8)==1 { selfie=1 }
137 if mirror==1 { if selfie==0 { if is_rear==1 { risk=risk+200; fo=ar_cat(factors_out, fo, "mirror_prop_with_non_selfie_pose," as *u8) } } }
138
139 // outfit_state_contradiction (0.20): an undress cue AND a clothed cue in the same prompt
140 var undress: i64 = 0
141 if ar_contains(prompt, plen, "nude" as *u8)==1 { undress=1 }
142 if ar_contains(prompt, plen, "topless" as *u8)==1 { undress=1 }
143 if ar_contains(prompt, plen, "exposed" as *u8)==1 { undress=1 }
144 if ar_contains(prompt, plen, "pulled down" as *u8)==1 { undress=1 }
145 if ar_contains(prompt, plen, "lifted up" as *u8)==1 { undress=1 }
146 var clothed: i64 = 0
147 if ar_contains(prompt, plen, "wearing" as *u8)==1 { clothed=1 }
148 if ar_contains(prompt, plen, "buttoned" as *u8)==1 { clothed=1 }
149 if ar_contains(prompt, plen, "fastened" as *u8)==1 { clothed=1 }
150 if undress==1 { if clothed==1 { risk=risk+200; fo=ar_cat(factors_out, fo, "outfit_state_contradiction," as *u8) } }
151
152 // long_prompt_with_many_anatomy_tokens (0.15, scaled anatomy/16)
153 var wc: i64 = ar_wordcount(prompt, plen)
154 var anat: i64 = ar_count(prompt, plen, "breast" as *u8) + ar_count(prompt, plen, "nipple" as *u8) + ar_count(prompt, plen, "thigh" as *u8) + ar_count(prompt, plen, "belly" as *u8) + ar_count(prompt, plen, "navel" as *u8) + ar_count(prompt, plen, "leg" as *u8) + ar_count(prompt, plen, "arm" as *u8) + ar_count(prompt, plen, "hand" as *u8) + ar_count(prompt, plen, "back" as *u8)
155 if wc > 200 { if anat >= 8 { var c2: i64 = 150*anat/16; if c2>150 { c2=150 } risk=risk+c2; fo=ar_cat(factors_out, fo, "long_prompt_with_many_anatomy_tokens," as *u8) } }
156
157 factors_out[fo]=0 as u8
158 var score: i64 = 1000 - risk
159 if score < 0 { score = 0 }
160 return score
161}