nx_visual_arc.nx source
↩ module page · 160 lines · 9080 B
1// nx_visual_arc.nx -- the VISUAL SPINE for Elder AI image generation: fixes the "clothes stayed the same,
2// arcs never shifted" defect. The prior work had a rich identity (character DNA) and a rich wardrobe, but a
3// single default_outfit and no advancing state -- so every render reused the same outfit and scene. This organ
4// separates the two axes correctly:
5// * IDENTITY ANCHOR (constant) -- the appearance description that keeps it the SAME PERSON across every
6// render, grounded in our scenes. Never rotates.
7// * ARC STATE (advancing) -- a per-persona step counter that indexes the wardrobe x scenes x activities
8// as an ODOMETER, so each varc_advance() yields a NEW combination (a different outfit AND, as the wardrobe
9// cycles, a different scene AND activity) with NO repeat until the whole space is exhausted.
10// varc_prompt() composes IDENTITY (constant) + the current outfit/scene/activity (varying) into the exact text
11// the sovereign generator conditions on. Integrated with the persona (one visual identity per persona id).
12// Stored in nx_registry over seg_store (additive; rule 13). Wardrobe/scenes/activities are DATA (rule 11/25):
13// the persona's own closet and world -- no global content policy, whatever the record holds is what renders.
14// license_tier: ORIGINAL
15import "nx_registry.nx"
16import "nx_tabrec.nx"
17
18const VID_PREFIX: *u8 = "knowledge/visualid-" as *u8
19const VID_KP: *u8 = "vid:" as *u8
20const VID_IDX: *u8 = "__vididx__" as *u8
21const VARC_KP: *u8 = "varc:" as *u8
22const VARC_IDX: *u8 = "__varcidx__" as *u8
23
24// identity record fields: anchor \t wardrobe \t scenes \t activities (the three sets are '|'-separated items)
25const VF_ANCHOR: i64 = 0
26const VF_WARDROBE: i64 = 1
27const VF_SCENES: i64 = 2
28const VF_ACTS: i64 = 3
29
30// ---- '|'-separated item access within a field --------------------------------------------------------
31func vitem_count(buf: *u8, off: i64, len: i64) -> i64 {
32 if len <= 0 { return 0 }
33 var c: i64 = 1
34 var i: i64 = 0
35 while i < len { if buf[off+i] == (0x7C as u8) { c = c + 1 } i = i + 1 }
36 return c
37}
38// idx-th '|'-item of buf[off,off+len): out2[0]=abs offset, out2[1]=length; 1 if found
39func vitem_at(buf: *u8, off: i64, len: i64, idx: i64, out2: *i64) -> i64 {
40 var f: i64 = 0
41 var s: i64 = off
42 var i: i64 = 0
43 while i <= len {
44 var sep: i64 = 0
45 if i == len { sep = 1 } else { if buf[off+i] == (0x7C as u8) { sep = 1 } }
46 if sep == 1 { if f == idx { out2[0] = s; out2[1] = (off+i) - s; return 1 } f = f + 1; s = off+i+1 }
47 i = i + 1
48 }
49 return 0
50}
51
52// ---- identity store ----------------------------------------------------------------------------------
53func vid_put_pfx(prefix: *u8, persona: *u8, anchor: *u8, wardrobe: *u8, scenes: *u8, acts: *u8) -> i64 {
54 let rec: *u8 = sys_mmap(65536); var o: i64 = 0
55 o = tr_cat(rec, o, anchor); o = tr_tab(rec, o)
56 o = tr_cat(rec, o, wardrobe); o = tr_tab(rec, o)
57 o = tr_cat(rec, o, scenes); o = tr_tab(rec, o)
58 o = tr_cat(rec, o, acts)
59 return reg_put(prefix, VID_KP, VID_IDX, persona, rec, o)
60}
61func vid_get_pfx(prefix: *u8, persona: *u8, ptrout: *i64, lenout: *i64) -> i64 { return reg_get(prefix, VID_KP, persona, ptrout, lenout) }
62
63// ---- arc state (step counter) ------------------------------------------------------------------------
64func varc_step_pfx(prefix: *u8, persona: *u8) -> i64 {
65 let p: *i64 = sys_mmap(16) as *i64
66 let l: *i64 = sys_mmap(16) as *i64
67 if reg_get(prefix, VARC_KP, persona, p, l) != 1 { return 0 }
68 return tr_atoi(p[0] as *u8, 0, l[0])
69}
70func varc_set_step_pfx(prefix: *u8, persona: *u8, step: i64) -> i64 {
71 let rec: *u8 = sys_mmap(32)
72 var m: i64 = step; var k: i64 = 0
73 if m < 0 { m = 0 }
74 if m == 0 { rec[0]=48 as u8; k=1 } else { let t: *u8=sys_mmap(32); var kk: i64=0; while m>0 { t[kk]=(48+(m%10)) as u8; m=m/10; kk=kk+1 } var i: i64=0; while i<kk { rec[i]=t[kk-1-i]; i=i+1 } k=kk }
75 return reg_put(prefix, VARC_KP, VARC_IDX, persona, rec, k)
76}
77func varc_advance_pfx(prefix: *u8, persona: *u8) -> i64 {
78 let s: i64 = varc_step_pfx(prefix, persona) + 1
79 varc_set_step_pfx(prefix, persona, s)
80 return s
81}
82func varc_reset_pfx(prefix: *u8, persona: *u8) -> i64 { return varc_set_step_pfx(prefix, persona, 0) }
83
84// ---- ODOMETER indices for a given step (the variety engine) ------------------------------------------
85// out3[0]=outfit idx, out3[1]=scene idx, out3[2]=activity idx. Outfit cycles fastest, then scene, then
86// activity -> nO*nS*nA distinct combinations before any repeat. Returns 1 if the identity exists, else 0.
87func varc_indices_pfx(prefix: *u8, persona: *u8, step: i64, out3: *i64) -> i64 {
88 let p: *i64 = sys_mmap(16) as *i64
89 let l: *i64 = sys_mmap(16) as *i64
90 if vid_get_pfx(prefix, persona, p, l) != 1 { return 0 }
91 let rec: *u8 = p[0] as *u8
92 let rl: i64 = l[0]
93 let f: *i64 = sys_mmap(16) as *i64
94 var nO: i64 = 1; var nS: i64 = 1; var nA: i64 = 1
95 if tr_field(rec, 0, rl, VF_WARDROBE, f) == 1 { nO = vitem_count(rec, f[0], f[1]); if nO < 1 { nO = 1 } }
96 if tr_field(rec, 0, rl, VF_SCENES, f) == 1 { nS = vitem_count(rec, f[0], f[1]); if nS < 1 { nS = 1 } }
97 if tr_field(rec, 0, rl, VF_ACTS, f) == 1 { nA = vitem_count(rec, f[0], f[1]); if nA < 1 { nA = 1 } }
98 out3[0] = step % nO
99 out3[1] = (step / nO) % nS
100 out3[2] = (step / (nO * nS)) % nA
101 return 1
102}
103
104// ---- compose the generation prompt for a given step (deterministic; identity constant, rest varying) -
105func varc_prompt_at_pfx(prefix: *u8, persona: *u8, step: i64, out: *u8, cap: i64) -> i64 {
106 let p: *i64 = sys_mmap(16) as *i64
107 let l: *i64 = sys_mmap(16) as *i64
108 if vid_get_pfx(prefix, persona, p, l) != 1 { out[0]=0 as u8; return 0 }
109 let rec: *u8 = p[0] as *u8
110 let rl: i64 = l[0]
111 let idx: *i64 = sys_mmap(32) as *i64
112 varc_indices_pfx(prefix, persona, step, idx)
113 let f: *i64 = sys_mmap(16) as *i64
114 let it: *i64 = sys_mmap(16) as *i64
115 var o: i64 = 0
116 // IDENTITY ANCHOR (constant -- the same person, every render)
117 if tr_field(rec, 0, rl, VF_ANCHOR, f) == 1 { o = vcatn(out, o, rec, f[0], f[1]) }
118 // + current OUTFIT (varying)
119 if tr_field(rec, 0, rl, VF_WARDROBE, f) == 1 { if vitem_at(rec, f[0], f[1], idx[0], it) == 1 { o = tr_cat(out, o, ", " as *u8); o = vcatn(out, o, rec, it[0], it[1]) } }
120 // + current SCENE (varying -- our scenes)
121 if tr_field(rec, 0, rl, VF_SCENES, f) == 1 { if vitem_at(rec, f[0], f[1], idx[1], it) == 1 { o = tr_cat(out, o, ", " as *u8); o = vcatn(out, o, rec, it[0], it[1]) } }
122 // + current ACTIVITY/POSE (varying)
123 if tr_field(rec, 0, rl, VF_ACTS, f) == 1 { if vitem_at(rec, f[0], f[1], idx[2], it) == 1 { o = tr_cat(out, o, ", " as *u8); o = vcatn(out, o, rec, it[0], it[1]) } }
124 out[o] = 0 as u8
125 return o
126}
127func vcatn(d: *u8, o: i64, src: *u8, off: i64, len: i64) -> i64 { var i: i64=0; while i<len { d[o+i]=src[off+i]; i=i+1 } return o+len }
128
129// current-state prompt (composes at the persona's current arc step)
130func varc_prompt_pfx(prefix: *u8, persona: *u8, out: *u8, cap: i64) -> i64 {
131 return varc_prompt_at_pfx(prefix, persona, varc_step_pfx(prefix, persona), out, cap)
132}
133
134// varc_caption_at: a short human-facing "outfit, scene" summary of the CURRENT look (no identity anchor) --
135// for a memory/chat line like "I sent you a photo of me <caption>". Returns length.
136func varc_caption_at_pfx(prefix: *u8, persona: *u8, step: i64, out: *u8, cap: i64) -> i64 {
137 let p: *i64 = sys_mmap(16) as *i64
138 let l: *i64 = sys_mmap(16) as *i64
139 if vid_get_pfx(prefix, persona, p, l) != 1 { out[0]=0 as u8; return 0 }
140 let rec: *u8 = p[0] as *u8
141 let rl: i64 = l[0]
142 let idx: *i64 = sys_mmap(32) as *i64
143 varc_indices_pfx(prefix, persona, step, idx)
144 let f: *i64 = sys_mmap(16) as *i64
145 let it: *i64 = sys_mmap(16) as *i64
146 var o: i64 = 0
147 if tr_field(rec, 0, rl, VF_WARDROBE, f) == 1 { if vitem_at(rec, f[0], f[1], idx[0], it) == 1 { o = vcatn(out, o, rec, it[0], it[1]) } }
148 if tr_field(rec, 0, rl, VF_SCENES, f) == 1 { if vitem_at(rec, f[0], f[1], idx[1], it) == 1 { o = tr_cat(out, o, ", " as *u8); o = vcatn(out, o, rec, it[0], it[1]) } }
149 out[o] = 0 as u8
150 return o
151}
152func varc_caption_at(persona: *u8, step: i64, out: *u8, cap: i64) -> i64 { return varc_caption_at_pfx(VID_PREFIX, persona, step, out, cap) }
153
154// production-prefix wrappers
155func vid_put(persona: *u8, anchor: *u8, wardrobe: *u8, scenes: *u8, acts: *u8) -> i64 { return vid_put_pfx(VID_PREFIX, persona, anchor, wardrobe, scenes, acts) }
156func varc_step(persona: *u8) -> i64 { return varc_step_pfx(VID_PREFIX, persona) }
157func varc_advance(persona: *u8) -> i64 { return varc_advance_pfx(VID_PREFIX, persona) }
158func varc_reset(persona: *u8) -> i64 { return varc_reset_pfx(VID_PREFIX, persona) }
159func varc_prompt(persona: *u8, out: *u8, cap: i64) -> i64 { return varc_prompt_pfx(VID_PREFIX, persona, out, cap) }
160func varc_prompt_at(persona: *u8, step: i64, out: *u8, cap: i64) -> i64 { return varc_prompt_at_pfx(VID_PREFIX, persona, step, out, cap) }