code wiki / _hdl_build / nx_vizsla_action.nx
nx_vizsla_action.nx source
↩ module page · 196 lines · 8608 B
1// nx_vizsla_action.nx -- NISHI VIZSLA: the controller that turns a FIRST-PARTY browser form POST into a
2// relationship mutation. Operator 2026-06-22: "s class exceed not just dropping files ... our first party
3// nishi browser ... manage and keep and use the data in a privacy first respectful way." The Vizsla page
4// (nx_vizsla_render) carries 0-JS native HTML <form method=post> elements; a sovereign POST endpoint hands
5// the URL-encoded body to THIS organ, which decodes it and dispatches to the gated tenant engine -- so you
6// add a contact / log a touch FROM the first-party page, no file editing, data never leaving the box.
7// submit <base> <tid> <action> <urlencoded-body> action = add-contact | touch
8// add-contact body: id=&name=&tier=&bday= (name spaces -> single token; id derived from name if blank)
9// touch body: date=&id=¬e= (note spaces -> single token)
10// Sovereign: own urldecode (%XX + '+'), composes _offc/nx_vizsla_tenant.elf (re-implements nothing). The
11// daemon accept-loop that calls this on a POST is the next thin transport rung. license_tier: ORIGINAL
12import "nx_syscalls.nx"
13
14func va_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
15func va_p(s: *u8) -> i64 { sys_write(1, s, va_slen(s)); return 0 }
16
17func va_eq(a: *u8, b: *u8) -> i64 {
18 var i: i64 = 0
19 var go: i64 = 1
20 while go == 1 { if a[i] != b[i] { return 0 } if a[i] == (0 as u8) { return 1 } i = i + 1 }
21 return 0
22}
23
24// hex digit value, or -1
25func va_hex(c: i64) -> i64 {
26 if c >= 48 { if c <= 57 { return c - 48 } }
27 if c >= 65 { if c <= 70 { return c - 55 } }
28 if c >= 97 { if c <= 102 { return c - 87 } }
29 return 0 - 1
30}
31
32// urldecode src[0,n) -> out (%XX -> byte, '+' -> space); returns length
33func va_urldecode(src: *u8, n: i64, out: *u8, cap: i64) -> i64 {
34 var i: i64 = 0
35 var o: i64 = 0
36 while i < n {
37 if o >= cap - 1 { break }
38 let c: i64 = src[i] as i64
39 var done: i64 = 0
40 if c == 37 {
41 if i + 2 < n {
42 let h1: i64 = va_hex(src[i + 1] as i64)
43 let h2: i64 = va_hex(src[i + 2] as i64)
44 if h1 >= 0 { if h2 >= 0 { out[o] = (h1 * 16 + h2) as u8; o = o + 1; i = i + 3; done = 1 } }
45 }
46 }
47 if done == 0 {
48 if c == 43 { out[o] = 32 as u8 } else { out[o] = c as u8 }
49 o = o + 1
50 i = i + 1
51 }
52 }
53 out[o] = 0 as u8
54 return o
55}
56
57// does body[i..] == "key=" ?
58func va_keymatch(body: *u8, bn: i64, i: i64, key: *u8, kl: i64) -> i64 {
59 if i + kl + 1 > bn { return 0 }
60 var j: i64 = 0
61 while j < kl { if body[i + j] != key[j] { return 0 } j = j + 1 }
62 if body[i + kl] != (61 as u8) { return 0 }
63 return 1
64}
65
66// extract field <key> from urlencoded body -> out (urldecoded); 1 if found
67func va_getfield(body: *u8, bn: i64, key: *u8, out: *u8, cap: i64) -> i64 {
68 let kl: i64 = va_slen(key)
69 var i: i64 = 0
70 while i < bn {
71 var atb: i64 = 0
72 if i == 0 { atb = 1 }
73 if i > 0 { if body[i - 1] == (38 as u8) { atb = 1 } }
74 var hit: i64 = 0
75 if atb == 1 { hit = va_keymatch(body, bn, i, key, kl) }
76 if hit == 1 {
77 let p: i64 = i + kl + 1
78 var ve: i64 = p
79 while ve < bn { if body[ve] == (38 as u8) { break } ve = ve + 1 }
80 va_urldecode((body as i64 + p) as *u8, ve - p, out, cap)
81 return 1
82 }
83 i = i + 1
84 }
85 out[0] = 0 as u8
86 return 0
87}
88
89// sanitize to a single engine-safe token (alnum kept, lowercased if lower=1; separators -> '-'; trimmed)
90func va_san(src: *u8, out: *u8, lower: i64) -> i64 {
91 var i: i64 = 0
92 var o: i64 = 0
93 var lastsep: i64 = 1
94 while src[i] != (0 as u8) {
95 let c: i64 = src[i] as i64
96 var isaln: i64 = 0
97 if c >= 48 { if c <= 57 { isaln = 1 } }
98 if c >= 65 { if c <= 90 { isaln = 1 } }
99 if c >= 97 { if c <= 122 { isaln = 1 } }
100 if isaln == 1 {
101 var lc: i64 = c
102 if lower == 1 { if c >= 65 { if c <= 90 { lc = c + 32 } } }
103 out[o] = lc as u8; o = o + 1; lastsep = 0
104 } else {
105 if lastsep == 0 { out[o] = 45 as u8; o = o + 1; lastsep = 1 }
106 }
107 i = i + 1
108 }
109 if o > 0 { if out[o - 1] == (45 as u8) { o = o - 1 } }
110 out[o] = 0 as u8
111 return o
112}
113
114// fork+exec the blessed tenant engine with up to 7 trailing args (0-terminated early); return exit
115func va_run_tenant(a1: *u8, a2: *u8, a3: *u8, a4: *u8, a5: *u8, a6: *u8, a7: *u8) -> i64 {
116 let pid: i64 = sys_fork()
117 if pid == 0 {
118 let argv: *i64 = sys_mmap(80) as *i64
119 argv[0] = "_offc/nx_vizsla_tenant.elf" as *u8 as i64
120 var k: i64 = 1
121 if (a1 as i64) != 0 { argv[k] = a1 as i64; k = k + 1 }
122 if (a2 as i64) != 0 { argv[k] = a2 as i64; k = k + 1 }
123 if (a3 as i64) != 0 { argv[k] = a3 as i64; k = k + 1 }
124 if (a4 as i64) != 0 { argv[k] = a4 as i64; k = k + 1 }
125 if (a5 as i64) != 0 { argv[k] = a5 as i64; k = k + 1 }
126 if (a6 as i64) != 0 { argv[k] = a6 as i64; k = k + 1 }
127 if (a7 as i64) != 0 { argv[k] = a7 as i64; k = k + 1 }
128 argv[k] = 0
129 let envp: *i64 = sys_mmap(16) as *i64
130 envp[0] = 0
131 sys_execve("_offc/nx_vizsla_tenant.elf" as *u8, argv, envp)
132 sys_exit(127)
133 }
134 let st: *i64 = sys_mmap(16) as *i64
135 sys_wait4(pid, st, 0)
136 return (st[0] >> 8) & 0xff
137}
138
139func va_cmd_submit(argc: i64, argv: *i64) -> i64 {
140 if argc < 6 { va_p("VIZSLA-ACTION submit needs <base> <tid> <action> <urlencoded-body> -- fail loud\n" as *u8); return 1 }
141 let base: *u8 = argv[2] as *u8
142 let tid: *u8 = argv[3] as *u8
143 let action: *u8 = argv[4] as *u8
144 let body: *u8 = argv[5] as *u8
145 let bn: i64 = va_slen(body)
146
147 let f1: *u8 = sys_mmap(512)
148 let f2: *u8 = sys_mmap(512)
149 let f3: *u8 = sys_mmap(512)
150 let f4: *u8 = sys_mmap(512)
151 let s1: *u8 = sys_mmap(512)
152 let s2: *u8 = sys_mmap(512)
153
154 if va_eq(action, "add-contact" as *u8) == 1 {
155 va_getfield(body, bn, "id" as *u8, f1, 512)
156 va_getfield(body, bn, "name" as *u8, f2, 512)
157 let hastier: i64 = va_getfield(body, bn, "tier" as *u8, f3, 512)
158 let hasbday: i64 = va_getfield(body, bn, "bday" as *u8, f4, 512)
159 va_san(f2, s2, 0)
160 if f1[0] == (0 as u8) { va_san(f2, s1, 1) } else { va_san(f1, s1, 1) }
161 if s1[0] == (0 as u8) { va_p("VIZSLA-ACTION add-contact: empty name/id -- fail loud\n" as *u8); return 1 }
162 if s2[0] == (0 as u8) { va_p("VIZSLA-ACTION add-contact: empty display -- fail loud\n" as *u8); return 1 }
163 var tier: *u8 = "network" as *u8
164 if hastier == 1 { if f3[0] != (0 as u8) { tier = f3 } }
165 var bday: *u8 = "-" as *u8
166 if hasbday == 1 { if f4[0] != (0 as u8) { bday = f4 } }
167 let rc: i64 = va_run_tenant("add-contact" as *u8, base, tid, s1, s2, tier, bday)
168 if rc != 0 { va_p("VIZSLA-ACTION add-contact: tenant rejected -- fail loud\n" as *u8); return 1 }
169 va_p("VIZSLA-ACTION add-contact OK id=" as *u8); va_p(s1); va_p(" tenant=" as *u8); va_p(tid); va_p("\n" as *u8)
170 return 0
171 }
172 if va_eq(action, "touch" as *u8) == 1 {
173 va_getfield(body, bn, "date" as *u8, f1, 512)
174 va_getfield(body, bn, "id" as *u8, f2, 512)
175 va_getfield(body, bn, "note" as *u8, f3, 512)
176 va_san(f2, s1, 1)
177 va_san(f3, s2, 0)
178 if s2[0] == (0 as u8) { s2[0] = 110 as u8; s2[1] = 111 as u8; s2[2] = 116 as u8; s2[3] = 101 as u8; s2[4] = 0 as u8 }
179 if f1[0] == (0 as u8) { va_p("VIZSLA-ACTION touch: missing date -- fail loud\n" as *u8); return 1 }
180 if s1[0] == (0 as u8) { va_p("VIZSLA-ACTION touch: missing contact id -- fail loud\n" as *u8); return 1 }
181 let rc: i64 = va_run_tenant("touch" as *u8, base, tid, f1, s1, s2, 0 as *u8)
182 if rc != 0 { va_p("VIZSLA-ACTION touch: tenant rejected -- fail loud\n" as *u8); return 1 }
183 va_p("VIZSLA-ACTION touch OK id=" as *u8); va_p(s1); va_p(" tenant=" as *u8); va_p(tid); va_p("\n" as *u8)
184 return 0
185 }
186 va_p("VIZSLA-ACTION unknown action (add-contact|touch) -- fail loud\n" as *u8)
187 return 1
188}
189
190func main(argc: i64, argv: *i64) -> i64 {
191 if argc < 2 { va_p("VIZSLA-ACTION usage: submit <base> <tenant-id> <action> <urlencoded-body> -- fail loud\n" as *u8); return 1 }
192 let cmd: *u8 = argv[1] as *u8
193 if va_eq(cmd, "submit" as *u8) == 1 { return va_cmd_submit(argc, argv) }
194 va_p("VIZSLA-ACTION unknown command (submit) -- fail loud\n" as *u8)
195 return 1
196}